blob: a1dad1ec9fa70b9f8923763fc8f861c834dba592 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dominik Laskowski2f01d772022-03-23 16:01:29 -070017#include <cinttypes>
18#include <memory>
19
Prabir Pradhan2770d242019-09-02 18:07:11 -070020#include <CursorInputMapper.h>
21#include <InputDevice.h>
22#include <InputMapper.h>
23#include <InputReader.h>
Prabir Pradhan1aed8582019-12-30 11:46:51 -080024#include <InputReaderBase.h>
25#include <InputReaderFactory.h>
Arthur Hung6d5b4b22022-01-21 07:21:10 +000026#include <JoystickInputMapper.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070027#include <KeyboardInputMapper.h>
28#include <MultiTouchInputMapper.h>
Chris Ye1dd2e5c2021-04-04 23:12:41 -070029#include <PeripheralController.h>
Chris Yef59a2f42020-10-16 12:55:26 -070030#include <SensorInputMapper.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070031#include <SingleTouchInputMapper.h>
32#include <SwitchInputMapper.h>
33#include <TestInputListener.h>
Prabir Pradhan739dca42022-09-09 20:12:01 +000034#include <TestInputListenerMatchers.h>
Prabir Pradhan2770d242019-09-02 18:07:11 -070035#include <TouchInputMapper.h>
Prabir Pradhan1aed8582019-12-30 11:46:51 -080036#include <UinputDevice.h>
Chris Ye87143712020-11-10 05:05:58 +000037#include <VibratorInputMapper.h>
Prabir Pradhan2574dfa2019-10-16 16:35:07 -070038#include <android-base/thread_annotations.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080039#include <gtest/gtest.h>
chaviw3277faf2021-05-19 16:45:23 -050040#include <gui/constants.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080041
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -070042#include <thread>
Harry Cuttsa5b71292022-11-28 12:56:17 +000043#include "FakeEventHub.h"
Harry Cutts6b5fbc52022-11-28 16:37:43 +000044#include "FakeInputReaderPolicy.h"
Harry Cuttsb57f1702022-11-28 15:34:22 +000045#include "FakePointerController.h"
Harry Cutts144ff542022-11-28 17:41:06 +000046#include "InstrumentedInputReader.h"
Harry Cuttsa5b71292022-11-28 12:56:17 +000047#include "TestConstants.h"
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +000048#include "android/hardware/input/InputDeviceCountryCode.h"
Michael Wrightdde67b82020-10-27 16:09:22 +000049#include "input/DisplayViewport.h"
50#include "input/Input.h"
Michael Wright17db18e2020-06-26 20:51:44 +010051
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +000052using android::hardware::input::InputDeviceCountryCode;
53
Michael Wrightd02c5b62014-02-10 15:10:22 -080054namespace android {
55
Dominik Laskowski2f01d772022-03-23 16:01:29 -070056using namespace ftl::flag_operators;
Prabir Pradhan739dca42022-09-09 20:12:01 +000057using testing::AllOf;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -070058using std::chrono_literals::operator""ms;
59
Michael Wrightd02c5b62014-02-10 15:10:22 -080060// Arbitrary display properties.
arthurhungcc7f9802020-04-30 17:55:40 +080061static constexpr int32_t DISPLAY_ID = 0;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000062static const std::string DISPLAY_UNIQUE_ID = "local:1";
arthurhungcc7f9802020-04-30 17:55:40 +080063static constexpr int32_t SECONDARY_DISPLAY_ID = DISPLAY_ID + 1;
Prabir Pradhanc13ff082022-09-08 22:03:30 +000064static const std::string SECONDARY_DISPLAY_UNIQUE_ID = "local:2";
arthurhungcc7f9802020-04-30 17:55:40 +080065static constexpr int32_t DISPLAY_WIDTH = 480;
66static constexpr int32_t DISPLAY_HEIGHT = 800;
67static constexpr int32_t VIRTUAL_DISPLAY_ID = 1;
68static constexpr int32_t VIRTUAL_DISPLAY_WIDTH = 400;
69static constexpr int32_t VIRTUAL_DISPLAY_HEIGHT = 500;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -070070static const char* VIRTUAL_DISPLAY_UNIQUE_ID = "virtual:1";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -070071static constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified
Michael Wrightd02c5b62014-02-10 15:10:22 -080072
arthurhungcc7f9802020-04-30 17:55:40 +080073static constexpr int32_t FIRST_SLOT = 0;
74static constexpr int32_t SECOND_SLOT = 1;
75static constexpr int32_t THIRD_SLOT = 2;
76static constexpr int32_t INVALID_TRACKING_ID = -1;
77static constexpr int32_t FIRST_TRACKING_ID = 0;
78static constexpr int32_t SECOND_TRACKING_ID = 1;
79static constexpr int32_t THIRD_TRACKING_ID = 2;
Chris Ye3fdbfef2021-01-06 18:45:18 -080080static constexpr int32_t LIGHT_BRIGHTNESS = 0x55000000;
81static constexpr int32_t LIGHT_COLOR = 0x7F448866;
82static constexpr int32_t LIGHT_PLAYER_ID = 2;
arthurhungcc7f9802020-04-30 17:55:40 +080083
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -080084static constexpr int32_t ACTION_POINTER_0_DOWN =
85 AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
86static constexpr int32_t ACTION_POINTER_0_UP =
87 AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
88static constexpr int32_t ACTION_POINTER_1_DOWN =
89 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
90static constexpr int32_t ACTION_POINTER_1_UP =
91 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
92
Michael Wrightd02c5b62014-02-10 15:10:22 -080093// Error tolerance for floating point assertions.
94static const float EPSILON = 0.001f;
95
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000096// Minimum timestamp separation between subsequent input events from a Bluetooth device.
97static constexpr nsecs_t MIN_BLUETOOTH_TIMESTAMP_DELTA = ms2ns(4);
98// Maximum smoothing time delta so that we don't generate events too far into the future.
99constexpr static nsecs_t MAX_BLUETOOTH_SMOOTHING_DELTA = ms2ns(32);
100
Michael Wrightd02c5b62014-02-10 15:10:22 -0800101template<typename T>
102static inline T min(T a, T b) {
103 return a < b ? a : b;
104}
105
106static inline float avg(float x, float y) {
107 return (x + y) / 2;
108}
109
Chris Ye3fdbfef2021-01-06 18:45:18 -0800110// Mapping for light color name and the light color
111const std::unordered_map<std::string, LightColor> LIGHT_COLORS = {{"red", LightColor::RED},
112 {"green", LightColor::GREEN},
113 {"blue", LightColor::BLUE}};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800114
Prabir Pradhanc14266f2021-05-12 15:56:24 -0700115static int32_t getInverseRotation(int32_t orientation) {
116 switch (orientation) {
117 case DISPLAY_ORIENTATION_90:
118 return DISPLAY_ORIENTATION_270;
119 case DISPLAY_ORIENTATION_270:
120 return DISPLAY_ORIENTATION_90;
121 default:
122 return orientation;
123 }
124}
125
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -0800126static void assertAxisResolution(MultiTouchInputMapper& mapper, int axis, float resolution) {
127 InputDeviceInfo info;
128 mapper.populateDeviceInfo(&info);
129
130 const InputDeviceInfo::MotionRange* motionRange =
131 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
132 ASSERT_NEAR(motionRange->resolution, resolution, EPSILON);
133}
134
135static void assertAxisNotPresent(MultiTouchInputMapper& mapper, int axis) {
136 InputDeviceInfo info;
137 mapper.populateDeviceInfo(&info);
138
139 const InputDeviceInfo::MotionRange* motionRange =
140 info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
141 ASSERT_EQ(nullptr, motionRange);
142}
143
Siarhei Vishniakou21e96e62022-10-27 10:23:37 -0700144[[maybe_unused]] static void dumpReader(InputReader& reader) {
145 std::string dump;
146 reader.dump(dump);
147 std::istringstream iss(dump);
148 for (std::string line; std::getline(iss, line);) {
149 ALOGE("%s", line.c_str());
150 std::this_thread::sleep_for(std::chrono::milliseconds(1));
151 }
152}
153
Michael Wrightd02c5b62014-02-10 15:10:22 -0800154// --- FakeInputMapper ---
155
156class FakeInputMapper : public InputMapper {
157 uint32_t mSources;
158 int32_t mKeyboardType;
159 int32_t mMetaState;
160 KeyedVector<int32_t, int32_t> mKeyCodeStates;
161 KeyedVector<int32_t, int32_t> mScanCodeStates;
162 KeyedVector<int32_t, int32_t> mSwitchStates;
Philip Junker4af3b3d2021-12-14 10:36:55 +0100163 // fake mapping which would normally come from keyCharacterMap
164 std::unordered_map<int32_t, int32_t> mKeyCodeMapping;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800165 std::vector<int32_t> mSupportedKeyCodes;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800166
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700167 std::mutex mLock;
168 std::condition_variable mStateChangedCondition;
169 bool mConfigureWasCalled GUARDED_BY(mLock);
170 bool mResetWasCalled GUARDED_BY(mLock);
171 bool mProcessWasCalled GUARDED_BY(mLock);
172 RawEvent mLastEvent GUARDED_BY(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800173
Arthur Hungc23540e2018-11-29 20:42:11 +0800174 std::optional<DisplayViewport> mViewport;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175public:
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800176 FakeInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
177 : InputMapper(deviceContext),
178 mSources(sources),
179 mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
Michael Wrightd02c5b62014-02-10 15:10:22 -0800180 mMetaState(0),
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800181 mConfigureWasCalled(false),
182 mResetWasCalled(false),
183 mProcessWasCalled(false) {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184
Chris Yea52ade12020-08-27 16:49:20 -0700185 virtual ~FakeInputMapper() {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186
187 void setKeyboardType(int32_t keyboardType) {
188 mKeyboardType = keyboardType;
189 }
190
191 void setMetaState(int32_t metaState) {
192 mMetaState = metaState;
193 }
194
195 void assertConfigureWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700196 std::unique_lock<std::mutex> lock(mLock);
197 base::ScopedLockAssertion assumeLocked(mLock);
198 const bool configureCalled =
199 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
200 return mConfigureWasCalled;
201 });
202 if (!configureCalled) {
203 FAIL() << "Expected configure() to have been called.";
204 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800205 mConfigureWasCalled = false;
206 }
207
208 void assertResetWasCalled() {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700209 std::unique_lock<std::mutex> lock(mLock);
210 base::ScopedLockAssertion assumeLocked(mLock);
211 const bool resetCalled =
212 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
213 return mResetWasCalled;
214 });
215 if (!resetCalled) {
216 FAIL() << "Expected reset() to have been called.";
217 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 mResetWasCalled = false;
219 }
220
Yi Kong9b14ac62018-07-17 13:48:38 -0700221 void assertProcessWasCalled(RawEvent* outLastEvent = nullptr) {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700222 std::unique_lock<std::mutex> lock(mLock);
223 base::ScopedLockAssertion assumeLocked(mLock);
224 const bool processCalled =
225 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
226 return mProcessWasCalled;
227 });
228 if (!processCalled) {
229 FAIL() << "Expected process() to have been called.";
230 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800231 if (outLastEvent) {
232 *outLastEvent = mLastEvent;
233 }
234 mProcessWasCalled = false;
235 }
236
237 void setKeyCodeState(int32_t keyCode, int32_t state) {
238 mKeyCodeStates.replaceValueFor(keyCode, state);
239 }
240
241 void setScanCodeState(int32_t scanCode, int32_t state) {
242 mScanCodeStates.replaceValueFor(scanCode, state);
243 }
244
245 void setSwitchState(int32_t switchCode, int32_t state) {
246 mSwitchStates.replaceValueFor(switchCode, state);
247 }
248
249 void addSupportedKeyCode(int32_t keyCode) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800250 mSupportedKeyCodes.push_back(keyCode);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800251 }
252
Philip Junker4af3b3d2021-12-14 10:36:55 +0100253 void addKeyCodeMapping(int32_t fromKeyCode, int32_t toKeyCode) {
254 mKeyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
255 }
256
Michael Wrightd02c5b62014-02-10 15:10:22 -0800257private:
Philip Junker4af3b3d2021-12-14 10:36:55 +0100258 uint32_t getSources() const override { return mSources; }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800259
Chris Yea52ade12020-08-27 16:49:20 -0700260 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800261 InputMapper::populateDeviceInfo(deviceInfo);
262
263 if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
264 deviceInfo->setKeyboardType(mKeyboardType);
265 }
266 }
267
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700268 std::list<NotifyArgs> configure(nsecs_t, const InputReaderConfiguration* config,
269 uint32_t changes) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700270 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800271 mConfigureWasCalled = true;
Arthur Hungc23540e2018-11-29 20:42:11 +0800272
273 // Find the associated viewport if exist.
Nathaniel R. Lewis26ec2222020-01-10 16:30:54 -0800274 const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
Arthur Hungc23540e2018-11-29 20:42:11 +0800275 if (displayPort && (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
276 mViewport = config->getDisplayViewportByPort(*displayPort);
277 }
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700278
279 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700280 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800281 }
282
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700283 std::list<NotifyArgs> reset(nsecs_t) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700284 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800285 mResetWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700286 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700287 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800288 }
289
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700290 std::list<NotifyArgs> process(const RawEvent* rawEvent) override {
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700291 std::scoped_lock<std::mutex> lock(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800292 mLastEvent = *rawEvent;
293 mProcessWasCalled = true;
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700294 mStateChangedCondition.notify_all();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700295 return {};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800296 }
297
Chris Yea52ade12020-08-27 16:49:20 -0700298 int32_t getKeyCodeState(uint32_t, int32_t keyCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800299 ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
300 return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
301 }
302
Philip Junker4af3b3d2021-12-14 10:36:55 +0100303 int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const override {
304 auto it = mKeyCodeMapping.find(locationKeyCode);
305 return it != mKeyCodeMapping.end() ? it->second : locationKeyCode;
306 }
307
Chris Yea52ade12020-08-27 16:49:20 -0700308 int32_t getScanCodeState(uint32_t, int32_t scanCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800309 ssize_t index = mScanCodeStates.indexOfKey(scanCode);
310 return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
311 }
312
Chris Yea52ade12020-08-27 16:49:20 -0700313 int32_t getSwitchState(uint32_t, int32_t switchCode) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800314 ssize_t index = mSwitchStates.indexOfKey(switchCode);
315 return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
316 }
317
Chris Yea52ade12020-08-27 16:49:20 -0700318 // Return true if the device has non-empty key layout.
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700319 bool markSupportedKeyCodes(uint32_t, const std::vector<int32_t>& keyCodes,
Chris Yea52ade12020-08-27 16:49:20 -0700320 uint8_t* outFlags) override {
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700321 for (size_t i = 0; i < keyCodes.size(); i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800322 for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
323 if (keyCodes[i] == mSupportedKeyCodes[j]) {
324 outFlags[i] = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800325 }
326 }
327 }
Chris Yea52ade12020-08-27 16:49:20 -0700328 bool result = mSupportedKeyCodes.size() > 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800329 return result;
330 }
331
332 virtual int32_t getMetaState() {
333 return mMetaState;
334 }
335
336 virtual void fadePointer() {
337 }
Arthur Hungc23540e2018-11-29 20:42:11 +0800338
339 virtual std::optional<int32_t> getAssociatedDisplay() {
340 if (mViewport) {
341 return std::make_optional(mViewport->displayId);
342 }
343 return std::nullopt;
344 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800345};
346
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700347// --- InputReaderPolicyTest ---
348class InputReaderPolicyTest : public testing::Test {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -0700349protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700350 sp<FakeInputReaderPolicy> mFakePolicy;
351
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700352 void SetUp() override { mFakePolicy = sp<FakeInputReaderPolicy>::make(); }
Chris Yea52ade12020-08-27 16:49:20 -0700353 void TearDown() override { mFakePolicy.clear(); }
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700354};
355
356/**
357 * Check that empty set of viewports is an acceptable configuration.
358 * Also try to get internal viewport two different ways - by type and by uniqueId.
359 *
360 * There will be confusion if two viewports with empty uniqueId and identical type are present.
361 * Such configuration is not currently allowed.
362 */
363TEST_F(InputReaderPolicyTest, Viewports_GetCleared) {
Siarhei Vishniakoucd7ac1e2018-10-15 13:39:50 -0700364 static const std::string uniqueId = "local:0";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700365
366 // We didn't add any viewports yet, so there shouldn't be any.
367 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100368 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700369 ASSERT_FALSE(internalViewport);
370
371 // Add an internal viewport, then clear it
372 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000373 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId, NO_PORT,
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100374 ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700375
376 // Check matching by uniqueId
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700377 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700378 ASSERT_TRUE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100379 ASSERT_EQ(ViewportType::INTERNAL, internalViewport->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700380
381 // Check matching by viewport type
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100382 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700383 ASSERT_TRUE(internalViewport);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700384 ASSERT_EQ(uniqueId, internalViewport->uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700385
386 mFakePolicy->clearViewports();
387 // Make sure nothing is found after clear
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700388 internalViewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700389 ASSERT_FALSE(internalViewport);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100390 internalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700391 ASSERT_FALSE(internalViewport);
392}
393
394TEST_F(InputReaderPolicyTest, Viewports_GetByType) {
395 const std::string internalUniqueId = "local:0";
396 const std::string externalUniqueId = "local:1";
397 const std::string virtualUniqueId1 = "virtual:2";
398 const std::string virtualUniqueId2 = "virtual:3";
399 constexpr int32_t virtualDisplayId1 = 2;
400 constexpr int32_t virtualDisplayId2 = 3;
401
402 // Add an internal viewport
403 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000404 DISPLAY_ORIENTATION_0, true /*isActive*/, internalUniqueId,
405 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700406 // Add an external viewport
407 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000408 DISPLAY_ORIENTATION_0, true /*isActive*/, externalUniqueId,
409 NO_PORT, ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700410 // Add an virtual viewport
411 mFakePolicy->addDisplayViewport(virtualDisplayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000412 DISPLAY_ORIENTATION_0, true /*isActive*/, virtualUniqueId1,
413 NO_PORT, ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700414 // Add another virtual viewport
415 mFakePolicy->addDisplayViewport(virtualDisplayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000416 DISPLAY_ORIENTATION_0, true /*isActive*/, virtualUniqueId2,
417 NO_PORT, ViewportType::VIRTUAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700418
419 // Check matching by type for internal
420 std::optional<DisplayViewport> internalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100421 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700422 ASSERT_TRUE(internalViewport);
423 ASSERT_EQ(internalUniqueId, internalViewport->uniqueId);
424
425 // Check matching by type for external
426 std::optional<DisplayViewport> externalViewport =
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100427 mFakePolicy->getDisplayViewportByType(ViewportType::EXTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700428 ASSERT_TRUE(externalViewport);
429 ASSERT_EQ(externalUniqueId, externalViewport->uniqueId);
430
431 // Check matching by uniqueId for virtual viewport #1
432 std::optional<DisplayViewport> virtualViewport1 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700433 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700434 ASSERT_TRUE(virtualViewport1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100435 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport1->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700436 ASSERT_EQ(virtualUniqueId1, virtualViewport1->uniqueId);
437 ASSERT_EQ(virtualDisplayId1, virtualViewport1->displayId);
438
439 // Check matching by uniqueId for virtual viewport #2
440 std::optional<DisplayViewport> virtualViewport2 =
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700441 mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700442 ASSERT_TRUE(virtualViewport2);
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100443 ASSERT_EQ(ViewportType::VIRTUAL, virtualViewport2->type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700444 ASSERT_EQ(virtualUniqueId2, virtualViewport2->uniqueId);
445 ASSERT_EQ(virtualDisplayId2, virtualViewport2->displayId);
446}
447
448
449/**
450 * We can have 2 viewports of the same kind. We can distinguish them by uniqueId, and confirm
451 * that lookup works by checking display id.
452 * Check that 2 viewports of each kind is possible, for all existing viewport types.
453 */
454TEST_F(InputReaderPolicyTest, Viewports_TwoOfSameType) {
455 const std::string uniqueId1 = "uniqueId1";
456 const std::string uniqueId2 = "uniqueId2";
457 constexpr int32_t displayId1 = 2;
458 constexpr int32_t displayId2 = 3;
459
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100460 std::vector<ViewportType> types = {ViewportType::INTERNAL, ViewportType::EXTERNAL,
461 ViewportType::VIRTUAL};
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700462 for (const ViewportType& type : types) {
463 mFakePolicy->clearViewports();
464 // Add a viewport
465 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000466 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1,
467 NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700468 // Add another viewport
469 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000470 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2,
471 NO_PORT, type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700472
473 // Check that correct display viewport was returned by comparing the display IDs.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700474 std::optional<DisplayViewport> viewport1 =
475 mFakePolicy->getDisplayViewportByUniqueId(uniqueId1);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700476 ASSERT_TRUE(viewport1);
477 ASSERT_EQ(displayId1, viewport1->displayId);
478 ASSERT_EQ(type, viewport1->type);
479
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700480 std::optional<DisplayViewport> viewport2 =
481 mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700482 ASSERT_TRUE(viewport2);
483 ASSERT_EQ(displayId2, viewport2->displayId);
484 ASSERT_EQ(type, viewport2->type);
485
486 // When there are multiple viewports of the same kind, and uniqueId is not specified
487 // in the call to getDisplayViewport, then that situation is not supported.
488 // The viewports can be stored in any order, so we cannot rely on the order, since that
489 // is just implementation detail.
490 // However, we can check that it still returns *a* viewport, we just cannot assert
491 // which one specifically is returned.
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700492 std::optional<DisplayViewport> someViewport = mFakePolicy->getDisplayViewportByType(type);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -0700493 ASSERT_TRUE(someViewport);
494 }
495}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800496
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700497/**
Michael Wrightdde67b82020-10-27 16:09:22 +0000498 * When we have multiple internal displays make sure we always return the default display when
499 * querying by type.
500 */
501TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) {
502 const std::string uniqueId1 = "uniqueId1";
503 const std::string uniqueId2 = "uniqueId2";
504 constexpr int32_t nonDefaultDisplayId = 2;
505 static_assert(nonDefaultDisplayId != ADISPLAY_ID_DEFAULT,
506 "Test display ID should not be ADISPLAY_ID_DEFAULT");
507
508 // Add the default display first and ensure it gets returned.
509 mFakePolicy->clearViewports();
510 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000511 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000512 ViewportType::INTERNAL);
513 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000514 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000515 ViewportType::INTERNAL);
516
517 std::optional<DisplayViewport> viewport =
518 mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
519 ASSERT_TRUE(viewport);
520 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
521 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
522
523 // Add the default display second to make sure order doesn't matter.
524 mFakePolicy->clearViewports();
525 mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000526 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000527 ViewportType::INTERNAL);
528 mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000529 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, NO_PORT,
Michael Wrightdde67b82020-10-27 16:09:22 +0000530 ViewportType::INTERNAL);
531
532 viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
533 ASSERT_TRUE(viewport);
534 ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
535 ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
536}
537
538/**
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700539 * Check getDisplayViewportByPort
540 */
541TEST_F(InputReaderPolicyTest, Viewports_GetByPort) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +0100542 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700543 const std::string uniqueId1 = "uniqueId1";
544 const std::string uniqueId2 = "uniqueId2";
545 constexpr int32_t displayId1 = 1;
546 constexpr int32_t displayId2 = 2;
547 const uint8_t hdmi1 = 0;
548 const uint8_t hdmi2 = 1;
549 const uint8_t hdmi3 = 2;
550
551 mFakePolicy->clearViewports();
552 // Add a viewport that's associated with some display port that's not of interest.
553 mFakePolicy->addDisplayViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000554 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId1, hdmi3,
555 type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700556 // Add another viewport, connected to HDMI1 port
557 mFakePolicy->addDisplayViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +0000558 DISPLAY_ORIENTATION_0, true /*isActive*/, uniqueId2, hdmi1,
559 type);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -0700560
561 // Check that correct display viewport was returned by comparing the display ports.
562 std::optional<DisplayViewport> hdmi1Viewport = mFakePolicy->getDisplayViewportByPort(hdmi1);
563 ASSERT_TRUE(hdmi1Viewport);
564 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
565 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
566
567 // Check that we can still get the same viewport using the uniqueId
568 hdmi1Viewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
569 ASSERT_TRUE(hdmi1Viewport);
570 ASSERT_EQ(displayId2, hdmi1Viewport->displayId);
571 ASSERT_EQ(uniqueId2, hdmi1Viewport->uniqueId);
572 ASSERT_EQ(type, hdmi1Viewport->type);
573
574 // Check that we cannot find a port with "HDMI2", because we never added one
575 std::optional<DisplayViewport> hdmi2Viewport = mFakePolicy->getDisplayViewportByPort(hdmi2);
576 ASSERT_FALSE(hdmi2Viewport);
577}
578
Michael Wrightd02c5b62014-02-10 15:10:22 -0800579// --- InputReaderTest ---
580
581class InputReaderTest : public testing::Test {
582protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700583 std::unique_ptr<TestInputListener> mFakeListener;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800584 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700585 std::shared_ptr<FakeEventHub> mFakeEventHub;
Prabir Pradhan28efc192019-11-05 01:10:04 +0000586 std::unique_ptr<InstrumentedInputReader> mReader;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800587
Chris Yea52ade12020-08-27 16:49:20 -0700588 void SetUp() override {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -0700589 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -0700590 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700591 mFakeListener = std::make_unique<TestInputListener>();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800592
Prabir Pradhan28efc192019-11-05 01:10:04 +0000593 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700594 *mFakeListener);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800595 }
596
Chris Yea52ade12020-08-27 16:49:20 -0700597 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700598 mFakeListener.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800599 mFakePolicy.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800600 }
601
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700602 void addDevice(int32_t eventHubId, const std::string& name,
603 ftl::Flags<InputDeviceClass> classes, const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800604 mFakeEventHub->addDevice(eventHubId, name, classes);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800605
606 if (configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800607 mFakeEventHub->addConfigurationMap(eventHubId, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800608 }
609 mFakeEventHub->finishDeviceScan();
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000610 mReader->loopOnce();
611 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700612 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
613 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800614 }
615
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800616 void disableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700617 mFakePolicy->addDisabledDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +0000618 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700619 }
620
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800621 void enableDevice(int32_t deviceId) {
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700622 mFakePolicy->removeDisabledDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +0000623 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE);
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700624 }
625
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800626 FakeInputMapper& addDeviceWithFakeInputMapper(int32_t deviceId, int32_t eventHubId,
Chris Ye1b0c7342020-07-28 21:57:03 -0700627 const std::string& name,
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700628 ftl::Flags<InputDeviceClass> classes,
629 uint32_t sources,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800630 const PropertyMap* configuration) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800631 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, name);
632 FakeInputMapper& mapper = device->addMapper<FakeInputMapper>(eventHubId, sources);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800633 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800634 addDevice(eventHubId, name, classes, configuration);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800635 return mapper;
636 }
637};
638
Chris Ye98d3f532020-10-01 21:48:59 -0700639TEST_F(InputReaderTest, PolicyGetInputDevices) {
640 ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700641 ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored", ftl::Flags<InputDeviceClass>(0),
Chris Ye98d3f532020-10-01 21:48:59 -0700642 nullptr)); // no classes so device will be ignored
Michael Wrightd02c5b62014-02-10 15:10:22 -0800643
644 // Should also have received a notification describing the new input devices.
Chris Ye98d3f532020-10-01 21:48:59 -0700645 const std::vector<InputDeviceInfo>& inputDevices = mFakePolicy->getInputDevices();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800646 ASSERT_EQ(1U, inputDevices.size());
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800647 ASSERT_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100648 ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800649 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
650 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
Siarhei Vishniakou1983a712021-06-04 19:27:09 +0000651 ASSERT_EQ(0U, inputDevices[0].getMotionRanges().size());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800652}
653
Chris Yee7310032020-09-22 15:36:28 -0700654TEST_F(InputReaderTest, GetMergedInputDevices) {
655 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
656 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
657 // Add two subdevices to device
658 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
659 // Must add at least one mapper or the device will be ignored!
660 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
661 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
662
663 // Push same device instance for next device to be added, so they'll have same identifier.
664 mReader->pushNextDevice(device);
665 mReader->pushNextDevice(device);
666 ASSERT_NO_FATAL_FAILURE(
667 addDevice(eventHubIds[0], "fake1", InputDeviceClass::KEYBOARD, nullptr));
668 ASSERT_NO_FATAL_FAILURE(
669 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
670
671 // Two devices will be merged to one input device as they have same identifier
Siarhei Vishniakou1983a712021-06-04 19:27:09 +0000672 ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
Chris Yee7310032020-09-22 15:36:28 -0700673}
674
Chris Yee14523a2020-12-19 13:46:00 -0800675TEST_F(InputReaderTest, GetMergedInputDevicesEnabled) {
676 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
677 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
678 // Add two subdevices to device
679 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
680 // Must add at least one mapper or the device will be ignored!
681 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
682 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
683
684 // Push same device instance for next device to be added, so they'll have same identifier.
685 mReader->pushNextDevice(device);
686 mReader->pushNextDevice(device);
687 // Sensor device is initially disabled
688 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1",
689 InputDeviceClass::KEYBOARD | InputDeviceClass::SENSOR,
690 nullptr));
691 // Device is disabled because the only sub device is a sensor device and disabled initially.
692 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
693 ASSERT_FALSE(device->isEnabled());
694 ASSERT_NO_FATAL_FAILURE(
695 addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
696 // The merged device is enabled if any sub device is enabled
697 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
698 ASSERT_TRUE(device->isEnabled());
699}
700
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700701TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800702 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700703 constexpr ftl::Flags<InputDeviceClass> deviceClass(InputDeviceClass::KEYBOARD);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800704 constexpr int32_t eventHubId = 1;
705 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700706 // Must add at least one mapper or the device will be ignored!
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800707 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800708 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800709 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700710
Yi Kong9b14ac62018-07-17 13:48:38 -0700711 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700712
713 NotifyDeviceResetArgs resetArgs;
714 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700715 ASSERT_EQ(deviceId, resetArgs.deviceId);
716
717 ASSERT_EQ(device->isEnabled(), true);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800718 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000719 mReader->loopOnce();
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700720
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700721 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700722 ASSERT_EQ(deviceId, resetArgs.deviceId);
723 ASSERT_EQ(device->isEnabled(), false);
724
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800725 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000726 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700727 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
728 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasNotCalled());
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700729 ASSERT_EQ(device->isEnabled(), false);
730
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800731 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000732 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700733 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -0700734 ASSERT_EQ(deviceId, resetArgs.deviceId);
735 ASSERT_EQ(device->isEnabled(), true);
736}
737
Michael Wrightd02c5b62014-02-10 15:10:22 -0800738TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800739 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700740 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800741 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800742 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800743 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800744 AINPUT_SOURCE_KEYBOARD, nullptr);
745 mapper.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800746
747 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
748 AINPUT_SOURCE_ANY, AKEYCODE_A))
749 << "Should return unknown when the device id is >= 0 but unknown.";
750
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800751 ASSERT_EQ(AKEY_STATE_UNKNOWN,
752 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
753 << "Should return unknown when the device id is valid but the sources are not "
754 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800755
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800756 ASSERT_EQ(AKEY_STATE_DOWN,
757 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
758 AKEYCODE_A))
759 << "Should return value provided by mapper when device id is valid and the device "
760 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800761
762 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
763 AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
764 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
765
766 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
767 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
768 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
769}
770
Philip Junker4af3b3d2021-12-14 10:36:55 +0100771TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_ForwardsRequestsToMappers) {
772 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
773 constexpr int32_t eventHubId = 1;
774 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "keyboard",
775 InputDeviceClass::KEYBOARD,
776 AINPUT_SOURCE_KEYBOARD, nullptr);
777 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
778
779 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(0, AKEYCODE_Y))
780 << "Should return unknown when the device with the specified id is not found.";
781
782 ASSERT_EQ(AKEYCODE_Z, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
783 << "Should return correct mapping when device id is valid and mapping exists.";
784
785 ASSERT_EQ(AKEYCODE_A, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_A))
786 << "Should return the location key code when device id is valid and there's no "
787 "mapping.";
788}
789
790TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_NoKeyboardMapper) {
791 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
792 constexpr int32_t eventHubId = 1;
793 FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "joystick",
794 InputDeviceClass::JOYSTICK,
795 AINPUT_SOURCE_GAMEPAD, nullptr);
796 mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
797
798 ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
799 << "Should return unknown when the device id is valid but there is no keyboard mapper";
800}
801
Michael Wrightd02c5b62014-02-10 15:10:22 -0800802TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800803 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700804 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800805 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800806 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800807 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800808 AINPUT_SOURCE_KEYBOARD, nullptr);
809 mapper.setScanCodeState(KEY_A, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800810
811 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
812 AINPUT_SOURCE_ANY, KEY_A))
813 << "Should return unknown when the device id is >= 0 but unknown.";
814
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800815 ASSERT_EQ(AKEY_STATE_UNKNOWN,
816 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, KEY_A))
817 << "Should return unknown when the device id is valid but the sources are not "
818 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800819
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800820 ASSERT_EQ(AKEY_STATE_DOWN,
821 mReader->getScanCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
822 KEY_A))
823 << "Should return value provided by mapper when device id is valid and the device "
824 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800825
826 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
827 AINPUT_SOURCE_TRACKBALL, KEY_A))
828 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
829
830 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
831 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
832 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
833}
834
835TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800836 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700837 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800838 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800839 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800840 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800841 AINPUT_SOURCE_KEYBOARD, nullptr);
842 mapper.setSwitchState(SW_LID, AKEY_STATE_DOWN);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843
844 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
845 AINPUT_SOURCE_ANY, SW_LID))
846 << "Should return unknown when the device id is >= 0 but unknown.";
847
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800848 ASSERT_EQ(AKEY_STATE_UNKNOWN,
849 mReader->getSwitchState(deviceId, AINPUT_SOURCE_TRACKBALL, SW_LID))
850 << "Should return unknown when the device id is valid but the sources are not "
851 "supported by the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800852
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800853 ASSERT_EQ(AKEY_STATE_DOWN,
854 mReader->getSwitchState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
855 SW_LID))
856 << "Should return value provided by mapper when device id is valid and the device "
857 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800858
859 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
860 AINPUT_SOURCE_TRACKBALL, SW_LID))
861 << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
862
863 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
864 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
865 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
866}
867
868TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800869 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700870 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800871 constexpr int32_t eventHubId = 1;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800872 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800873 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800874 AINPUT_SOURCE_KEYBOARD, nullptr);
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +0100875
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800876 mapper.addSupportedKeyCode(AKEYCODE_A);
877 mapper.addSupportedKeyCode(AKEYCODE_B);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800878
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700879 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
Michael Wrightd02c5b62014-02-10 15:10:22 -0800880 uint8_t flags[4] = { 0, 0, 0, 1 };
881
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700882 ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, keyCodes, flags))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800883 << "Should return false when device id is >= 0 but unknown.";
884 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
885
886 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700887 ASSERT_FALSE(mReader->hasKeys(deviceId, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800888 << "Should return false when device id is valid but the sources are not supported by "
889 "the device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800890 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
891
892 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700893 ASSERT_TRUE(mReader->hasKeys(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800894 keyCodes, flags))
895 << "Should return value provided by mapper when device id is valid and the device "
896 "supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800897 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
898
899 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700900 ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
901 << "Should return false when the device id is < 0 but the sources are not supported by "
902 "any device.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800903 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
904
905 flags[3] = 1;
Siarhei Vishniakou74007942022-06-13 13:57:47 -0700906 ASSERT_TRUE(
907 mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
908 << "Should return value provided by mapper when device id is < 0 and one of the "
909 "devices supports some of the sources.";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800910 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
911}
912
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000913TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800914 constexpr int32_t eventHubId = 1;
Chris Ye1b0c7342020-07-28 21:57:03 -0700915 addDevice(eventHubId, "ignored", InputDeviceClass::KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800916
917 NotifyConfigurationChangedArgs args;
918
919 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
920 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
921}
922
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000923TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800924 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700925 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000926 constexpr nsecs_t when = 0;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800927 constexpr int32_t eventHubId = 1;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000928 constexpr nsecs_t readTime = 2;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800929 FakeInputMapper& mapper =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800930 addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800931 AINPUT_SOURCE_KEYBOARD, nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800932
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000933 mFakeEventHub->enqueueEvent(when, readTime, eventHubId, EV_KEY, KEY_A, 1);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000934 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800935 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
936
937 RawEvent event;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800938 ASSERT_NO_FATAL_FAILURE(mapper.assertProcessWasCalled(&event));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +0000939 ASSERT_EQ(when, event.when);
940 ASSERT_EQ(readTime, event.readTime);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800941 ASSERT_EQ(eventHubId, event.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800942 ASSERT_EQ(EV_KEY, event.type);
943 ASSERT_EQ(KEY_A, event.code);
944 ASSERT_EQ(1, event.value);
945}
946
Garfield Tan1c7bc862020-01-28 13:24:04 -0800947TEST_F(InputReaderTest, DeviceReset_RandomId) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800948 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700949 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800950 constexpr int32_t eventHubId = 1;
951 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
Prabir Pradhan42611e02018-11-27 14:04:02 -0800952 // Must add at least one mapper or the device will be ignored!
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800953 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800954 mReader->pushNextDevice(device);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800955 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan42611e02018-11-27 14:04:02 -0800956
957 NotifyDeviceResetArgs resetArgs;
958 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800959 int32_t prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -0800960
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800961 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000962 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700963 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -0800964 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800965 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -0800966
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800967 enableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000968 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700969 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -0800970 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800971 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -0800972
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -0800973 disableDevice(deviceId);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +0000974 mReader->loopOnce();
Prabir Pradhan2574dfa2019-10-16 16:35:07 -0700975 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Garfield Tan1c7bc862020-01-28 13:24:04 -0800976 ASSERT_NE(prevId, resetArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800977 prevId = resetArgs.id;
Prabir Pradhan42611e02018-11-27 14:04:02 -0800978}
979
Garfield Tan1c7bc862020-01-28 13:24:04 -0800980TEST_F(InputReaderTest, DeviceReset_GenerateIdWithInputReaderSource) {
981 constexpr int32_t deviceId = 1;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700982 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Garfield Tan1c7bc862020-01-28 13:24:04 -0800983 constexpr int32_t eventHubId = 1;
984 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
985 // Must add at least one mapper or the device will be ignored!
986 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -0800987 mReader->pushNextDevice(device);
Garfield Tan1c7bc862020-01-28 13:24:04 -0800988 ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
989
990 NotifyDeviceResetArgs resetArgs;
991 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
992 ASSERT_EQ(IdGenerator::Source::INPUT_READER, IdGenerator::getSource(resetArgs.id));
993}
994
Arthur Hungc23540e2018-11-29 20:42:11 +0800995TEST_F(InputReaderTest, Device_CanDispatchToDisplay) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800996 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -0700997 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -0800998 constexpr int32_t eventHubId = 1;
Arthur Hungc23540e2018-11-29 20:42:11 +0800999 const char* DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001000 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1001 FakeInputMapper& mapper =
1002 device->addMapper<FakeInputMapper>(eventHubId, AINPUT_SOURCE_TOUCHSCREEN);
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001003 mReader->pushNextDevice(device);
Arthur Hungc23540e2018-11-29 20:42:11 +08001004
1005 const uint8_t hdmi1 = 1;
1006
1007 // Associated touch screen with second display.
1008 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
1009
1010 // Add default and second display.
Prabir Pradhan28efc192019-11-05 01:10:04 +00001011 mFakePolicy->clearViewports();
Arthur Hungc23540e2018-11-29 20:42:11 +08001012 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001013 DISPLAY_ORIENTATION_0, true /*isActive*/, "local:0", NO_PORT,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001014 ViewportType::INTERNAL);
Arthur Hungc23540e2018-11-29 20:42:11 +08001015 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001016 DISPLAY_ORIENTATION_0, true /*isActive*/, "local:1", hdmi1,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001017 ViewportType::EXTERNAL);
Arthur Hungc23540e2018-11-29 20:42:11 +08001018 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Siarhei Vishniakou6cbc9782019-11-15 17:59:25 +00001019 mReader->loopOnce();
Prabir Pradhan28efc192019-11-05 01:10:04 +00001020
1021 // Add the device, and make sure all of the callbacks are triggered.
1022 // The device is added after the input port associations are processed since
1023 // we do not yet support dynamic device-to-display associations.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08001024 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Prabir Pradhan2574dfa2019-10-16 16:35:07 -07001025 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhan28efc192019-11-05 01:10:04 +00001026 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001027 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
Arthur Hungc23540e2018-11-29 20:42:11 +08001028
Arthur Hung2c9a3342019-07-23 14:18:59 +08001029 // Device should only dispatch to the specified display.
Arthur Hungc23540e2018-11-29 20:42:11 +08001030 ASSERT_EQ(deviceId, device->getId());
1031 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, DISPLAY_ID));
1032 ASSERT_TRUE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hung2c9a3342019-07-23 14:18:59 +08001033
1034 // Can't dispatch event from a disabled device.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08001035 disableDevice(deviceId);
Prabir Pradhan28efc192019-11-05 01:10:04 +00001036 mReader->loopOnce();
Arthur Hung2c9a3342019-07-23 14:18:59 +08001037 ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
Arthur Hungc23540e2018-11-29 20:42:11 +08001038}
1039
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001040TEST_F(InputReaderTest, WhenEnabledChanges_AllSubdevicesAreUpdated) {
1041 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001042 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001043 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1044 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1045 // Must add at least one mapper or the device will be ignored!
1046 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
1047 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
1048 mReader->pushNextDevice(device);
1049 mReader->pushNextDevice(device);
1050 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1051 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1052
1053 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
1054
1055 NotifyDeviceResetArgs resetArgs;
1056 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1057 ASSERT_EQ(deviceId, resetArgs.deviceId);
1058 ASSERT_TRUE(device->isEnabled());
1059 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1060 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1061
1062 disableDevice(deviceId);
1063 mReader->loopOnce();
1064
1065 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1066 ASSERT_EQ(deviceId, resetArgs.deviceId);
1067 ASSERT_FALSE(device->isEnabled());
1068 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1069 ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1070
1071 enableDevice(deviceId);
1072 mReader->loopOnce();
1073
1074 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1075 ASSERT_EQ(deviceId, resetArgs.deviceId);
1076 ASSERT_TRUE(device->isEnabled());
1077 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1078 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1079}
1080
1081TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToSubdeviceMappers) {
1082 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001083 constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
Nathaniel R. Lewisc8bfa542020-02-24 14:05:11 -08001084 constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1085 // Add two subdevices to device
1086 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1087 FakeInputMapper& mapperDevice1 =
1088 device->addMapper<FakeInputMapper>(eventHubIds[0], AINPUT_SOURCE_KEYBOARD);
1089 FakeInputMapper& mapperDevice2 =
1090 device->addMapper<FakeInputMapper>(eventHubIds[1], AINPUT_SOURCE_KEYBOARD);
1091 mReader->pushNextDevice(device);
1092 mReader->pushNextDevice(device);
1093 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1094 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1095
1096 mapperDevice1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
1097 mapperDevice2.setKeyCodeState(AKEYCODE_B, AKEY_STATE_DOWN);
1098
1099 ASSERT_EQ(AKEY_STATE_DOWN,
1100 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_A));
1101 ASSERT_EQ(AKEY_STATE_DOWN,
1102 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_B));
1103 ASSERT_EQ(AKEY_STATE_UNKNOWN,
1104 mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_C));
1105}
1106
Prabir Pradhan7e186182020-11-10 13:56:45 -08001107TEST_F(InputReaderTest, ChangingPointerCaptureNotifiesInputListener) {
1108 NotifyPointerCaptureChangedArgs args;
1109
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001110 auto request = mFakePolicy->setPointerCapture(true);
Prabir Pradhan7e186182020-11-10 13:56:45 -08001111 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
1112 mReader->loopOnce();
1113 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001114 ASSERT_TRUE(args.request.enable) << "Pointer Capture should be enabled.";
1115 ASSERT_EQ(args.request, request) << "Pointer Capture sequence number should match.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08001116
1117 mFakePolicy->setPointerCapture(false);
1118 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
1119 mReader->loopOnce();
1120 mFakeListener->assertNotifyCaptureWasCalled(&args);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001121 ASSERT_FALSE(args.request.enable) << "Pointer Capture should be disabled.";
Prabir Pradhan7e186182020-11-10 13:56:45 -08001122
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001123 // Verify that the Pointer Capture state is not updated when the configuration value
Prabir Pradhan7e186182020-11-10 13:56:45 -08001124 // does not change.
1125 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
1126 mReader->loopOnce();
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001127 mFakeListener->assertNotifyCaptureWasNotCalled();
Prabir Pradhan7e186182020-11-10 13:56:45 -08001128}
1129
Chris Ye87143712020-11-10 05:05:58 +00001130class FakeVibratorInputMapper : public FakeInputMapper {
1131public:
1132 FakeVibratorInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
1133 : FakeInputMapper(deviceContext, sources) {}
1134
1135 std::vector<int32_t> getVibratorIds() override { return getDeviceContext().getVibratorIds(); }
1136};
1137
1138TEST_F(InputReaderTest, VibratorGetVibratorIds) {
1139 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001140 ftl::Flags<InputDeviceClass> deviceClass =
1141 InputDeviceClass::KEYBOARD | InputDeviceClass::VIBRATOR;
Chris Ye87143712020-11-10 05:05:58 +00001142 constexpr int32_t eventHubId = 1;
1143 const char* DEVICE_LOCATION = "BLUETOOTH";
1144 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1145 FakeVibratorInputMapper& mapper =
1146 device->addMapper<FakeVibratorInputMapper>(eventHubId, AINPUT_SOURCE_KEYBOARD);
1147 mReader->pushNextDevice(device);
1148
1149 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1150 ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
1151
1152 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
1153 ASSERT_EQ(mReader->getVibratorIds(deviceId).size(), 2U);
1154}
1155
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001156// --- FakePeripheralController ---
Kim Low03ea0352020-11-06 12:45:07 -08001157
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001158class FakePeripheralController : public PeripheralControllerInterface {
Chris Yee2b1e5c2021-03-10 22:45:12 -08001159public:
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001160 FakePeripheralController(InputDeviceContext& deviceContext) : mDeviceContext(deviceContext) {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08001161
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001162 ~FakePeripheralController() override {}
Chris Yee2b1e5c2021-03-10 22:45:12 -08001163
Andy Chenf9f1a022022-08-29 20:07:10 -04001164 int32_t getEventHubId() const { return getDeviceContext().getEventHubId(); }
1165
Chris Yee2b1e5c2021-03-10 22:45:12 -08001166 void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {}
1167
1168 void dump(std::string& dump) override {}
1169
1170 std::optional<int32_t> getBatteryCapacity(int32_t batteryId) override {
1171 return getDeviceContext().getBatteryCapacity(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08001172 }
1173
Chris Yee2b1e5c2021-03-10 22:45:12 -08001174 std::optional<int32_t> getBatteryStatus(int32_t batteryId) override {
1175 return getDeviceContext().getBatteryStatus(batteryId);
Kim Low03ea0352020-11-06 12:45:07 -08001176 }
Chris Ye3fdbfef2021-01-06 18:45:18 -08001177
1178 bool setLightColor(int32_t lightId, int32_t color) override {
1179 getDeviceContext().setLightBrightness(lightId, color >> 24);
1180 return true;
1181 }
1182
1183 std::optional<int32_t> getLightColor(int32_t lightId) override {
1184 std::optional<int32_t> result = getDeviceContext().getLightBrightness(lightId);
1185 if (!result.has_value()) {
1186 return std::nullopt;
1187 }
1188 return result.value() << 24;
1189 }
Chris Yee2b1e5c2021-03-10 22:45:12 -08001190
1191 bool setLightPlayerId(int32_t lightId, int32_t playerId) override { return true; }
1192
1193 std::optional<int32_t> getLightPlayerId(int32_t lightId) override { return std::nullopt; }
1194
1195private:
1196 InputDeviceContext& mDeviceContext;
1197 inline int32_t getDeviceId() { return mDeviceContext.getId(); }
1198 inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
Andy Chenf9f1a022022-08-29 20:07:10 -04001199 inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; }
Chris Ye3fdbfef2021-01-06 18:45:18 -08001200};
1201
Chris Yee2b1e5c2021-03-10 22:45:12 -08001202TEST_F(InputReaderTest, BatteryGetCapacity) {
1203 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001204 ftl::Flags<InputDeviceClass> deviceClass =
1205 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001206 constexpr int32_t eventHubId = 1;
1207 const char* DEVICE_LOCATION = "BLUETOOTH";
1208 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001209 FakePeripheralController& controller =
1210 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001211 mReader->pushNextDevice(device);
1212
1213 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1214
Harry Cuttsa5b71292022-11-28 12:56:17 +00001215 ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY),
1216 FakeEventHub::BATTERY_CAPACITY);
1217 ASSERT_EQ(mReader->getBatteryCapacity(deviceId), FakeEventHub::BATTERY_CAPACITY);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001218}
1219
1220TEST_F(InputReaderTest, BatteryGetStatus) {
1221 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001222 ftl::Flags<InputDeviceClass> deviceClass =
1223 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
Chris Yee2b1e5c2021-03-10 22:45:12 -08001224 constexpr int32_t eventHubId = 1;
1225 const char* DEVICE_LOCATION = "BLUETOOTH";
1226 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001227 FakePeripheralController& controller =
1228 device->addController<FakePeripheralController>(eventHubId);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001229 mReader->pushNextDevice(device);
1230
1231 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1232
Harry Cuttsa5b71292022-11-28 12:56:17 +00001233 ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY),
1234 FakeEventHub::BATTERY_STATUS);
1235 ASSERT_EQ(mReader->getBatteryStatus(deviceId), FakeEventHub::BATTERY_STATUS);
Chris Yee2b1e5c2021-03-10 22:45:12 -08001236}
1237
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001238TEST_F(InputReaderTest, BatteryGetDevicePath) {
1239 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1240 ftl::Flags<InputDeviceClass> deviceClass =
1241 InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
1242 constexpr int32_t eventHubId = 1;
1243 const char* DEVICE_LOCATION = "BLUETOOTH";
1244 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1245 device->addController<FakePeripheralController>(eventHubId);
1246 mReader->pushNextDevice(device);
1247
1248 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1249
Harry Cuttsa5b71292022-11-28 12:56:17 +00001250 ASSERT_EQ(mReader->getBatteryDevicePath(deviceId), FakeEventHub::BATTERY_DEVPATH);
Prabir Pradhane287ecd2022-09-07 21:18:05 +00001251}
1252
Chris Ye3fdbfef2021-01-06 18:45:18 -08001253TEST_F(InputReaderTest, LightGetColor) {
1254 constexpr int32_t deviceId = END_RESERVED_ID + 1000;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07001255 ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD | InputDeviceClass::LIGHT;
Chris Ye3fdbfef2021-01-06 18:45:18 -08001256 constexpr int32_t eventHubId = 1;
1257 const char* DEVICE_LOCATION = "BLUETOOTH";
1258 std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
Chris Ye1dd2e5c2021-04-04 23:12:41 -07001259 FakePeripheralController& controller =
1260 device->addController<FakePeripheralController>(eventHubId);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001261 mReader->pushNextDevice(device);
1262 RawLightInfo info = {.id = 1,
1263 .name = "Mono",
1264 .maxBrightness = 255,
1265 .flags = InputLightClass::BRIGHTNESS,
1266 .path = ""};
1267 mFakeEventHub->addRawLightInfo(1 /* rawId */, std::move(info));
1268 mFakeEventHub->fakeLightBrightness(1 /* rawId */, 0x55);
1269
1270 ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
Chris Ye3fdbfef2021-01-06 18:45:18 -08001271
Chris Yee2b1e5c2021-03-10 22:45:12 -08001272 ASSERT_TRUE(controller.setLightColor(1 /* lightId */, LIGHT_BRIGHTNESS));
1273 ASSERT_EQ(controller.getLightColor(1 /* lightId */), LIGHT_BRIGHTNESS);
Chris Ye3fdbfef2021-01-06 18:45:18 -08001274 ASSERT_TRUE(mReader->setLightColor(deviceId, 1 /* lightId */, LIGHT_BRIGHTNESS));
1275 ASSERT_EQ(mReader->getLightColor(deviceId, 1 /* lightId */), LIGHT_BRIGHTNESS);
1276}
1277
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001278// --- InputReaderIntegrationTest ---
1279
1280// These tests create and interact with the InputReader only through its interface.
1281// The InputReader is started during SetUp(), which starts its processing in its own
1282// thread. The tests use linux uinput to emulate input devices.
1283// NOTE: Interacting with the physical device while these tests are running may cause
1284// the tests to fail.
1285class InputReaderIntegrationTest : public testing::Test {
1286protected:
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001287 std::unique_ptr<TestInputListener> mTestListener;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001288 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001289 std::unique_ptr<InputReaderInterface> mReader;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001290
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00001291 std::shared_ptr<FakePointerController> mFakePointerController;
1292
Chris Yea52ade12020-08-27 16:49:20 -07001293 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001294#if !defined(__ANDROID__)
1295 GTEST_SKIP();
1296#endif
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07001297 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00001298 mFakePointerController = std::make_shared<FakePointerController>();
1299 mFakePolicy->setPointerController(mFakePointerController);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001300 mTestListener = std::make_unique<TestInputListener>(2000ms /*eventHappenedTimeout*/,
1301 30ms /*eventDidNotHappenTimeout*/);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001302
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001303 mReader = std::make_unique<InputReader>(std::make_shared<EventHub>(), mFakePolicy,
1304 *mTestListener);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001305 ASSERT_EQ(mReader->start(), OK);
1306
1307 // Since this test is run on a real device, all the input devices connected
1308 // to the test device will show up in mReader. We wait for those input devices to
1309 // show up before beginning the tests.
1310 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1311 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1312 }
1313
Chris Yea52ade12020-08-27 16:49:20 -07001314 void TearDown() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001315#if !defined(__ANDROID__)
1316 return;
1317#endif
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001318 ASSERT_EQ(mReader->stop(), OK);
Siarhei Vishniakou18050092021-09-01 13:32:49 -07001319 mReader.reset();
1320 mTestListener.reset();
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001321 mFakePolicy.clear();
1322 }
Prabir Pradhanda20b172022-09-26 17:01:18 +00001323
1324 std::optional<InputDeviceInfo> findDeviceByName(const std::string& name) {
1325 const std::vector<InputDeviceInfo> inputDevices = mFakePolicy->getInputDevices();
1326 const auto& it = std::find_if(inputDevices.begin(), inputDevices.end(),
1327 [&name](const InputDeviceInfo& info) {
1328 return info.getIdentifier().name == name;
1329 });
1330 return it != inputDevices.end() ? std::make_optional(*it) : std::nullopt;
1331 }
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001332};
1333
1334TEST_F(InputReaderIntegrationTest, TestInvalidDevice) {
1335 // An invalid input device that is only used for this test.
1336 class InvalidUinputDevice : public UinputDevice {
1337 public:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +00001338 InvalidUinputDevice() : UinputDevice("Invalid Device", 99 /*productId*/) {}
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001339
1340 private:
1341 void configureDevice(int fd, uinput_user_dev* device) override {}
1342 };
1343
1344 const size_t numDevices = mFakePolicy->getInputDevices().size();
1345
1346 // UinputDevice does not set any event or key bits, so InputReader should not
1347 // consider it as a valid device.
1348 std::unique_ptr<UinputDevice> invalidDevice = createUinputDevice<InvalidUinputDevice>();
1349 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1350 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
1351 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1352
1353 invalidDevice.reset();
1354 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1355 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
1356 ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1357}
1358
1359TEST_F(InputReaderIntegrationTest, AddNewDevice) {
1360 const size_t initialNumDevices = mFakePolicy->getInputDevices().size();
1361
1362 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1363 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1364 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1365 ASSERT_EQ(initialNumDevices + 1, mFakePolicy->getInputDevices().size());
1366
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001367 const auto device = findDeviceByName(keyboard->getName());
1368 ASSERT_TRUE(device.has_value());
1369 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1370 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources());
1371 ASSERT_EQ(0U, device->getMotionRanges().size());
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001372
1373 keyboard.reset();
1374 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1375 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1376 ASSERT_EQ(initialNumDevices, mFakePolicy->getInputDevices().size());
1377}
1378
1379TEST_F(InputReaderIntegrationTest, SendsEventsToInputListener) {
1380 std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1381 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1382
1383 NotifyConfigurationChangedArgs configChangedArgs;
1384 ASSERT_NO_FATAL_FAILURE(
1385 mTestListener->assertNotifyConfigurationChangedWasCalled(&configChangedArgs));
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001386 int32_t prevId = configChangedArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001387 nsecs_t prevTimestamp = configChangedArgs.eventTime;
1388
1389 NotifyKeyArgs keyArgs;
1390 keyboard->pressAndReleaseHomeKey();
1391 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1392 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001393 ASSERT_NE(prevId, keyArgs.id);
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001394 prevId = keyArgs.id;
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001395 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001396 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001397 prevTimestamp = keyArgs.eventTime;
1398
1399 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1400 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
Garfield Tan1c7bc862020-01-28 13:24:04 -08001401 ASSERT_NE(prevId, keyArgs.id);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001402 ASSERT_LE(prevTimestamp, keyArgs.eventTime);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00001403 ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
Prabir Pradhan1aed8582019-12-30 11:46:51 -08001404}
Michael Wrightd02c5b62014-02-10 15:10:22 -08001405
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001406TEST_F(InputReaderIntegrationTest, ExternalStylusesButtons) {
1407 std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
1408 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1409
1410 const auto device = findDeviceByName(stylus->getName());
1411 ASSERT_TRUE(device.has_value());
1412
Prabir Pradhana3621852022-10-14 18:57:23 +00001413 // An external stylus with buttons should also be recognized as a keyboard.
1414 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_STYLUS, device->getSources())
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001415 << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1416 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1417
1418 const auto DOWN =
1419 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD));
1420 const auto UP = AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD));
1421
1422 stylus->pressAndReleaseKey(BTN_STYLUS);
1423 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1424 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1425 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1426 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1427
1428 stylus->pressAndReleaseKey(BTN_STYLUS2);
1429 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1430 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1431 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1432 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1433
1434 stylus->pressAndReleaseKey(BTN_STYLUS3);
1435 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1436 AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1437 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1438 AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1439}
1440
Siarhei Vishniakoua0d2b802020-05-13 14:00:31 -07001441/**
1442 * The Steam controller sends BTN_GEAR_DOWN and BTN_GEAR_UP for the two "paddle" buttons
1443 * on the back. In this test, we make sure that BTN_GEAR_DOWN / BTN_WHEEL and BTN_GEAR_UP
1444 * are passed to the listener.
1445 */
1446static_assert(BTN_GEAR_DOWN == BTN_WHEEL);
1447TEST_F(InputReaderIntegrationTest, SendsGearDownAndUpToInputListener) {
1448 std::unique_ptr<UinputSteamController> controller = createUinputDevice<UinputSteamController>();
1449 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1450 NotifyKeyArgs keyArgs;
1451
1452 controller->pressAndReleaseKey(BTN_GEAR_DOWN);
1453 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1454 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1455 ASSERT_EQ(BTN_GEAR_DOWN, keyArgs.scanCode);
1456
1457 controller->pressAndReleaseKey(BTN_GEAR_UP);
1458 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1459 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1460 ASSERT_EQ(BTN_GEAR_UP, keyArgs.scanCode);
1461}
1462
Prabir Pradhan484d55a2022-10-14 23:17:16 +00001463// --- TouchIntegrationTest ---
1464
Arthur Hungaab25622020-01-16 11:22:11 +08001465class TouchIntegrationTest : public InputReaderIntegrationTest {
1466protected:
Arthur Hungaab25622020-01-16 11:22:11 +08001467 const std::string UNIQUE_ID = "local:0";
1468
Chris Yea52ade12020-08-27 16:49:20 -07001469 void SetUp() override {
Siarhei Vishniakou31977182022-09-30 08:51:23 -07001470#if !defined(__ANDROID__)
1471 GTEST_SKIP();
1472#endif
Arthur Hungaab25622020-01-16 11:22:11 +08001473 InputReaderIntegrationTest::SetUp();
1474 // At least add an internal display.
1475 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
1476 DISPLAY_ORIENTATION_0, UNIQUE_ID, NO_PORT,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01001477 ViewportType::INTERNAL);
Arthur Hungaab25622020-01-16 11:22:11 +08001478
1479 mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
1480 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1481 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
Prabir Pradhanda20b172022-09-26 17:01:18 +00001482 const auto info = findDeviceByName(mDevice->getName());
1483 ASSERT_TRUE(info);
1484 mDeviceInfo = *info;
Arthur Hungaab25622020-01-16 11:22:11 +08001485 }
1486
1487 void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
1488 int32_t orientation, const std::string& uniqueId,
1489 std::optional<uint8_t> physicalPort,
1490 ViewportType viewportType) {
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00001491 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/,
1492 uniqueId, physicalPort, viewportType);
Arthur Hungaab25622020-01-16 11:22:11 +08001493 mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
1494 }
1495
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001496 void assertReceivedMotion(int32_t action, const std::vector<Point>& points) {
1497 NotifyMotionArgs args;
1498 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1499 EXPECT_EQ(action, args.action);
1500 ASSERT_EQ(points.size(), args.pointerCount);
1501 for (size_t i = 0; i < args.pointerCount; i++) {
1502 EXPECT_EQ(points[i].x, args.pointerCoords[i].getX());
1503 EXPECT_EQ(points[i].y, args.pointerCoords[i].getY());
1504 }
1505 }
1506
Arthur Hungaab25622020-01-16 11:22:11 +08001507 std::unique_ptr<UinputTouchScreen> mDevice;
Prabir Pradhanda20b172022-09-26 17:01:18 +00001508 InputDeviceInfo mDeviceInfo;
Arthur Hungaab25622020-01-16 11:22:11 +08001509};
1510
Prabir Pradhanf9a41282022-10-25 17:15:50 +00001511TEST_F(TouchIntegrationTest, MultiTouchDeviceSource) {
1512 // The UinputTouchScreen is an MT device that supports MT_TOOL_TYPE and also supports stylus
1513 // buttons. It should show up as a touchscreen, stylus, and keyboard (for reporting button
1514 // presses).
1515 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD,
1516 mDeviceInfo.getSources());
1517}
1518
Arthur Hungaab25622020-01-16 11:22:11 +08001519TEST_F(TouchIntegrationTest, InputEvent_ProcessSingleTouch) {
1520 NotifyMotionArgs args;
1521 const Point centerPoint = mDevice->getCenterPoint();
1522
1523 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00001524 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001525 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001526 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001527 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1528 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1529
1530 // ACTION_MOVE
1531 mDevice->sendMove(centerPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001532 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001533 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1534 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1535
1536 // ACTION_UP
1537 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001538 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001539 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1540 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1541}
1542
1543TEST_F(TouchIntegrationTest, InputEvent_ProcessMultiTouch) {
1544 NotifyMotionArgs args;
1545 const Point centerPoint = mDevice->getCenterPoint();
1546
1547 // ACTION_DOWN
Arthur Hung9ad18942021-06-19 02:04:46 +00001548 mDevice->sendSlot(FIRST_SLOT);
1549 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001550 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001551 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001552 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1553 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1554
1555 // ACTION_POINTER_DOWN (Second slot)
1556 const Point secondPoint = centerPoint + Point(100, 100);
1557 mDevice->sendSlot(SECOND_SLOT);
1558 mDevice->sendTrackingId(SECOND_TRACKING_ID);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001559 mDevice->sendDown(secondPoint);
1560 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001561 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001562 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001563
1564 // ACTION_MOVE (Second slot)
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001565 mDevice->sendMove(secondPoint + Point(1, 1));
1566 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001567 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1568 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1569
1570 // ACTION_POINTER_UP (Second slot)
arthurhungcc7f9802020-04-30 17:55:40 +08001571 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001572 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001573 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001574 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001575
1576 // ACTION_UP
1577 mDevice->sendSlot(FIRST_SLOT);
1578 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001579 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001580 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1581 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1582}
1583
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001584/**
1585 * What happens when a pointer goes up while another pointer moves in the same frame? Are POINTER_UP
1586 * events guaranteed to contain the same data as a preceding MOVE, or can they contain different
1587 * data?
1588 * In this test, we try to send a change in coordinates in Pointer 0 in the same frame as the
1589 * liftoff of Pointer 1. We check that POINTER_UP event is generated first, and the MOVE event
1590 * for Pointer 0 only is generated after.
1591 * Suppose we are only interested in learning the movement of Pointer 0. If we only observe MOVE
1592 * events, we will not miss any information.
1593 * Even though the Pointer 1 up event contains updated Pointer 0 coordinates, there is another MOVE
1594 * event generated afterwards that contains the newest movement of pointer 0.
1595 * This is important for palm rejection. If there is a subsequent InputListener stage that detects
1596 * palms, and wants to cancel Pointer 1, then it is safe to simply drop POINTER_1_UP event without
1597 * losing information about non-palm pointers.
1598 */
1599TEST_F(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerUp) {
1600 NotifyMotionArgs args;
1601 const Point centerPoint = mDevice->getCenterPoint();
1602
1603 // ACTION_DOWN
1604 mDevice->sendSlot(FIRST_SLOT);
1605 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1606 mDevice->sendDown(centerPoint);
1607 mDevice->sendSync();
1608 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1609
1610 // ACTION_POINTER_DOWN (Second slot)
1611 const Point secondPoint = centerPoint + Point(100, 100);
1612 mDevice->sendSlot(SECOND_SLOT);
1613 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1614 mDevice->sendDown(secondPoint);
1615 mDevice->sendSync();
1616 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1617
1618 // ACTION_MOVE (First slot)
1619 mDevice->sendSlot(FIRST_SLOT);
1620 mDevice->sendMove(centerPoint + Point(5, 5));
1621 // ACTION_POINTER_UP (Second slot)
1622 mDevice->sendSlot(SECOND_SLOT);
1623 mDevice->sendPointerUp();
1624 // Send a single sync for the above 2 pointer updates
1625 mDevice->sendSync();
1626
1627 // First, we should get POINTER_UP for the second pointer
1628 assertReceivedMotion(ACTION_POINTER_1_UP,
1629 {/*first pointer */ centerPoint + Point(5, 5),
1630 /*second pointer*/ secondPoint});
1631
1632 // Next, the MOVE event for the first pointer
1633 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1634}
1635
1636/**
1637 * Similar scenario as above. The difference is that when the second pointer goes up, it will first
1638 * move, and then it will go up, all in the same frame.
1639 * In this scenario, the movement of the second pointer just prior to liftoff is ignored, and never
1640 * gets sent to the listener.
1641 */
1642TEST_F(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerMoveAndUp) {
1643 NotifyMotionArgs args;
1644 const Point centerPoint = mDevice->getCenterPoint();
1645
1646 // ACTION_DOWN
1647 mDevice->sendSlot(FIRST_SLOT);
1648 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1649 mDevice->sendDown(centerPoint);
1650 mDevice->sendSync();
1651 assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1652
1653 // ACTION_POINTER_DOWN (Second slot)
1654 const Point secondPoint = centerPoint + Point(100, 100);
1655 mDevice->sendSlot(SECOND_SLOT);
1656 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1657 mDevice->sendDown(secondPoint);
1658 mDevice->sendSync();
1659 assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1660
1661 // ACTION_MOVE (First slot)
1662 mDevice->sendSlot(FIRST_SLOT);
1663 mDevice->sendMove(centerPoint + Point(5, 5));
1664 // ACTION_POINTER_UP (Second slot)
1665 mDevice->sendSlot(SECOND_SLOT);
1666 mDevice->sendMove(secondPoint + Point(6, 6));
1667 mDevice->sendPointerUp();
1668 // Send a single sync for the above 2 pointer updates
1669 mDevice->sendSync();
1670
1671 // First, we should get POINTER_UP for the second pointer
1672 // The movement of the second pointer during the liftoff frame is ignored.
1673 // The coordinates 'secondPoint + Point(6, 6)' are never sent to the listener.
1674 assertReceivedMotion(ACTION_POINTER_1_UP,
1675 {/*first pointer */ centerPoint + Point(5, 5),
1676 /*second pointer*/ secondPoint});
1677
1678 // Next, the MOVE event for the first pointer
1679 assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1680}
1681
Arthur Hungaab25622020-01-16 11:22:11 +08001682TEST_F(TouchIntegrationTest, InputEvent_ProcessPalm) {
1683 NotifyMotionArgs args;
1684 const Point centerPoint = mDevice->getCenterPoint();
1685
1686 // ACTION_DOWN
arthurhungcc7f9802020-04-30 17:55:40 +08001687 mDevice->sendSlot(FIRST_SLOT);
1688 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Arthur Hungaab25622020-01-16 11:22:11 +08001689 mDevice->sendDown(centerPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001690 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001691 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1692 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1693
arthurhungcc7f9802020-04-30 17:55:40 +08001694 // ACTION_POINTER_DOWN (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001695 const Point secondPoint = centerPoint + Point(100, 100);
1696 mDevice->sendSlot(SECOND_SLOT);
1697 mDevice->sendTrackingId(SECOND_TRACKING_ID);
1698 mDevice->sendDown(secondPoint);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001699 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001700 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001701 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001702
arthurhungcc7f9802020-04-30 17:55:40 +08001703 // ACTION_MOVE (second slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001704 mDevice->sendMove(secondPoint + Point(1, 1));
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001705 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001706 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1707 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1708
arthurhungcc7f9802020-04-30 17:55:40 +08001709 // Send MT_TOOL_PALM (second slot), which indicates that the touch IC has determined this to be
1710 // a palm event.
1711 // Expect to receive the ACTION_POINTER_UP with cancel flag.
Arthur Hungaab25622020-01-16 11:22:11 +08001712 mDevice->sendToolType(MT_TOOL_PALM);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001713 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001714 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08001715 ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
arthurhungcc7f9802020-04-30 17:55:40 +08001716 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, args.flags);
Arthur Hungaab25622020-01-16 11:22:11 +08001717
arthurhungcc7f9802020-04-30 17:55:40 +08001718 // Send up to second slot, expect first slot send moving.
1719 mDevice->sendPointerUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001720 mDevice->sendSync();
arthurhungcc7f9802020-04-30 17:55:40 +08001721 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1722 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001723
arthurhungcc7f9802020-04-30 17:55:40 +08001724 // Send ACTION_UP (first slot)
Arthur Hungaab25622020-01-16 11:22:11 +08001725 mDevice->sendSlot(FIRST_SLOT);
1726 mDevice->sendUp();
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -08001727 mDevice->sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +08001728
arthurhungcc7f9802020-04-30 17:55:40 +08001729 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1730 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Arthur Hungaab25622020-01-16 11:22:11 +08001731}
1732
Prabir Pradhanda20b172022-09-26 17:01:18 +00001733TEST_F(TouchIntegrationTest, NotifiesPolicyWhenStylusGestureStarted) {
1734 const Point centerPoint = mDevice->getCenterPoint();
1735
1736 // Send down with the pen tool selected. The policy should be notified of the stylus presence.
1737 mDevice->sendSlot(FIRST_SLOT);
1738 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1739 mDevice->sendToolType(MT_TOOL_PEN);
1740 mDevice->sendDown(centerPoint);
1741 mDevice->sendSync();
1742 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1743 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1744 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
1745
1746 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
1747
1748 // Release the stylus touch.
1749 mDevice->sendUp();
1750 mDevice->sendSync();
1751 ASSERT_NO_FATAL_FAILURE(
1752 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1753
1754 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
1755
1756 // Touch down with the finger, without the pen tool selected. The policy is not notified.
1757 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1758 mDevice->sendToolType(MT_TOOL_FINGER);
1759 mDevice->sendDown(centerPoint);
1760 mDevice->sendSync();
1761 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1762 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1763 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
1764
1765 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
1766
1767 mDevice->sendUp();
1768 mDevice->sendSync();
1769 ASSERT_NO_FATAL_FAILURE(
1770 mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
1771
1772 // Send a move event with the stylus tool without BTN_TOUCH to generate a hover enter.
1773 // The policy should be notified of the stylus presence.
1774 mDevice->sendTrackingId(FIRST_TRACKING_ID);
1775 mDevice->sendToolType(MT_TOOL_PEN);
1776 mDevice->sendMove(centerPoint);
1777 mDevice->sendSync();
1778 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
1779 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1780 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
1781
1782 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
1783}
1784
Prabir Pradhan124ea442022-10-28 20:27:44 +00001785// --- StylusButtonIntegrationTest ---
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001786
Prabir Pradhan124ea442022-10-28 20:27:44 +00001787// Verify the behavior of button presses reported by various kinds of styluses, including buttons
1788// reported by the touchscreen's device, by a fused external stylus, and by an un-fused external
1789// stylus.
1790template <typename UinputStylusDevice>
1791class StylusButtonIntegrationTest : public TouchIntegrationTest {
1792protected:
1793 void SetUp() override {
1794#if !defined(__ANDROID__)
1795 GTEST_SKIP();
1796#endif
1797 TouchIntegrationTest::SetUp();
1798 mTouchscreen = mDevice.get();
1799 mTouchscreenInfo = mDeviceInfo;
1800
1801 setUpStylusDevice();
1802 }
1803
1804 UinputStylusDevice* mStylus{nullptr};
1805 InputDeviceInfo mStylusInfo{};
1806
1807 UinputTouchScreen* mTouchscreen{nullptr};
1808 InputDeviceInfo mTouchscreenInfo{};
1809
1810private:
1811 // When we are attempting to test stylus button events that are sent from the touchscreen,
1812 // use the same Uinput device for the touchscreen and the stylus.
1813 template <typename T = UinputStylusDevice>
1814 std::enable_if_t<std::is_same_v<UinputTouchScreen, T>, void> setUpStylusDevice() {
1815 mStylus = mDevice.get();
1816 mStylusInfo = mDeviceInfo;
1817 }
1818
1819 // When we are attempting to stylus buttons from an external stylus being merged with touches
1820 // from a touchscreen, create a new Uinput device through which stylus buttons can be injected.
1821 template <typename T = UinputStylusDevice>
1822 std::enable_if_t<!std::is_same_v<UinputTouchScreen, T>, void> setUpStylusDevice() {
1823 mStylusDeviceLifecycleTracker = createUinputDevice<T>();
1824 mStylus = mStylusDeviceLifecycleTracker.get();
1825 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1826 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
1827 const auto info = findDeviceByName(mStylus->getName());
1828 ASSERT_TRUE(info);
1829 mStylusInfo = *info;
1830 }
1831
1832 std::unique_ptr<UinputStylusDevice> mStylusDeviceLifecycleTracker{};
1833
1834 // Hide the base class's device to expose it with a different name for readability.
1835 using TouchIntegrationTest::mDevice;
1836 using TouchIntegrationTest::mDeviceInfo;
1837};
1838
1839using StylusButtonIntegrationTestTypes =
1840 ::testing::Types<UinputTouchScreen, UinputExternalStylus, UinputExternalStylusWithPressure>;
1841TYPED_TEST_SUITE(StylusButtonIntegrationTest, StylusButtonIntegrationTestTypes);
1842
1843TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsGenerateKeyEvents) {
1844 const auto stylusId = TestFixture::mStylusInfo.getId();
1845
1846 TestFixture::mStylus->pressKey(BTN_STYLUS);
1847 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
1848 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
1849 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
1850
1851 TestFixture::mStylus->releaseKey(BTN_STYLUS);
1852 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001853 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001854 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhane1a41a82022-10-14 18:06:50 +00001855}
1856
Prabir Pradhan124ea442022-10-28 20:27:44 +00001857TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingTouchGesture) {
1858 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
1859 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
1860 const auto stylusId = TestFixture::mStylusInfo.getId();
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001861
1862 // Press the stylus button.
Prabir Pradhan124ea442022-10-28 20:27:44 +00001863 TestFixture::mStylus->pressKey(BTN_STYLUS);
1864 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001865 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001866 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001867
1868 // Start and finish a stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00001869 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
1870 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
1871 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
1872 TestFixture::mTouchscreen->sendDown(centerPoint);
1873 TestFixture::mTouchscreen->sendSync();
1874 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001875 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1876 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001877 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
1878 WithDeviceId(touchscreenId))));
1879 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001880 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1881 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001882 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
1883 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001884
Prabir Pradhan124ea442022-10-28 20:27:44 +00001885 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
1886 TestFixture::mTouchscreen->sendSync();
1887 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001888 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001889 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
1890 WithDeviceId(touchscreenId))));
1891 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001892 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001893 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
1894 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001895
1896 // Release the stylus button.
Prabir Pradhan124ea442022-10-28 20:27:44 +00001897 TestFixture::mStylus->releaseKey(BTN_STYLUS);
1898 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001899 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001900 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001901}
1902
Prabir Pradhan9a561c22022-11-07 16:11:23 +00001903TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingHoveringTouchGesture) {
1904 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
1905 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
1906 const auto stylusId = TestFixture::mStylusInfo.getId();
1907 auto toolTypeDevice =
1908 AllOf(WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithDeviceId(touchscreenId));
1909
1910 // Press the stylus button.
1911 TestFixture::mStylus->pressKey(BTN_STYLUS);
1912 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
1913 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
1914 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
1915
1916 // Start hovering with the stylus.
1917 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
1918 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
1919 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
1920 TestFixture::mTouchscreen->sendMove(centerPoint);
1921 TestFixture::mTouchscreen->sendSync();
1922 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1923 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1924 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1925 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1926 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
1927 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1928 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1929 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
1930 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1931
1932 // Touch down with the stylus.
1933 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
1934 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
1935 TestFixture::mTouchscreen->sendDown(centerPoint);
1936 TestFixture::mTouchscreen->sendSync();
1937 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1938 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
1939 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1940
1941 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1942 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
1943 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1944
1945 // Stop touching with the stylus, and start hovering.
1946 TestFixture::mTouchscreen->sendUp();
1947 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
1948 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
1949 TestFixture::mTouchscreen->sendMove(centerPoint);
1950 TestFixture::mTouchscreen->sendSync();
1951 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1952 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_UP),
1953 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1954 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1955 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
1956 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1957 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1958 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
1959 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1960
1961 // Stop hovering.
1962 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
1963 TestFixture::mTouchscreen->sendSync();
1964 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1965 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
1966 WithButtonState(0))));
1967 // TODO(b/257971675): Fix inconsistent button state when exiting hover.
1968 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
1969 AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
1970 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
1971
1972 // Release the stylus button.
1973 TestFixture::mStylus->releaseKey(BTN_STYLUS);
1974 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
1975 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
1976 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
1977}
1978
Prabir Pradhan124ea442022-10-28 20:27:44 +00001979TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsWithinTouchGesture) {
1980 const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
1981 const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
1982 const auto stylusId = TestFixture::mStylusInfo.getId();
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001983
1984 // Start a stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00001985 TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
1986 TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
1987 TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
1988 TestFixture::mTouchscreen->sendDown(centerPoint);
1989 TestFixture::mTouchscreen->sendSync();
1990 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001991 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001992 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
1993 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001994
1995 // Press and release a stylus button. Each change in button state also generates a MOVE event.
Prabir Pradhan124ea442022-10-28 20:27:44 +00001996 TestFixture::mStylus->pressKey(BTN_STYLUS);
1997 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00001998 AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00001999 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2000 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002001 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
2002 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002003 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2004 WithDeviceId(touchscreenId))));
2005 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002006 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
2007 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002008 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2009 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002010
Prabir Pradhan124ea442022-10-28 20:27:44 +00002011 TestFixture::mStylus->releaseKey(BTN_STYLUS);
2012 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002013 AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002014 WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2015 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002016 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002017 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2018 WithDeviceId(touchscreenId))));
2019 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002020 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002021 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2022 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002023
2024 // Finish the stylus gesture.
Prabir Pradhan124ea442022-10-28 20:27:44 +00002025 TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2026 TestFixture::mTouchscreen->sendSync();
2027 ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002028 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Prabir Pradhan124ea442022-10-28 20:27:44 +00002029 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2030 WithDeviceId(touchscreenId))));
Prabir Pradhan7bffbf52022-10-14 20:31:53 +00002031}
2032
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002033// --- ExternalStylusIntegrationTest ---
2034
2035// Verify the behavior of an external stylus. An external stylus can report pressure or button
2036// data independently of the touchscreen, which is then sent as a MotionEvent as part of an
2037// ongoing stylus gesture that is being emitted by the touchscreen.
2038using ExternalStylusIntegrationTest = TouchIntegrationTest;
2039
2040TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureReported) {
2041 const Point centerPoint = mDevice->getCenterPoint();
2042
2043 // Create an external stylus capable of reporting pressure data that
2044 // should be fused with a touch pointer.
2045 std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2046 createUinputDevice<UinputExternalStylusWithPressure>();
2047 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2048 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2049 const auto stylusInfo = findDeviceByName(stylus->getName());
2050 ASSERT_TRUE(stylusInfo);
2051
2052 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2053
2054 const auto touchscreenId = mDeviceInfo.getId();
2055
2056 // Set a pressure value on the stylus. It doesn't generate any events.
2057 const auto& RAW_PRESSURE_MAX = UinputExternalStylusWithPressure::RAW_PRESSURE_MAX;
2058 stylus->setPressure(100);
2059 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2060
2061 // Start a finger gesture, and ensure it shows up as stylus gesture
2062 // with the pressure set by the external stylus.
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002063 mDevice->sendSlot(FIRST_SLOT);
Chris Ye1b0c7342020-07-28 21:57:03 -07002064 mDevice->sendTrackingId(FIRST_TRACKING_ID);
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002065 mDevice->sendToolType(MT_TOOL_FINGER);
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002066 mDevice->sendDown(centerPoint);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067 mDevice->sendSync();
2068 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2069 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002070 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2071 WithDeviceId(touchscreenId), WithPressure(100.f / RAW_PRESSURE_MAX))));
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002072
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002073 // Change the pressure on the external stylus, and ensure the touchscreen generates a MOVE
2074 // event with the updated pressure.
2075 stylus->setPressure(200);
Vaibhav Devmuraridd82b8e2022-08-16 15:34:01 +00002076 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2077 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002078 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2079 WithDeviceId(touchscreenId), WithPressure(200.f / RAW_PRESSURE_MAX))));
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002080
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002081 // The external stylus did not generate any events.
2082 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2083 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2084}
2085
2086TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) {
2087 const Point centerPoint = mDevice->getCenterPoint();
2088
2089 // Create an external stylus capable of reporting pressure data that
2090 // should be fused with a touch pointer.
2091 std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2092 createUinputDevice<UinputExternalStylusWithPressure>();
2093 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2094 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2095 const auto stylusInfo = findDeviceByName(stylus->getName());
2096 ASSERT_TRUE(stylusInfo);
2097
2098 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2099
2100 const auto touchscreenId = mDeviceInfo.getId();
2101
2102 // Set a pressure value of 0 on the stylus. It doesn't generate any events.
2103 const auto& RAW_PRESSURE_MAX = UinputExternalStylusWithPressure::RAW_PRESSURE_MAX;
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002104 // Send a non-zero value first to prevent the kernel from consuming the zero event.
2105 stylus->setPressure(100);
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002106 stylus->setPressure(0);
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002107 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002108
2109 // Start a finger gesture. The touch device will withhold generating any touches for
2110 // up to 72 milliseconds while waiting for pressure data from the external stylus.
2111 mDevice->sendSlot(FIRST_SLOT);
2112 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2113 mDevice->sendToolType(MT_TOOL_FINGER);
2114 mDevice->sendDown(centerPoint);
2115 auto waitUntil = std::chrono::system_clock::now() +
2116 std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT));
Siarhei Vishniakoue54cb852017-03-21 17:48:16 -07002117 mDevice->sendSync();
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002118 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled(waitUntil));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002119
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002120 // Since the external stylus did not report a pressure value within the timeout,
2121 // it shows up as a finger pointer.
2122 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2123 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2124 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER), WithDeviceId(touchscreenId),
2125 WithPressure(1.f))));
2126
2127 // Change the pressure on the external stylus. Since the pressure was not present at the start
2128 // of the gesture, it is ignored for now.
2129 stylus->setPressure(200);
2130 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2131
2132 // Finish the finger gesture.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002133 mDevice->sendTrackingId(INVALID_TRACKING_ID);
2134 mDevice->sendSync();
2135 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2136 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
Prabir Pradhan484d55a2022-10-14 23:17:16 +00002137 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
2138
2139 // Start a new gesture. Since we have a valid pressure value, it shows up as a stylus.
2140 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2141 mDevice->sendToolType(MT_TOOL_FINGER);
2142 mDevice->sendDown(centerPoint);
2143 mDevice->sendSync();
2144 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2145 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2146 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0),
2147 WithDeviceId(touchscreenId), WithPressure(200.f / RAW_PRESSURE_MAX))));
2148
2149 // The external stylus did not generate any events.
2150 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2151 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002152}
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002153
Prabir Pradhan3f7545f2022-10-19 16:56:39 +00002154TEST_F(ExternalStylusIntegrationTest, UnfusedExternalStylus) {
2155 const Point centerPoint = mDevice->getCenterPoint();
2156
2157 // Create an external stylus device that does not support pressure. It should not affect any
2158 // touch pointers.
2159 std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
2160 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2161 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
2162 const auto stylusInfo = findDeviceByName(stylus->getName());
2163 ASSERT_TRUE(stylusInfo);
2164
2165 ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2166
2167 const auto touchscreenId = mDeviceInfo.getId();
2168
2169 // Start a finger gesture and ensure a finger pointer is generated for it, without waiting for
2170 // pressure data from the external stylus.
2171 mDevice->sendSlot(FIRST_SLOT);
2172 mDevice->sendTrackingId(FIRST_TRACKING_ID);
2173 mDevice->sendToolType(MT_TOOL_FINGER);
2174 mDevice->sendDown(centerPoint);
2175 auto waitUntil = std::chrono::system_clock::now() +
2176 std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT));
2177 mDevice->sendSync();
2178 ASSERT_NO_FATAL_FAILURE(
2179 mTestListener
2180 ->assertNotifyMotionWasCalled(AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2181 WithToolType(
2182 AMOTION_EVENT_TOOL_TYPE_FINGER),
2183 WithButtonState(0),
2184 WithDeviceId(touchscreenId),
2185 WithPressure(1.f)),
2186 waitUntil));
2187
2188 // The external stylus did not generate any events.
2189 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2190 ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2191}
2192
Michael Wrightd02c5b62014-02-10 15:10:22 -08002193// --- InputDeviceTest ---
2194class InputDeviceTest : public testing::Test {
2195protected:
2196 static const char* DEVICE_NAME;
2197 static const char* DEVICE_LOCATION;
2198 static const int32_t DEVICE_ID;
2199 static const int32_t DEVICE_GENERATION;
2200 static const int32_t DEVICE_CONTROLLER_NUMBER;
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002201 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002202 static const int32_t EVENTHUB_ID;
2203 static const std::string DEVICE_BLUETOOTH_ADDRESS;
2204
2205 std::shared_ptr<FakeEventHub> mFakeEventHub;
2206 sp<FakeInputReaderPolicy> mFakePolicy;
2207 std::unique_ptr<TestInputListener> mFakeListener;
2208 std::unique_ptr<InstrumentedInputReader> mReader;
2209 std::shared_ptr<InputDevice> mDevice;
2210
2211 void SetUp() override {
2212 mFakeEventHub = std::make_unique<FakeEventHub>();
2213 mFakePolicy = sp<FakeInputReaderPolicy>::make();
2214 mFakeListener = std::make_unique<TestInputListener>();
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002215 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002216 *mFakeListener);
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002217 InputDeviceIdentifier identifier;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002218 identifier.name = DEVICE_NAME;
2219 identifier.location = DEVICE_LOCATION;
2220 identifier.bluetoothAddress = DEVICE_BLUETOOTH_ADDRESS;
2221 mDevice = std::make_shared<InputDevice>(mReader->getContext(), DEVICE_ID, DEVICE_GENERATION,
2222 identifier);
2223 mReader->pushNextDevice(mDevice);
2224 mFakeEventHub->addDevice(EVENTHUB_ID, DEVICE_NAME, ftl::Flags<InputDeviceClass>(0));
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002225 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002226 }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002227
2228 void TearDown() override {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002229 mFakeListener.reset();
2230 mFakePolicy.clear();
2231 }
2232};
2233
2234const char* InputDeviceTest::DEVICE_NAME = "device";
2235const char* InputDeviceTest::DEVICE_LOCATION = "USB1";
2236const int32_t InputDeviceTest::DEVICE_ID = END_RESERVED_ID + 1000;
2237const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002238const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002239const ftl::Flags<InputDeviceClass> InputDeviceTest::DEVICE_CLASSES =
2240 InputDeviceClass::KEYBOARD | InputDeviceClass::TOUCH | InputDeviceClass::JOYSTICK;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002241const int32_t InputDeviceTest::EVENTHUB_ID = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002242const std::string InputDeviceTest::DEVICE_BLUETOOTH_ADDRESS = "11:AA:22:BB:33:CC";
2243
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002244TEST_F(InputDeviceTest, ImmutableProperties) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002245 ASSERT_EQ(DEVICE_ID, mDevice->getId());
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002246 ASSERT_STREQ(DEVICE_NAME, mDevice->getName().c_str());
2247 ASSERT_EQ(ftl::Flags<InputDeviceClass>(0), mDevice->getClasses());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002248}
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002249
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250TEST_F(InputDeviceTest, CountryCodeCorrectlyMapped) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002251 mFakeEventHub->setCountryCode(EVENTHUB_ID, InputDeviceCountryCode::INTERNATIONAL);
2252
Michael Wrightd02c5b62014-02-10 15:10:22 -08002253 // Configuration
2254 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002255 InputReaderConfiguration config;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002256 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
2257
Michael Wrightd02c5b62014-02-10 15:10:22 -08002258 ASSERT_EQ(InputDeviceCountryCode::INTERNATIONAL, mDevice->getDeviceInfo().getCountryCode());
2259}
2260
2261TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsFalse) {
2262 ASSERT_EQ(mDevice->isEnabled(), false);
2263}
2264
2265TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
2266 // Configuration.
2267 InputReaderConfiguration config;
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00002268 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002269
Siarhei Vishniakouec8f7252018-07-06 11:19:32 +01002270 // Reset.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271 unused += mDevice->reset(ARBITRARY_TIME);
2272
2273 NotifyDeviceResetArgs resetArgs;
2274 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2275 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2276 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2277
2278 // Metadata.
2279 ASSERT_TRUE(mDevice->isIgnored());
2280 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
2281
2282 InputDeviceInfo info = mDevice->getDeviceInfo();
2283 ASSERT_EQ(DEVICE_ID, info.getId());
2284 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
2285 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
2286 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
2287
2288 // State queries.
2289 ASSERT_EQ(0, mDevice->getMetaState());
2290
2291 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002292 << "Ignored device should return unknown key code state.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002293 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002294 << "Ignored device should return unknown scan code state.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002295 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
2296 << "Ignored device should return unknown switch state.";
2297
2298 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B};
2299 uint8_t flags[2] = { 0, 1 };
2300 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
Siarhei Vishniakou74007942022-06-13 13:57:47 -07002301 << "Ignored device should never mark any key codes.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002302 ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
2303 ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
2304}
2305
2306TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
2307 // Configuration.
2308 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "key", "value");
2309
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002310 FakeInputMapper& mapper1 =
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002311 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002312 mapper1.setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002313 mapper1.setMetaState(AMETA_ALT_ON);
2314 mapper1.addSupportedKeyCode(AKEYCODE_A);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002315 mapper1.addSupportedKeyCode(AKEYCODE_B);
2316 mapper1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002317 mapper1.setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
2318 mapper1.setScanCodeState(2, AKEY_STATE_DOWN);
2319 mapper1.setScanCodeState(3, AKEY_STATE_UP);
2320 mapper1.setSwitchState(4, AKEY_STATE_DOWN);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002321
Arthur Hung2c9a3342019-07-23 14:18:59 +08002322 FakeInputMapper& mapper2 =
2323 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_TOUCHSCREEN);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002324 mapper2.setMetaState(AMETA_SHIFT_ON);
2325
Arthur Hung2c9a3342019-07-23 14:18:59 +08002326 InputReaderConfiguration config;
2327 std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, &config, 0);
2328
2329 std::string propertyValue;
2330 ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty("key", propertyValue))
2331 << "Device should have read configuration during configuration phase.";
2332 ASSERT_EQ("value", propertyValue);
2333
2334 ASSERT_NO_FATAL_FAILURE(mapper1.assertConfigureWasCalled());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002335 ASSERT_NO_FATAL_FAILURE(mapper2.assertConfigureWasCalled());
2336
Arthur Hung2c9a3342019-07-23 14:18:59 +08002337 // Reset
2338 unused += mDevice->reset(ARBITRARY_TIME);
2339 ASSERT_NO_FATAL_FAILURE(mapper1.assertResetWasCalled());
2340 ASSERT_NO_FATAL_FAILURE(mapper2.assertResetWasCalled());
2341
2342 NotifyDeviceResetArgs resetArgs;
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002343 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2344 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002345 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2346
Arthur Hung2c9a3342019-07-23 14:18:59 +08002347 // Metadata.
2348 ASSERT_FALSE(mDevice->isIgnored());
2349 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
2350
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002351 InputDeviceInfo info = mDevice->getDeviceInfo();
2352 ASSERT_EQ(DEVICE_ID, info.getId());
Arthur Hung2c9a3342019-07-23 14:18:59 +08002353 ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
2354 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
2355 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002356
2357 // State queries.
Arthur Hung2c9a3342019-07-23 14:18:59 +08002358 ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
2359 << "Should query mappers and combine meta states.";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002360
Christine Franks1ba71cc2021-04-07 14:37:42 -07002361 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2362 << "Should return unknown key code state when source not supported.";
2363 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2364 << "Should return unknown scan code state when source not supported.";
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002365 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2366 << "Should return unknown switch state when source not supported.";
Christine Franks1ba71cc2021-04-07 14:37:42 -07002367
2368 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
2369 << "Should query mapper when source is supported.";
2370 ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
Christine Franks2a2293c2022-01-18 11:51:16 -08002371 << "Should query mapper when source is supported.";
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002372 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
2373 << "Should query mapper when source is supported.";
Christine Franks1ba71cc2021-04-07 14:37:42 -07002374
2375 const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
2376 uint8_t flags[4] = { 0, 0, 0, 1 };
2377 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
2378 << "Should do nothing when source is unsupported.";
2379 ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002380 ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
2381 ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
Christine Franks1ba71cc2021-04-07 14:37:42 -07002382 ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
2383
2384 ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
2385 << "Should query mapper when source is supported.";
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002386 ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
2387 ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
Christine Franks1ba71cc2021-04-07 14:37:42 -07002388 ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
2389 ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
2390
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002391 // Event handling.
2392 RawEvent event;
Christine Franks1ba71cc2021-04-07 14:37:42 -07002393 event.deviceId = EVENTHUB_ID;
2394 unused += mDevice->process(&event, 1);
2395
Christine Franks2a2293c2022-01-18 11:51:16 -08002396 ASSERT_NO_FATAL_FAILURE(mapper1.assertProcessWasCalled());
2397 ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled());
2398}
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002399
2400// A single input device is associated with a specific display. Check that:
Christine Franks2a2293c2022-01-18 11:51:16 -08002401// 1. Device is disabled if the viewport corresponding to the associated display is not found
Christine Franks2a2293c2022-01-18 11:51:16 -08002402// 2. Device is disabled when setEnabled API is called
2403TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) {
2404 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_TOUCHSCREEN);
2405
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002406 // First Configuration.
2407 std::list<NotifyArgs> unused =
Christine Franks2a2293c2022-01-18 11:51:16 -08002408 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
2409
2410 // Device should be enabled by default.
Siarhei Vishniakou30feb8c2022-09-28 10:48:29 -07002411 ASSERT_TRUE(mDevice->isEnabled());
2412
2413 // Prepare associated info.
2414 constexpr uint8_t hdmi = 1;
2415 const std::string UNIQUE_ID = "local:1";
2416
2417 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi);
2418 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2419 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2420 // Device should be disabled because it is associated with a specific display via
2421 // input port <-> display port association, but the corresponding display is not found
2422 ASSERT_FALSE(mDevice->isEnabled());
2423
2424 // Prepare displays.
2425 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002426 DISPLAY_ORIENTATION_0, true /*isActive*/, UNIQUE_ID, hdmi,
2427 ViewportType::INTERNAL);
2428 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2429 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2430 ASSERT_TRUE(mDevice->isEnabled());
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07002431
Michael Wrightd02c5b62014-02-10 15:10:22 -08002432 // Device should be disabled after set disable.
2433 mFakePolicy->addDisabledDevice(mDevice->getId());
2434 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002435 InputReaderConfiguration::CHANGE_ENABLED_STATE);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002436 ASSERT_FALSE(mDevice->isEnabled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002437
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07002438 // Device should still be disabled even found the associated display.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002439 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002440 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
arthurhungdcef2dc2020-08-11 14:47:50 +08002441 ASSERT_FALSE(mDevice->isEnabled());
2442}
Michael Wrightd02c5b62014-02-10 15:10:22 -08002443
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002444TEST_F(InputDeviceTest, Configure_AssignsDisplayUniqueId) {
Siarhei Vishniakou3bc7e092019-07-24 17:43:30 -07002445 // Device should be enabled by default.
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -07002446 mFakePolicy->clearViewports();
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002447 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
arthurhungdcef2dc2020-08-11 14:47:50 +08002448 std::list<NotifyArgs> unused =
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002449 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
arthurhungdcef2dc2020-08-11 14:47:50 +08002450 ASSERT_TRUE(mDevice->isEnabled());
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002451
2452 // Device should be disabled because it is associated with a specific display, but the
Michael Wrightd02c5b62014-02-10 15:10:22 -08002453 // corresponding display is not found.
2454 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07002455 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhanc14266f2021-05-12 15:56:24 -07002456 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2457 ASSERT_FALSE(mDevice->isEnabled());
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002458
Chris Yea52ade12020-08-27 16:49:20 -07002459 // Device should be enabled when a display is found.
Siarhei Vishniakou18050092021-09-01 13:32:49 -07002460 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002461 DISPLAY_ORIENTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002462 NO_PORT, ViewportType::INTERNAL);
2463 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2464 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Siarhei Vishniakou4f94c1a2022-07-13 07:29:51 -07002465 ASSERT_TRUE(mDevice->isEnabled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002466
2467 // Device should be disabled after set disable.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002468 mFakePolicy->addDisabledDevice(mDevice->getId());
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00002469 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2470 InputReaderConfiguration::CHANGE_ENABLED_STATE);
2471 ASSERT_FALSE(mDevice->isEnabled());
2472
arthurhungdcef2dc2020-08-11 14:47:50 +08002473 // Device should still be disabled even found the associated display.
2474 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
Prabir Pradhanc7ef27e2020-02-03 19:19:15 -08002475 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002476 ASSERT_FALSE(mDevice->isEnabled());
2477}
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002478
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002479TEST_F(InputDeviceTest, Configure_UniqueId_CorrectlyMatches) {
2480 mFakePolicy->clearViewports();
2481 mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002482 std::list<NotifyArgs> unused =
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002483 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08002484
2485 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
arthurhungdcef2dc2020-08-11 14:47:50 +08002486 mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
2487 DISPLAY_ORIENTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002488 NO_PORT, ViewportType::INTERNAL);
arthurhungdcef2dc2020-08-11 14:47:50 +08002489 unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2490 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2491 ASSERT_EQ(DISPLAY_UNIQUE_ID, mDevice->getAssociatedDisplayUniqueId());
2492}
2493
2494/**
2495 * This test reproduces a crash caused by a dangling reference that remains after device is added
2496 * and removed. The reference is accessed in InputDevice::dump(..);
2497 */
2498TEST_F(InputDeviceTest, DumpDoesNotCrash) {
2499 constexpr int32_t TEST_EVENTHUB_ID = 10;
2500 mFakeEventHub->addDevice(TEST_EVENTHUB_ID, "Test EventHub device", InputDeviceClass::BATTERY);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002501
2502 InputDevice device(mReader->getContext(), 1 /*id*/, 2 /*generation*/, {} /*identifier*/);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002503 device.addEventHubDevice(TEST_EVENTHUB_ID, true /*populateMappers*/);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08002504 device.removeEventHubDevice(TEST_EVENTHUB_ID);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002505 std::string dumpStr, eventHubDevStr;
2506 device.dump(dumpStr, eventHubDevStr);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002507}
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002508
Prabir Pradhanb54ffb22022-10-27 18:03:34 +00002509TEST_F(InputDeviceTest, GetBluetoothAddress) {
2510 const auto& address = mReader->getBluetoothAddress(DEVICE_ID);
2511 ASSERT_TRUE(address);
2512 ASSERT_EQ(DEVICE_BLUETOOTH_ADDRESS, *address);
2513}
2514
Michael Wrightd02c5b62014-02-10 15:10:22 -08002515// --- InputMapperTest ---
2516
2517class InputMapperTest : public testing::Test {
2518protected:
2519 static const char* DEVICE_NAME;
2520 static const char* DEVICE_LOCATION;
2521 static const int32_t DEVICE_ID;
2522 static const int32_t DEVICE_GENERATION;
2523 static const int32_t DEVICE_CONTROLLER_NUMBER;
2524 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
2525 static const int32_t EVENTHUB_ID;
2526
2527 std::shared_ptr<FakeEventHub> mFakeEventHub;
2528 sp<FakeInputReaderPolicy> mFakePolicy;
2529 std::unique_ptr<TestInputListener> mFakeListener;
2530 std::unique_ptr<InstrumentedInputReader> mReader;
2531 std::shared_ptr<InputDevice> mDevice;
2532
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002533 virtual void SetUp(ftl::Flags<InputDeviceClass> classes, int bus = 0) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002534 mFakeEventHub = std::make_unique<FakeEventHub>();
2535 mFakePolicy = sp<FakeInputReaderPolicy>::make();
2536 mFakeListener = std::make_unique<TestInputListener>();
2537 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
2538 *mFakeListener);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002539 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes, bus);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002540 // Consume the device reset notification generated when adding a new device.
2541 mFakeListener->assertNotifyDeviceResetWasCalled();
2542 }
2543
2544 void SetUp() override {
2545 SetUp(DEVICE_CLASSES);
2546 }
2547
2548 void TearDown() override {
2549 mFakeListener.reset();
2550 mFakePolicy.clear();
2551 }
2552
2553 void addConfigurationProperty(const char* key, const char* value) {
2554 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, key, value);
2555 }
2556
2557 std::list<NotifyArgs> configureDevice(uint32_t changes) {
2558 if (!changes ||
2559 (changes &
2560 (InputReaderConfiguration::CHANGE_DISPLAY_INFO |
2561 InputReaderConfiguration::CHANGE_POINTER_CAPTURE))) {
2562 mReader->requestRefreshConfiguration(changes);
2563 mReader->loopOnce();
2564 }
2565 std::list<NotifyArgs> out =
2566 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
2567 // Loop the reader to flush the input listener queue.
2568 for (const NotifyArgs& args : out) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002569 mFakeListener->notify(args);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002570 }
2571 mReader->loopOnce();
2572 return out;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07002573 }
2574
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002575 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07002576 const std::string& location, int32_t eventHubId,
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002577 ftl::Flags<InputDeviceClass> classes, int bus = 0) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07002578 InputDeviceIdentifier identifier;
2579 identifier.name = name;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002580 identifier.location = location;
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002581 identifier.bus = bus;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002582 std::shared_ptr<InputDevice> device =
Michael Wrightd02c5b62014-02-10 15:10:22 -08002583 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
2584 identifier);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002585 mReader->pushNextDevice(device);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00002586 mFakeEventHub->addDevice(eventHubId, name, classes, bus);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002587 mReader->loopOnce();
2588 return device;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002589 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002590
2591 template <class T, typename... Args>
2592 T& addMapperAndConfigure(Args... args) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002593 T& mapper = mDevice->addMapper<T>(EVENTHUB_ID, args...);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002594 configureDevice(0);
2595 std::list<NotifyArgs> resetArgList = mDevice->reset(ARBITRARY_TIME);
Chris Ye42b06822020-08-07 11:39:33 -07002596 resetArgList += mapper.reset(ARBITRARY_TIME);
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002597 // Loop the reader to flush the input listener queue.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002598 for (const NotifyArgs& loopArgs : resetArgList) {
2599 mFakeListener->notify(loopArgs);
2600 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002601 mReader->loopOnce();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002602 return mapper;
2603 }
2604
2605 void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
2606 int32_t orientation, const std::string& uniqueId,
2607 std::optional<uint8_t> physicalPort, ViewportType viewportType) {
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00002608 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, true /*isActive*/,
2609 uniqueId, physicalPort, viewportType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002610 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2611 }
2612
2613 void clearViewports() {
2614 mFakePolicy->clearViewports();
2615 }
2616
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002617 std::list<NotifyArgs> process(InputMapper& mapper, nsecs_t when, nsecs_t readTime, int32_t type,
2618 int32_t code, int32_t value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002619 RawEvent event;
2620 event.when = when;
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002621 event.readTime = readTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002622 event.deviceId = mapper.getDeviceContext().getEventHubId();
2623 event.type = type;
2624 event.code = code;
2625 event.value = value;
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002626 std::list<NotifyArgs> processArgList = mapper.process(&event);
2627 for (const NotifyArgs& args : processArgList) {
2628 mFakeListener->notify(args);
2629 }
Prabir Pradhanb5174de2022-08-05 22:26:56 +00002630 // Loop the reader to flush the input listener queue.
arthurhungdcef2dc2020-08-11 14:47:50 +08002631 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002632 return processArgList;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002633 }
2634
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00002635 void resetMapper(InputMapper& mapper, nsecs_t when) {
2636 const auto resetArgs = mapper.reset(when);
2637 for (const auto args : resetArgs) {
2638 mFakeListener->notify(args);
2639 }
2640 // Loop the reader to flush the input listener queue.
2641 mReader->loopOnce();
2642 }
2643
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00002644 std::list<NotifyArgs> handleTimeout(InputMapper& mapper, nsecs_t when) {
2645 std::list<NotifyArgs> generatedArgs = mapper.timeoutExpired(when);
2646 for (const NotifyArgs& args : generatedArgs) {
2647 mFakeListener->notify(args);
2648 }
2649 // Loop the reader to flush the input listener queue.
2650 mReader->loopOnce();
2651 return generatedArgs;
2652 }
2653
Michael Wrightd02c5b62014-02-10 15:10:22 -08002654 static void assertMotionRange(const InputDeviceInfo& info,
2655 int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) {
2656 const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
Yi Kong9b14ac62018-07-17 13:48:38 -07002657 ASSERT_TRUE(range != nullptr) << "Axis: " << axis << " Source: " << source;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002658 ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
2659 ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
2660 ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
2661 ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
2662 ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
2663 ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
2664 }
2665
Prabir Pradhanf5334b82021-05-13 14:00:39 -07002666 static void assertPointerCoords(const PointerCoords& coords, float x, float y, float pressure,
2667 float size, float touchMajor, float touchMinor, float toolMajor,
2668 float toolMinor, float orientation, float distance,
2669 float scaledAxisEpsilon = 1.f) {
2670 ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), scaledAxisEpsilon);
2671 ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), scaledAxisEpsilon);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002672 ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
2673 ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07002674 ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2675 scaledAxisEpsilon);
2676 ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2677 scaledAxisEpsilon);
2678 ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2679 scaledAxisEpsilon);
2680 ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2681 scaledAxisEpsilon);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002682 ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
2683 ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
2684 }
2685
Michael Wright17db18e2020-06-26 20:51:44 +01002686 static void assertPosition(const FakePointerController& controller, float x, float y) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002687 float actualX, actualY;
Michael Wright17db18e2020-06-26 20:51:44 +01002688 controller.getPosition(&actualX, &actualY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002689 ASSERT_NEAR(x, actualX, 1);
2690 ASSERT_NEAR(y, actualY, 1);
2691 }
2692};
2693
2694const char* InputMapperTest::DEVICE_NAME = "device";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07002695const char* InputMapperTest::DEVICE_LOCATION = "USB1";
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002696const int32_t InputMapperTest::DEVICE_ID = END_RESERVED_ID + 1000;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002697const int32_t InputMapperTest::DEVICE_GENERATION = 2;
2698const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -07002699const ftl::Flags<InputDeviceClass> InputMapperTest::DEVICE_CLASSES =
2700 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002701const int32_t InputMapperTest::EVENTHUB_ID = 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002702
2703// --- SwitchInputMapperTest ---
2704
2705class SwitchInputMapperTest : public InputMapperTest {
2706protected:
2707};
2708
2709TEST_F(SwitchInputMapperTest, GetSources) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002710 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002711
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002712 ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002713}
2714
2715TEST_F(SwitchInputMapperTest, GetSwitchState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002716 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002717
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002718 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002719 ASSERT_EQ(1, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002720
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08002721 mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002722 ASSERT_EQ(0, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002723}
2724
2725TEST_F(SwitchInputMapperTest, Process) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002726 SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002727 std::list<NotifyArgs> out;
2728 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_LID, 1);
2729 ASSERT_TRUE(out.empty());
2730 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
2731 ASSERT_TRUE(out.empty());
2732 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
2733 ASSERT_TRUE(out.empty());
2734 out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002735
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002736 ASSERT_EQ(1u, out.size());
2737 const NotifySwitchArgs& args = std::get<NotifySwitchArgs>(*out.begin());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002738 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
Dan Albert1bd2fc02016-02-02 15:11:57 -08002739 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
2740 ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741 args.switchMask);
2742 ASSERT_EQ(uint32_t(0), args.policyFlags);
2743}
2744
Chris Ye87143712020-11-10 05:05:58 +00002745// --- VibratorInputMapperTest ---
2746class VibratorInputMapperTest : public InputMapperTest {
2747protected:
2748 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::VIBRATOR); }
2749};
2750
2751TEST_F(VibratorInputMapperTest, GetSources) {
2752 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
2753
2754 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mapper.getSources());
2755}
2756
2757TEST_F(VibratorInputMapperTest, GetVibratorIds) {
2758 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
2759
2760 ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
2761}
2762
2763TEST_F(VibratorInputMapperTest, Vibrate) {
2764 constexpr uint8_t DEFAULT_AMPLITUDE = 192;
Chris Yefb552902021-02-03 17:18:37 -08002765 constexpr int32_t VIBRATION_TOKEN = 100;
Chris Ye87143712020-11-10 05:05:58 +00002766 VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
2767
2768 VibrationElement pattern(2);
2769 VibrationSequence sequence(2);
2770 pattern.duration = std::chrono::milliseconds(200);
2771 pattern.channels = {{0 /* vibratorId */, DEFAULT_AMPLITUDE / 2},
2772 {1 /* vibratorId */, DEFAULT_AMPLITUDE}};
2773 sequence.addElement(pattern);
2774 pattern.duration = std::chrono::milliseconds(500);
2775 pattern.channels = {{0 /* vibratorId */, DEFAULT_AMPLITUDE / 4},
2776 {1 /* vibratorId */, DEFAULT_AMPLITUDE}};
2777 sequence.addElement(pattern);
2778
2779 std::vector<int64_t> timings = {0, 1};
2780 std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
2781
2782 ASSERT_FALSE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08002783 // Start vibrating
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002784 std::list<NotifyArgs> out = mapper.vibrate(sequence, -1 /* repeat */, VIBRATION_TOKEN);
Chris Ye87143712020-11-10 05:05:58 +00002785 ASSERT_TRUE(mapper.isVibrating());
Chris Yefb552902021-02-03 17:18:37 -08002786 // Verify vibrator state listener was notified.
2787 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002788 ASSERT_EQ(1u, out.size());
2789 const NotifyVibratorStateArgs& vibrateArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
2790 ASSERT_EQ(DEVICE_ID, vibrateArgs.deviceId);
2791 ASSERT_TRUE(vibrateArgs.isOn);
Chris Yefb552902021-02-03 17:18:37 -08002792 // Stop vibrating
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002793 out = mapper.cancelVibrate(VIBRATION_TOKEN);
Chris Yefb552902021-02-03 17:18:37 -08002794 ASSERT_FALSE(mapper.isVibrating());
2795 // Verify vibrator state listener was notified.
2796 mReader->loopOnce();
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07002797 ASSERT_EQ(1u, out.size());
2798 const NotifyVibratorStateArgs& cancelArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
2799 ASSERT_EQ(DEVICE_ID, cancelArgs.deviceId);
2800 ASSERT_FALSE(cancelArgs.isOn);
Chris Ye87143712020-11-10 05:05:58 +00002801}
Michael Wrightd02c5b62014-02-10 15:10:22 -08002802
Chris Yef59a2f42020-10-16 12:55:26 -07002803// --- SensorInputMapperTest ---
2804
2805class SensorInputMapperTest : public InputMapperTest {
2806protected:
2807 static const int32_t ACCEL_RAW_MIN;
2808 static const int32_t ACCEL_RAW_MAX;
2809 static const int32_t ACCEL_RAW_FUZZ;
2810 static const int32_t ACCEL_RAW_FLAT;
2811 static const int32_t ACCEL_RAW_RESOLUTION;
2812
2813 static const int32_t GYRO_RAW_MIN;
2814 static const int32_t GYRO_RAW_MAX;
2815 static const int32_t GYRO_RAW_FUZZ;
2816 static const int32_t GYRO_RAW_FLAT;
2817 static const int32_t GYRO_RAW_RESOLUTION;
2818
2819 static const float GRAVITY_MS2_UNIT;
2820 static const float DEGREE_RADIAN_UNIT;
2821
2822 void prepareAccelAxes();
2823 void prepareGyroAxes();
2824 void setAccelProperties();
2825 void setGyroProperties();
2826 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::SENSOR); }
2827};
2828
2829const int32_t SensorInputMapperTest::ACCEL_RAW_MIN = -32768;
2830const int32_t SensorInputMapperTest::ACCEL_RAW_MAX = 32768;
2831const int32_t SensorInputMapperTest::ACCEL_RAW_FUZZ = 16;
2832const int32_t SensorInputMapperTest::ACCEL_RAW_FLAT = 0;
2833const int32_t SensorInputMapperTest::ACCEL_RAW_RESOLUTION = 8192;
2834
2835const int32_t SensorInputMapperTest::GYRO_RAW_MIN = -2097152;
2836const int32_t SensorInputMapperTest::GYRO_RAW_MAX = 2097152;
2837const int32_t SensorInputMapperTest::GYRO_RAW_FUZZ = 16;
2838const int32_t SensorInputMapperTest::GYRO_RAW_FLAT = 0;
2839const int32_t SensorInputMapperTest::GYRO_RAW_RESOLUTION = 1024;
2840
2841const float SensorInputMapperTest::GRAVITY_MS2_UNIT = 9.80665f;
2842const float SensorInputMapperTest::DEGREE_RADIAN_UNIT = 0.0174533f;
2843
2844void SensorInputMapperTest::prepareAccelAxes() {
2845 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2846 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2847 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2848 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2849 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Z, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
2850 ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
2851}
2852
2853void SensorInputMapperTest::prepareGyroAxes() {
2854 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RX, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
2855 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
2856 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RY, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
2857 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
2858 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RZ, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
2859 GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
2860}
2861
2862void SensorInputMapperTest::setAccelProperties() {
2863 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 0, InputDeviceSensorType::ACCELEROMETER,
2864 /* sensorDataIndex */ 0);
2865 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 1, InputDeviceSensorType::ACCELEROMETER,
2866 /* sensorDataIndex */ 1);
2867 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 2, InputDeviceSensorType::ACCELEROMETER,
2868 /* sensorDataIndex */ 2);
2869 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
2870 addConfigurationProperty("sensor.accelerometer.reportingMode", "0");
2871 addConfigurationProperty("sensor.accelerometer.maxDelay", "100000");
2872 addConfigurationProperty("sensor.accelerometer.minDelay", "5000");
2873 addConfigurationProperty("sensor.accelerometer.power", "1.5");
2874}
2875
2876void SensorInputMapperTest::setGyroProperties() {
2877 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 3, InputDeviceSensorType::GYROSCOPE,
2878 /* sensorDataIndex */ 0);
2879 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 4, InputDeviceSensorType::GYROSCOPE,
2880 /* sensorDataIndex */ 1);
2881 mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 5, InputDeviceSensorType::GYROSCOPE,
2882 /* sensorDataIndex */ 2);
2883 mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
2884 addConfigurationProperty("sensor.gyroscope.reportingMode", "0");
2885 addConfigurationProperty("sensor.gyroscope.maxDelay", "100000");
2886 addConfigurationProperty("sensor.gyroscope.minDelay", "5000");
2887 addConfigurationProperty("sensor.gyroscope.power", "0.8");
2888}
2889
2890TEST_F(SensorInputMapperTest, GetSources) {
2891 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
2892
2893 ASSERT_EQ(static_cast<uint32_t>(AINPUT_SOURCE_SENSOR), mapper.getSources());
2894}
2895
2896TEST_F(SensorInputMapperTest, ProcessAccelerometerSensor) {
2897 setAccelProperties();
2898 prepareAccelAxes();
2899 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
2900
2901 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::ACCELEROMETER,
2902 std::chrono::microseconds(10000),
2903 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08002904 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002905 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, 20000);
2906 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, -20000);
2907 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Z, 40000);
2908 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
2909 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07002910
2911 NotifySensorArgs args;
2912 std::vector<float> values = {20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
2913 -20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
2914 40000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT};
2915
2916 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
2917 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
2918 ASSERT_EQ(args.deviceId, DEVICE_ID);
2919 ASSERT_EQ(args.sensorType, InputDeviceSensorType::ACCELEROMETER);
2920 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
2921 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
2922 ASSERT_EQ(args.values, values);
2923 mapper.flushSensor(InputDeviceSensorType::ACCELEROMETER);
2924}
2925
2926TEST_F(SensorInputMapperTest, ProcessGyroscopeSensor) {
2927 setGyroProperties();
2928 prepareGyroAxes();
2929 SensorInputMapper& mapper = addMapperAndConfigure<SensorInputMapper>();
2930
2931 ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::GYROSCOPE,
2932 std::chrono::microseconds(10000),
2933 std::chrono::microseconds(0)));
Chris Yee14523a2020-12-19 13:46:00 -08002934 ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002935 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RX, 20000);
2936 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RY, -20000);
2937 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RZ, 40000);
2938 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
2939 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Chris Yef59a2f42020-10-16 12:55:26 -07002940
2941 NotifySensorArgs args;
2942 std::vector<float> values = {20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
2943 -20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
2944 40000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT};
2945
2946 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
2947 ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
2948 ASSERT_EQ(args.deviceId, DEVICE_ID);
2949 ASSERT_EQ(args.sensorType, InputDeviceSensorType::GYROSCOPE);
2950 ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
2951 ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
2952 ASSERT_EQ(args.values, values);
2953 mapper.flushSensor(InputDeviceSensorType::GYROSCOPE);
2954}
2955
Michael Wrightd02c5b62014-02-10 15:10:22 -08002956// --- KeyboardInputMapperTest ---
2957
2958class KeyboardInputMapperTest : public InputMapperTest {
2959protected:
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002960 const std::string UNIQUE_ID = "local:0";
2961
2962 void prepareDisplay(int32_t orientation);
2963
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002964 void testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalScanCode,
Arthur Hung2c9a3342019-07-23 14:18:59 +08002965 int32_t originalKeyCode, int32_t rotatedKeyCode,
2966 int32_t displayId = ADISPLAY_ID_NONE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002967};
2968
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002969/* Similar to setDisplayInfoAndReconfigure, but pre-populates all parameters except for the
2970 * orientation.
2971 */
2972void KeyboardInputMapperTest::prepareDisplay(int32_t orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01002973 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
2974 NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07002975}
2976
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002977void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper& mapper,
Arthur Hung2c9a3342019-07-23 14:18:59 +08002978 int32_t originalScanCode, int32_t originalKeyCode,
2979 int32_t rotatedKeyCode, int32_t displayId) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002980 NotifyKeyArgs args;
2981
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002982 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002983 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2984 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
2985 ASSERT_EQ(originalScanCode, args.scanCode);
2986 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002987 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002988
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00002989 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002990 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2991 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
2992 ASSERT_EQ(originalScanCode, args.scanCode);
2993 ASSERT_EQ(rotatedKeyCode, args.keyCode);
Arthur Hung2c9a3342019-07-23 14:18:59 +08002994 ASSERT_EQ(displayId, args.displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002995}
2996
Michael Wrightd02c5b62014-02-10 15:10:22 -08002997TEST_F(KeyboardInputMapperTest, GetSources) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08002998 KeyboardInputMapper& mapper =
2999 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3000 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003001
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003002 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003003}
3004
3005TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
3006 const int32_t USAGE_A = 0x070004;
3007 const int32_t USAGE_UNKNOWN = 0x07ffff;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003008 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3009 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
Chris Yea52ade12020-08-27 16:49:20 -07003010 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, POLICY_FLAG_WAKE);
3011 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, POLICY_FLAG_WAKE);
3012 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003013
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003014 KeyboardInputMapper& mapper =
3015 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3016 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003017 // Initial metastate is AMETA_NONE.
3018 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003019
3020 // Key down by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003021 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003022 NotifyKeyArgs args;
3023 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3024 ASSERT_EQ(DEVICE_ID, args.deviceId);
3025 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3026 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3027 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3028 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3029 ASSERT_EQ(KEY_HOME, args.scanCode);
3030 ASSERT_EQ(AMETA_NONE, args.metaState);
3031 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3032 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3033 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3034
3035 // Key up by scan code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003036 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003037 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3038 ASSERT_EQ(DEVICE_ID, args.deviceId);
3039 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3040 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3041 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3042 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3043 ASSERT_EQ(KEY_HOME, args.scanCode);
3044 ASSERT_EQ(AMETA_NONE, args.metaState);
3045 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3046 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3047 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3048
3049 // Key down by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003050 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
3051 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, 0, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003052 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3053 ASSERT_EQ(DEVICE_ID, args.deviceId);
3054 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3055 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3056 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3057 ASSERT_EQ(AKEYCODE_A, args.keyCode);
3058 ASSERT_EQ(0, args.scanCode);
3059 ASSERT_EQ(AMETA_NONE, args.metaState);
3060 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3061 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3062 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3063
3064 // Key up by usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003065 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_A);
3066 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003067 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3068 ASSERT_EQ(DEVICE_ID, args.deviceId);
3069 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3070 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3071 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3072 ASSERT_EQ(AKEYCODE_A, args.keyCode);
3073 ASSERT_EQ(0, args.scanCode);
3074 ASSERT_EQ(AMETA_NONE, args.metaState);
3075 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3076 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3077 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3078
3079 // Key down with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003080 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
3081 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003082 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3083 ASSERT_EQ(DEVICE_ID, args.deviceId);
3084 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3085 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3086 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3087 ASSERT_EQ(0, args.keyCode);
3088 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
3089 ASSERT_EQ(AMETA_NONE, args.metaState);
3090 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3091 ASSERT_EQ(0U, args.policyFlags);
3092 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3093
3094 // Key up with unknown scan code or usage code.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003095 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
3096 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003097 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3098 ASSERT_EQ(DEVICE_ID, args.deviceId);
3099 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3100 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
3101 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3102 ASSERT_EQ(0, args.keyCode);
3103 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
3104 ASSERT_EQ(AMETA_NONE, args.metaState);
3105 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3106 ASSERT_EQ(0U, args.policyFlags);
3107 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3108}
3109
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003110/**
3111 * Ensure that the readTime is set to the time when the EV_KEY is received.
3112 */
3113TEST_F(KeyboardInputMapperTest, Process_SendsReadTime) {
3114 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3115
3116 KeyboardInputMapper& mapper =
3117 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3118 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3119 NotifyKeyArgs args;
3120
3121 // Key down
3122 process(mapper, ARBITRARY_TIME, 12 /*readTime*/, EV_KEY, KEY_HOME, 1);
3123 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3124 ASSERT_EQ(12, args.readTime);
3125
3126 // Key up
3127 process(mapper, ARBITRARY_TIME, 15 /*readTime*/, EV_KEY, KEY_HOME, 1);
3128 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3129 ASSERT_EQ(15, args.readTime);
3130}
3131
Michael Wrightd02c5b62014-02-10 15:10:22 -08003132TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003133 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
3134 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07003135 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 0);
3136 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 0);
3137 mFakeEventHub->addKey(EVENTHUB_ID, 0, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003138
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003139 KeyboardInputMapper& mapper =
3140 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3141 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003142
Arthur Hung95f68612022-04-07 14:08:22 +08003143 // Initial metastate is AMETA_NONE.
3144 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003145
3146 // Metakey down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003147 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003148 NotifyKeyArgs args;
3149 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3150 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003151 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08003152 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003153
3154 // Key down.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003155 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_A, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003156 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3157 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003158 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003159
3160 // Key up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003161 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, KEY_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3163 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003164 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003165
3166 // Metakey up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003167 process(mapper, ARBITRARY_TIME + 3, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003168 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3169 ASSERT_EQ(AMETA_NONE, args.metaState);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003170 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungdcef2dc2020-08-11 14:47:50 +08003171 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertUpdateGlobalMetaStateWasCalled());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003172}
3173
3174TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003175 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3176 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3177 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3178 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003179
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003180 KeyboardInputMapper& mapper =
3181 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3182 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003183
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003184 prepareDisplay(DISPLAY_ORIENTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003185 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3186 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
3187 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3188 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
3189 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3190 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
3191 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
3192 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
3193}
3194
3195TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003196 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3197 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3198 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3199 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003200
Michael Wrightd02c5b62014-02-10 15:10:22 -08003201 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003202 KeyboardInputMapper& mapper =
3203 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3204 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003205
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003206 prepareDisplay(DISPLAY_ORIENTATION_0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003207 ASSERT_NO_FATAL_FAILURE(
3208 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
3209 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3210 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3211 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3212 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3213 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3214 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003215
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003216 clearViewports();
3217 prepareDisplay(DISPLAY_ORIENTATION_90);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003218 ASSERT_NO_FATAL_FAILURE(
3219 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3220 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3221 AKEYCODE_DPAD_UP, DISPLAY_ID));
3222 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3223 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3224 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3225 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003226
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003227 clearViewports();
3228 prepareDisplay(DISPLAY_ORIENTATION_180);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003229 ASSERT_NO_FATAL_FAILURE(
3230 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3231 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3232 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3233 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3234 AKEYCODE_DPAD_UP, DISPLAY_ID));
3235 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3236 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003237
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003238 clearViewports();
3239 prepareDisplay(DISPLAY_ORIENTATION_270);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003240 ASSERT_NO_FATAL_FAILURE(
3241 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3242 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3243 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3244 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3245 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3246 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3247 AKEYCODE_DPAD_UP, DISPLAY_ID));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003248
3249 // Special case: if orientation changes while key is down, we still emit the same keycode
3250 // in the key up as we did in the key down.
3251 NotifyKeyArgs args;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003252 clearViewports();
3253 prepareDisplay(DISPLAY_ORIENTATION_270);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003254 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003255 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3256 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3257 ASSERT_EQ(KEY_UP, args.scanCode);
3258 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3259
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003260 clearViewports();
3261 prepareDisplay(DISPLAY_ORIENTATION_180);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003262 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003263 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3264 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3265 ASSERT_EQ(KEY_UP, args.scanCode);
3266 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
3267}
3268
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003269TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_NotOrientationAware) {
3270 // If the keyboard is not orientation aware,
3271 // key events should not be associated with a specific display id
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003272 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003273
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003274 KeyboardInputMapper& mapper =
3275 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3276 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003277 NotifyKeyArgs args;
3278
3279 // Display id should be ADISPLAY_ID_NONE without any display configuration.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003280 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003281 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003282 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003283 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3284 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3285
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003286 prepareDisplay(DISPLAY_ORIENTATION_0);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003287 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003288 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003289 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003290 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3291 ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
3292}
3293
3294TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_OrientationAware) {
3295 // If the keyboard is orientation aware,
3296 // key events should be associated with the internal viewport
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003297 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003298
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003299 addConfigurationProperty("keyboard.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003300 KeyboardInputMapper& mapper =
3301 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3302 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003303 NotifyKeyArgs args;
3304
3305 // Display id should be ADISPLAY_ID_NONE without any display configuration.
3306 // ^--- already checked by the previous test
3307
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003308 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003309 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003310 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003311 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003312 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003313 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3314 ASSERT_EQ(DISPLAY_ID, args.displayId);
3315
3316 constexpr int32_t newDisplayId = 2;
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07003317 clearViewports();
3318 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003319 UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003320 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 1);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003321 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003322 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UP, 0);
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01003323 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3324 ASSERT_EQ(newDisplayId, args.displayId);
3325}
3326
Michael Wrightd02c5b62014-02-10 15:10:22 -08003327TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003328 KeyboardInputMapper& mapper =
3329 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3330 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003331
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003332 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003333 ASSERT_EQ(1, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003334
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003335 mFakeEventHub->setKeyCodeState(EVENTHUB_ID, AKEYCODE_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003336 ASSERT_EQ(0, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003337}
3338
Philip Junker4af3b3d2021-12-14 10:36:55 +01003339TEST_F(KeyboardInputMapperTest, GetKeyCodeForKeyLocation) {
3340 KeyboardInputMapper& mapper =
3341 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3342 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3343
3344 mFakeEventHub->addKeyCodeMapping(EVENTHUB_ID, AKEYCODE_Y, AKEYCODE_Z);
3345 ASSERT_EQ(AKEYCODE_Z, mapper.getKeyCodeForKeyLocation(AKEYCODE_Y))
3346 << "If a mapping is available, the result is equal to the mapping";
3347
3348 ASSERT_EQ(AKEYCODE_A, mapper.getKeyCodeForKeyLocation(AKEYCODE_A))
3349 << "If no mapping is available, the result is the key location";
3350}
3351
Michael Wrightd02c5b62014-02-10 15:10:22 -08003352TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003353 KeyboardInputMapper& mapper =
3354 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3355 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003356
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003357 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 1);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003358 ASSERT_EQ(1, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003359
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003360 mFakeEventHub->setScanCodeState(EVENTHUB_ID, KEY_A, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003361 ASSERT_EQ(0, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003362}
3363
3364TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003365 KeyboardInputMapper& mapper =
3366 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3367 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003368
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003369 mFakeEventHub->addKey(EVENTHUB_ID, KEY_A, 0, AKEYCODE_A, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003370
Michael Wrightd02c5b62014-02-10 15:10:22 -08003371 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07003372 ASSERT_TRUE(mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_A, AKEYCODE_B}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003373 ASSERT_TRUE(flags[0]);
3374 ASSERT_FALSE(flags[1]);
3375}
3376
3377TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003378 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3379 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3380 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3381 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3382 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3383 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003385 KeyboardInputMapper& mapper =
3386 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3387 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003388 // Initial metastate is AMETA_NONE.
3389 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003390
3391 // Initialization should have turned all of the lights off.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003392 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3393 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3394 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003395
3396 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003397 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3398 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003399 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3400 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3401 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003402 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003403
3404 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003405 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3406 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003407 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3408 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3409 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003410 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003411
3412 // Toggle caps lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003413 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3414 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003415 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3416 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3417 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003418 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003419
3420 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003421 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3422 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003423 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3424 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3425 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003426 ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003427
3428 // Toggle num lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003429 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3430 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003431 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3432 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3433 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003434 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003435
3436 // Toggle scroll lock off.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003437 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3438 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003439 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3440 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3441 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003442 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003443}
3444
Chris Yea52ade12020-08-27 16:49:20 -07003445TEST_F(KeyboardInputMapperTest, NoMetaStateWhenMetaKeysNotPresent) {
3446 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_BUTTON_A, 0);
3447 mFakeEventHub->addKey(EVENTHUB_ID, BTN_B, 0, AKEYCODE_BUTTON_B, 0);
3448 mFakeEventHub->addKey(EVENTHUB_ID, BTN_X, 0, AKEYCODE_BUTTON_X, 0);
3449 mFakeEventHub->addKey(EVENTHUB_ID, BTN_Y, 0, AKEYCODE_BUTTON_Y, 0);
3450
3451 KeyboardInputMapper& mapper =
3452 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3453 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
3454
Chris Yea52ade12020-08-27 16:49:20 -07003455 // Meta state should be AMETA_NONE after reset
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003456 std::list<NotifyArgs> unused = mapper.reset(ARBITRARY_TIME);
Chris Yea52ade12020-08-27 16:49:20 -07003457 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3458 // Meta state should be AMETA_NONE with update, as device doesn't have the keys.
3459 mapper.updateMetaState(AKEYCODE_NUM_LOCK);
3460 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3461
3462 NotifyKeyArgs args;
3463 // Press button "A"
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003464 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_A, 1);
Chris Yea52ade12020-08-27 16:49:20 -07003465 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3466 ASSERT_EQ(AMETA_NONE, args.metaState);
3467 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3468 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3469 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
3470
3471 // Button up.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003472 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_A, 0);
Chris Yea52ade12020-08-27 16:49:20 -07003473 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3474 ASSERT_EQ(AMETA_NONE, args.metaState);
3475 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
3476 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3477 ASSERT_EQ(AKEYCODE_BUTTON_A, args.keyCode);
3478}
3479
Arthur Hung2c9a3342019-07-23 14:18:59 +08003480TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) {
3481 // keyboard 1.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003482 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3483 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3484 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3485 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003486
3487 // keyboard 2.
3488 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08003489 const std::string DEVICE_NAME2 = "KEYBOARD2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08003490 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003491 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08003492 std::shared_ptr<InputDevice> device2 =
3493 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003494 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08003495
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003496 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
3497 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
3498 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3499 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003500
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003501 KeyboardInputMapper& mapper =
3502 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3503 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003504
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003505 KeyboardInputMapper& mapper2 =
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003506 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003507 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003508 std::list<NotifyArgs> unused =
3509 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3510 0 /*changes*/);
3511 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003512
3513 // Prepared displays and associated info.
3514 constexpr uint8_t hdmi1 = 0;
3515 constexpr uint8_t hdmi2 = 1;
3516 const std::string SECONDARY_UNIQUE_ID = "local:1";
3517
3518 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
3519 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
3520
3521 // No associated display viewport found, should disable the device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003522 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3523 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003524 ASSERT_FALSE(device2->isEnabled());
3525
3526 // Prepare second display.
3527 constexpr int32_t newDisplayId = 2;
3528 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003529 UNIQUE_ID, hdmi1, ViewportType::INTERNAL);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003530 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
Michael Wrightfe3de7d2020-07-02 19:05:30 +01003531 SECONDARY_UNIQUE_ID, hdmi2, ViewportType::EXTERNAL);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003532 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003533 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3534 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Arthur Hung2c9a3342019-07-23 14:18:59 +08003535
3536 // Device should be enabled after the associated display is found.
3537 ASSERT_TRUE(mDevice->isEnabled());
3538 ASSERT_TRUE(device2->isEnabled());
3539
3540 // Test pad key events
3541 ASSERT_NO_FATAL_FAILURE(
3542 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
3543 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3544 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
3545 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3546 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
3547 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3548 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
3549
3550 ASSERT_NO_FATAL_FAILURE(
3551 testDPadKeyRotation(mapper2, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, newDisplayId));
3552 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
3553 AKEYCODE_DPAD_RIGHT, newDisplayId));
3554 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_DOWN, AKEYCODE_DPAD_DOWN,
3555 AKEYCODE_DPAD_DOWN, newDisplayId));
3556 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_LEFT, AKEYCODE_DPAD_LEFT,
3557 AKEYCODE_DPAD_LEFT, newDisplayId));
3558}
Michael Wrightd02c5b62014-02-10 15:10:22 -08003559
arthurhungc903df12020-08-11 15:08:42 +08003560TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleAfterReattach) {
3561 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3562 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3563 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3564 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3565 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3566 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3567
3568 KeyboardInputMapper& mapper =
3569 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3570 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003571 // Initial metastate is AMETA_NONE.
3572 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08003573
3574 // Initialization should have turned all of the lights off.
3575 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3576 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3577 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3578
3579 // Toggle caps lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003580 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3581 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003582 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3583 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
3584
3585 // Toggle num lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003586 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3587 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003588 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3589 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
3590
3591 // Toggle scroll lock on.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003592 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3593 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
arthurhungc903df12020-08-11 15:08:42 +08003594 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3595 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
3596
3597 mFakeEventHub->removeDevice(EVENTHUB_ID);
3598 mReader->loopOnce();
3599
3600 // keyboard 2 should default toggle keys.
3601 const std::string USB2 = "USB2";
3602 const std::string DEVICE_NAME2 = "KEYBOARD2";
3603 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
3604 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
3605 std::shared_ptr<InputDevice> device2 =
3606 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07003607 ftl::Flags<InputDeviceClass>(0));
arthurhungc903df12020-08-11 15:08:42 +08003608 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3609 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
3610 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3611 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3612 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3613 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3614
arthurhung6fe95782020-10-05 22:41:16 +08003615 KeyboardInputMapper& mapper2 =
3616 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
3617 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003618 std::list<NotifyArgs> unused =
3619 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3620 0 /*changes*/);
3621 unused += device2->reset(ARBITRARY_TIME);
arthurhungc903df12020-08-11 15:08:42 +08003622
3623 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_CAPSL));
3624 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_NUML));
3625 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_SCROLLL));
arthurhung6fe95782020-10-05 22:41:16 +08003626 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON,
3627 mapper2.getMetaState());
arthurhungc903df12020-08-11 15:08:42 +08003628}
3629
Arthur Hungcb40a002021-08-03 14:31:01 +00003630TEST_F(KeyboardInputMapperTest, Process_toggleCapsLockState) {
3631 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3632 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3633 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3634
3635 // Suppose we have two mappers. (DPAD + KEYBOARD)
3636 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_DPAD,
3637 AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
3638 KeyboardInputMapper& mapper =
3639 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3640 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Arthur Hung95f68612022-04-07 14:08:22 +08003641 // Initial metastate is AMETA_NONE.
3642 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
Arthur Hungcb40a002021-08-03 14:31:01 +00003643
3644 mReader->toggleCapsLockState(DEVICE_ID);
3645 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
3646}
3647
Arthur Hungfb3cc112022-04-13 07:39:50 +00003648TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) {
3649 // keyboard 1.
3650 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3651 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
3652 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3653 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3654 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3655 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3656
3657 KeyboardInputMapper& mapper1 =
3658 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3659 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3660
3661 // keyboard 2.
3662 const std::string USB2 = "USB2";
3663 const std::string DEVICE_NAME2 = "KEYBOARD2";
3664 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
3665 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
3666 std::shared_ptr<InputDevice> device2 =
3667 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
3668 ftl::Flags<InputDeviceClass>(0));
3669 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
3670 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
3671 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
3672 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
3673 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
3674 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
3675
3676 KeyboardInputMapper& mapper2 =
3677 device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
3678 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07003679 std::list<NotifyArgs> unused =
3680 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3681 0 /*changes*/);
3682 unused += device2->reset(ARBITRARY_TIME);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003683
Arthur Hung95f68612022-04-07 14:08:22 +08003684 // Initial metastate is AMETA_NONE.
3685 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3686 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3687
3688 // Toggle num lock on and off.
3689 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3690 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
Arthur Hungfb3cc112022-04-13 07:39:50 +00003691 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3692 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState());
3693 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState());
3694
3695 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
3696 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
3697 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
3698 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3699 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3700
3701 // Toggle caps lock on and off.
3702 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3703 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
3704 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3705 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper1.getMetaState());
3706 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper2.getMetaState());
3707
3708 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
3709 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
3710 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
3711 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3712 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3713
3714 // Toggle scroll lock on and off.
3715 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3716 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
3717 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3718 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper1.getMetaState());
3719 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper2.getMetaState());
3720
3721 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
3722 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
3723 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
3724 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
3725 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
3726}
3727
Arthur Hung2141d542022-08-23 07:45:21 +00003728TEST_F(KeyboardInputMapperTest, Process_DisabledDevice) {
3729 const int32_t USAGE_A = 0x070004;
3730 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3731 mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
3732
3733 KeyboardInputMapper& mapper =
3734 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3735 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
3736 // Key down by scan code.
3737 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
3738 NotifyKeyArgs args;
3739 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3740 ASSERT_EQ(DEVICE_ID, args.deviceId);
3741 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3742 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3743 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3744 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3745 ASSERT_EQ(KEY_HOME, args.scanCode);
3746 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
3747
3748 // Disable device, it should synthesize cancellation events for down events.
3749 mFakePolicy->addDisabledDevice(DEVICE_ID);
3750 configureDevice(InputReaderConfiguration::CHANGE_ENABLED_STATE);
3751
3752 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3753 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3754 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3755 ASSERT_EQ(KEY_HOME, args.scanCode);
3756 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, args.flags);
3757}
3758
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003759// --- KeyboardInputMapperTest_ExternalDevice ---
3760
3761class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest {
3762protected:
Chris Yea52ade12020-08-27 16:49:20 -07003763 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003764};
3765
3766TEST_F(KeyboardInputMapperTest_ExternalDevice, WakeBehavior) {
Powei Fengd041c5d2019-05-03 17:11:33 -07003767 // For external devices, non-media keys will trigger wake on key down. Media keys need to be
3768 // marked as WAKE in the keylayout file to trigger wake.
Powei Fengd041c5d2019-05-03 17:11:33 -07003769
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003770 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, 0);
3771 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, 0);
3772 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAYPAUSE, 0, AKEYCODE_MEDIA_PLAY_PAUSE,
3773 POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07003774
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003775 KeyboardInputMapper& mapper =
3776 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3777 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07003778
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003779 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003780 NotifyKeyArgs args;
3781 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3782 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3783
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003784 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
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, READ_TIME, EV_KEY, KEY_PLAY, 1);
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 + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003793 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3794 ASSERT_EQ(uint32_t(0), args.policyFlags);
3795
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003796 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003797 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3798 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3799
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003800 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAYPAUSE, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003801 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3802 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3803}
3804
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003805TEST_F(KeyboardInputMapperTest_ExternalDevice, DoNotWakeByDefaultBehavior) {
Powei Fengd041c5d2019-05-03 17:11:33 -07003806 // Tv Remote key's wake behavior is prescribed by the keylayout file.
Powei Fengd041c5d2019-05-03 17:11:33 -07003807
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08003808 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3809 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
3810 mFakeEventHub->addKey(EVENTHUB_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE);
Powei Fengd041c5d2019-05-03 17:11:33 -07003811
Powei Fengd041c5d2019-05-03 17:11:33 -07003812 addConfigurationProperty("keyboard.doNotWakeByDefault", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003813 KeyboardInputMapper& mapper =
3814 addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
3815 AINPUT_KEYBOARD_TYPE_ALPHABETIC);
Powei Fengd041c5d2019-05-03 17:11:33 -07003816
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003817 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003818 NotifyKeyArgs args;
3819 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 + 1, READ_TIME, EV_KEY, KEY_HOME, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003823 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3824 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3825
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003826 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_DOWN, 1);
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 + 1, READ_TIME, EV_KEY, KEY_DOWN, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003831 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3832 ASSERT_EQ(uint32_t(0), args.policyFlags);
3833
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003834 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_PLAY, 1);
Powei Fengd041c5d2019-05-03 17:11:33 -07003835 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3836 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3837
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003838 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, KEY_PLAY, 0);
Powei Fengd041c5d2019-05-03 17:11:33 -07003839 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3840 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
3841}
3842
Michael Wrightd02c5b62014-02-10 15:10:22 -08003843// --- CursorInputMapperTest ---
3844
3845class CursorInputMapperTest : public InputMapperTest {
3846protected:
3847 static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
3848
Michael Wright17db18e2020-06-26 20:51:44 +01003849 std::shared_ptr<FakePointerController> mFakePointerController;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003850
Chris Yea52ade12020-08-27 16:49:20 -07003851 void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 InputMapperTest::SetUp();
3853
Michael Wright17db18e2020-06-26 20:51:44 +01003854 mFakePointerController = std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00003855 mFakePolicy->setPointerController(mFakePointerController);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003856 }
3857
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003858 void testMotionRotation(CursorInputMapper& mapper, int32_t originalX, int32_t originalY,
3859 int32_t rotatedX, int32_t rotatedY);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003860
3861 void prepareDisplay(int32_t orientation) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00003862 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation,
3863 DISPLAY_UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
3864 }
3865
3866 void prepareSecondaryDisplay() {
3867 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
3868 DISPLAY_ORIENTATION_0, SECONDARY_DISPLAY_UNIQUE_ID, NO_PORT,
3869 ViewportType::EXTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07003870 }
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003871
3872 static void assertCursorPointerCoords(const PointerCoords& coords, float x, float y,
3873 float pressure) {
3874 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(coords, x, y, pressure, 0.0f, 0.0f, 0.0f, 0.0f,
3875 0.0f, 0.0f, 0.0f, EPSILON));
3876 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003877};
3878
3879const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
3880
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003881void CursorInputMapperTest::testMotionRotation(CursorInputMapper& mapper, int32_t originalX,
3882 int32_t originalY, int32_t rotatedX,
3883 int32_t rotatedY) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003884 NotifyMotionArgs args;
3885
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003886 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, originalX);
3887 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, originalY);
3888 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003889 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3890 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003891 ASSERT_NO_FATAL_FAILURE(
3892 assertCursorPointerCoords(args.pointerCoords[0],
3893 float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
3894 float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003895}
3896
3897TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003898 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003899 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003900
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003901 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003902}
3903
3904TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003906 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003907
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003908 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003909}
3910
3911TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003912 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003913 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003914
3915 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003916 mapper.populateDeviceInfo(&info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003917
3918 // Initially there may not be a valid motion range.
Yi Kong9b14ac62018-07-17 13:48:38 -07003919 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
3920 ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003921 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3922 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
3923
3924 // When the bounds are set, then there should be a valid motion range.
3925 mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
3926
3927 InputDeviceInfo info2;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003928 mapper.populateDeviceInfo(&info2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003929
3930 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
3931 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
3932 1, 800 - 1, 0.0f, 0.0f));
3933 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
3934 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE,
3935 2, 480 - 1, 0.0f, 0.0f));
3936 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
3937 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE,
3938 0.0f, 1.0f, 0.0f, 0.0f));
3939}
3940
3941TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003942 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003943 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003944
3945 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003946 mapper.populateDeviceInfo(&info);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003947
3948 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3949 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
3950 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
3951 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3952 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL,
3953 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
3954 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
3955 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL,
3956 0.0f, 1.0f, 0.0f, 0.0f));
3957}
3958
3959TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003960 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08003961 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962
arthurhungdcef2dc2020-08-11 14:47:50 +08003963 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003964
3965 NotifyMotionArgs args;
3966
3967 // Button press.
3968 // Mostly testing non x/y behavior here so we don't need to check again elsewhere.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00003969 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
3970 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003971 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3972 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3973 ASSERT_EQ(DEVICE_ID, args.deviceId);
3974 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
3975 ASSERT_EQ(uint32_t(0), args.policyFlags);
3976 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
3977 ASSERT_EQ(0, args.flags);
3978 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
3979 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
3980 ASSERT_EQ(0, args.edgeFlags);
3981 ASSERT_EQ(uint32_t(1), args.pointerCount);
3982 ASSERT_EQ(0, args.pointerProperties[0].id);
3983 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07003984 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003985 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
3986 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
3987 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3988
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08003989 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3990 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3991 ASSERT_EQ(DEVICE_ID, args.deviceId);
3992 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
3993 ASSERT_EQ(uint32_t(0), args.policyFlags);
3994 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
3995 ASSERT_EQ(0, args.flags);
3996 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
3997 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
3998 ASSERT_EQ(0, args.edgeFlags);
3999 ASSERT_EQ(uint32_t(1), args.pointerCount);
4000 ASSERT_EQ(0, args.pointerProperties[0].id);
4001 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004002 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004003 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4004 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4005 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4006
Michael Wrightd02c5b62014-02-10 15:10:22 -08004007 // Button release. Should have same down time.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004008 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4009 process(mapper, ARBITRARY_TIME + 1, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004010 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4011 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
4012 ASSERT_EQ(DEVICE_ID, args.deviceId);
4013 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4014 ASSERT_EQ(uint32_t(0), args.policyFlags);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004015 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
4016 ASSERT_EQ(0, args.flags);
4017 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4018 ASSERT_EQ(0, args.buttonState);
4019 ASSERT_EQ(0, args.edgeFlags);
4020 ASSERT_EQ(uint32_t(1), args.pointerCount);
4021 ASSERT_EQ(0, args.pointerProperties[0].id);
4022 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004023 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004024 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4025 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4026 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4027
4028 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4029 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
4030 ASSERT_EQ(DEVICE_ID, args.deviceId);
4031 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
4032 ASSERT_EQ(uint32_t(0), args.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004033 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
4034 ASSERT_EQ(0, args.flags);
4035 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
4036 ASSERT_EQ(0, args.buttonState);
4037 ASSERT_EQ(0, args.edgeFlags);
4038 ASSERT_EQ(uint32_t(1), args.pointerCount);
4039 ASSERT_EQ(0, args.pointerProperties[0].id);
4040 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004041 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004042 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
4043 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
4044 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
4045}
4046
4047TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004048 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004049 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004050
4051 NotifyMotionArgs args;
4052
4053 // Motion in X but not Y.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004054 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4055 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004056 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4057 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004058 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4059 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f,
4060 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004061
4062 // Motion in Y but not X.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004063 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
4064 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004065 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4066 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004067 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f,
4068 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004069}
4070
4071TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004072 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004073 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004074
4075 NotifyMotionArgs args;
4076
4077 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004078 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4079 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004080 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4081 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004082 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004083
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004084 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4085 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004086 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004087
Michael Wrightd02c5b62014-02-10 15:10:22 -08004088 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004089 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4090 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004091 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004092 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004093 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004094
4095 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004096 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004097 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004098}
4099
4100TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004101 addConfigurationProperty("cursor.mode", "navigation");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004102 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004103
4104 NotifyMotionArgs args;
4105
4106 // Combined X, Y and Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004107 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4108 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, -2);
4109 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4110 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004111 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4112 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004113 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4114 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4115 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004116
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004117 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4118 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004119 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4120 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4121 -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004122
Michael Wrightd02c5b62014-02-10 15:10:22 -08004123 // Move X, Y a bit while pressed.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004124 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 2);
4125 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 1);
4126 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004127 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4128 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004129 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0],
4130 2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
4131 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004132
4133 // Release Button.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004134 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4135 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004136 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004137 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004138 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004139
4140 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004141 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004142 ASSERT_NO_FATAL_FAILURE(assertCursorPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004143}
4144
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004145TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldNotRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004146 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004147 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004148 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
4149 // need to be rotated.
4150 addConfigurationProperty("cursor.orientationAware", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004151 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004152
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004153 prepareDisplay(DISPLAY_ORIENTATION_90);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004154 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 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
4159 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
4160 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
4161 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
4162}
4163
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004164TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldRotateMotions) {
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004165 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166 addConfigurationProperty("cursor.mode", "navigation");
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004167 // Since InputReader works in the un-rotated coordinate space, only devices that are not
4168 // orientation-aware are affected by display rotation.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004169 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004171 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004172 prepareDisplay(DISPLAY_ORIENTATION_0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004173 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 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
4178 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
4179 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
4180 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
4181
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004182 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004183 prepareDisplay(DISPLAY_ORIENTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004184 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));
4188 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 1, 0));
4189 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, -1));
4190 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, -1));
4191 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, -1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004192
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004193 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004194 prepareDisplay(DISPLAY_ORIENTATION_180);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004195 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 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, 1));
4200 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, 1));
4201 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 1, 0));
4202 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, -1));
4203
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004204 clearViewports();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004205 prepareDisplay(DISPLAY_ORIENTATION_270);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07004206 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));
4210 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, -1, 0));
4211 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, 1));
4212 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, 1));
4213 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, 1));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004214}
4215
4216TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004217 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004218 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004219
4220 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4221 mFakePointerController->setPosition(100, 200);
4222 mFakePointerController->setButtonState(0);
4223
4224 NotifyMotionArgs motionArgs;
4225 NotifyKeyArgs keyArgs;
4226
4227 // press BTN_LEFT, release BTN_LEFT
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004228 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 1);
4229 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004230 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4231 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4232 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
4233 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004234 ASSERT_NO_FATAL_FAILURE(
4235 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004236
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004237 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4238 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4239 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
4240 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004241 ASSERT_NO_FATAL_FAILURE(
4242 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004243
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004244 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_LEFT, 0);
4245 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004246 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004247 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004248 ASSERT_EQ(0, motionArgs.buttonState);
4249 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004250 ASSERT_NO_FATAL_FAILURE(
4251 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004252
4253 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004254 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004255 ASSERT_EQ(0, motionArgs.buttonState);
4256 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004257 ASSERT_NO_FATAL_FAILURE(
4258 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004259
4260 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004261 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004262 ASSERT_EQ(0, motionArgs.buttonState);
4263 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004264 ASSERT_NO_FATAL_FAILURE(
4265 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004266
4267 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004268 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 1);
4269 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 1);
4270 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004271 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4272 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4273 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4274 motionArgs.buttonState);
4275 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4276 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004277 ASSERT_NO_FATAL_FAILURE(
4278 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004279
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004280 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4281 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4282 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4283 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4284 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004285 ASSERT_NO_FATAL_FAILURE(
4286 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004287
4288 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4289 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4290 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4291 motionArgs.buttonState);
4292 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4293 mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004294 ASSERT_NO_FATAL_FAILURE(
4295 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004296
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004297 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_RIGHT, 0);
4298 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004299 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004300 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004301 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4302 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004303 ASSERT_NO_FATAL_FAILURE(
4304 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004305
4306 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004307 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004308 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4309 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004310 ASSERT_NO_FATAL_FAILURE(
4311 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 1.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004312
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004313 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4314 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004315 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004316 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4317 ASSERT_EQ(0, motionArgs.buttonState);
4318 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004319 ASSERT_NO_FATAL_FAILURE(
4320 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004321 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MIDDLE, 0);
4322 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004323
4324 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325 ASSERT_EQ(0, motionArgs.buttonState);
4326 ASSERT_EQ(0, mFakePointerController->getButtonState());
4327 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004328 ASSERT_NO_FATAL_FAILURE(
4329 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004330
Michael Wrightd02c5b62014-02-10 15:10:22 -08004331 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4332 ASSERT_EQ(0, motionArgs.buttonState);
4333 ASSERT_EQ(0, mFakePointerController->getButtonState());
4334 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004335 ASSERT_NO_FATAL_FAILURE(
4336 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337
4338 // press BTN_BACK, release BTN_BACK
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004339 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 1);
4340 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004341 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4342 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4343 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004344
Michael Wrightd02c5b62014-02-10 15:10:22 -08004345 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004346 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004347 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4348 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004349 ASSERT_NO_FATAL_FAILURE(
4350 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004351
4352 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4353 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4354 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4355 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004356 ASSERT_NO_FATAL_FAILURE(
4357 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004358
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004359 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_BACK, 0);
4360 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004361 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004362 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004363 ASSERT_EQ(0, motionArgs.buttonState);
4364 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004365 ASSERT_NO_FATAL_FAILURE(
4366 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004367
4368 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004369 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004370 ASSERT_EQ(0, motionArgs.buttonState);
4371 ASSERT_EQ(0, mFakePointerController->getButtonState());
4372
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004373 ASSERT_NO_FATAL_FAILURE(
4374 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004375 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4376 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4377 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4378
4379 // press BTN_SIDE, release BTN_SIDE
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004380 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 1);
4381 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004382 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4383 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4384 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004385
Michael Wrightd02c5b62014-02-10 15:10:22 -08004386 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004387 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004388 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4389 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004390 ASSERT_NO_FATAL_FAILURE(
4391 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004392
4393 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4394 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4395 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4396 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004397 ASSERT_NO_FATAL_FAILURE(
4398 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004399
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004400 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_SIDE, 0);
4401 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004402 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004403 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004404 ASSERT_EQ(0, motionArgs.buttonState);
4405 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004406 ASSERT_NO_FATAL_FAILURE(
4407 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004408
4409 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4410 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4411 ASSERT_EQ(0, motionArgs.buttonState);
4412 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004413 ASSERT_NO_FATAL_FAILURE(
4414 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004415
Michael Wrightd02c5b62014-02-10 15:10:22 -08004416 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4417 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4418 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4419
4420 // press BTN_FORWARD, release BTN_FORWARD
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004421 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 1);
4422 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004423 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4424 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4425 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004426
Michael Wrightd02c5b62014-02-10 15:10:22 -08004427 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004428 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004429 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4430 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004431 ASSERT_NO_FATAL_FAILURE(
4432 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004433
4434 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4435 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4436 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4437 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004438 ASSERT_NO_FATAL_FAILURE(
4439 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004440
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004441 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_FORWARD, 0);
4442 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004443 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004444 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004445 ASSERT_EQ(0, motionArgs.buttonState);
4446 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004447 ASSERT_NO_FATAL_FAILURE(
4448 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004449
4450 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4451 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4452 ASSERT_EQ(0, motionArgs.buttonState);
4453 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004454 ASSERT_NO_FATAL_FAILURE(
4455 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004456
Michael Wrightd02c5b62014-02-10 15:10:22 -08004457 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4458 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4459 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4460
4461 // press BTN_EXTRA, release BTN_EXTRA
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004462 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 1);
4463 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004464 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4465 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4466 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004467
Michael Wrightd02c5b62014-02-10 15:10:22 -08004468 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004469 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004470 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4471 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004472 ASSERT_NO_FATAL_FAILURE(
4473 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004474
4475 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4476 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4477 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4478 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004479 ASSERT_NO_FATAL_FAILURE(
4480 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004481
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004482 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_EXTRA, 0);
4483 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004484 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004485 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004486 ASSERT_EQ(0, motionArgs.buttonState);
4487 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004488 ASSERT_NO_FATAL_FAILURE(
4489 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004490
4491 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4492 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4493 ASSERT_EQ(0, motionArgs.buttonState);
4494 ASSERT_EQ(0, mFakePointerController->getButtonState());
Prabir Pradhanf5334b82021-05-13 14:00:39 -07004495 ASSERT_NO_FATAL_FAILURE(
4496 assertCursorPointerCoords(motionArgs.pointerCoords[0], 100.0f, 200.0f, 0.0f));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08004497
Michael Wrightd02c5b62014-02-10 15:10:22 -08004498 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4499 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4500 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4501}
4502
4503TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004504 addConfigurationProperty("cursor.mode", "pointer");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004505 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004506
4507 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4508 mFakePointerController->setPosition(100, 200);
4509 mFakePointerController->setButtonState(0);
4510
4511 NotifyMotionArgs args;
4512
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004513 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4514 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4515 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004516 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004517 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4518 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4519 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4520 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 +01004521 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004522}
4523
4524TEST_F(CursorInputMapperTest, Process_PointerCapture) {
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004525 addConfigurationProperty("cursor.mode", "pointer");
4526 mFakePolicy->setPointerCapture(true);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004527 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004528
4529 NotifyDeviceResetArgs resetArgs;
4530 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4531 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4532 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4533
4534 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
4535 mFakePointerController->setPosition(100, 200);
4536 mFakePointerController->setButtonState(0);
4537
4538 NotifyMotionArgs args;
4539
4540 // Move.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004541 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4542 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4543 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004544 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4545 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4546 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4547 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4548 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 +01004549 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004550
4551 // Button press.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004552 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_MOUSE, 1);
4553 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004554 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4555 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4556 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
4557 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4558 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4559 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4560 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4561 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
4562 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4563 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4564
4565 // Button release.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004566 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_KEY, BTN_MOUSE, 0);
4567 process(mapper, ARBITRARY_TIME + 2, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004568 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4569 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4570 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
4571 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4572 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4573 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4574 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4575 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
4576 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4577 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
4578
4579 // Another move.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004580 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 30);
4581 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 40);
4582 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004583 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4584 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4585 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4586 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4587 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 +01004588 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004589
4590 // Disable pointer capture and check that the device generation got bumped
4591 // and events are generated the usual way.
arthurhungdcef2dc2020-08-11 14:47:50 +08004592 const uint32_t generation = mReader->getContext()->getGeneration();
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004593 mFakePolicy->setPointerCapture(false);
4594 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
arthurhungdcef2dc2020-08-11 14:47:50 +08004595 ASSERT_TRUE(mReader->getContext()->getGeneration() != generation);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004596
4597 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004598 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4599
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004600 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4601 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4602 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Vladislav Kaznacheev78f97b32016-12-15 18:14:58 -08004603 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4604 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004605 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4606 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4607 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 +01004608 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004609}
4610
Prabir Pradhanf99d6e72022-04-21 15:28:35 +00004611/**
4612 * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
4613 * pointer acceleration or speed processing should not be applied.
4614 */
4615TEST_F(CursorInputMapperTest, PointerCaptureDisablesVelocityProcessing) {
4616 addConfigurationProperty("cursor.mode", "pointer");
4617 const VelocityControlParameters testParams(5.f /*scale*/, 0.f /*low threshold*/,
4618 100.f /*high threshold*/, 10.f /*acceleration*/);
4619 mFakePolicy->setVelocityControlParams(testParams);
4620 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4621
4622 NotifyDeviceResetArgs resetArgs;
4623 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4624 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4625 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4626
4627 NotifyMotionArgs args;
4628
4629 // Move and verify scale is applied.
4630 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4631 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4632 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4633 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4634 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4635 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4636 const float relX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
4637 const float relY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
4638 ASSERT_GT(relX, 10);
4639 ASSERT_GT(relY, 20);
4640
4641 // Enable Pointer Capture
4642 mFakePolicy->setPointerCapture(true);
4643 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
4644 NotifyPointerCaptureChangedArgs captureArgs;
4645 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
4646 ASSERT_TRUE(captureArgs.request.enable);
4647
4648 // Move and verify scale is not applied.
4649 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4650 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4651 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4652 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4653 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4654 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4655 ASSERT_EQ(10, args.pointerCoords[0].getX());
4656 ASSERT_EQ(20, args.pointerCoords[0].getY());
4657}
4658
Prabir Pradhan208360b2022-06-24 18:37:04 +00004659TEST_F(CursorInputMapperTest, PointerCaptureDisablesOrientationChanges) {
4660 addConfigurationProperty("cursor.mode", "pointer");
4661 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4662
4663 NotifyDeviceResetArgs resetArgs;
4664 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
4665 ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
4666 ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
4667
4668 // Ensure the display is rotated.
4669 prepareDisplay(DISPLAY_ORIENTATION_90);
4670
4671 NotifyMotionArgs args;
4672
4673 // Verify that the coordinates are rotated.
4674 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4675 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4676 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4677 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4678 ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
4679 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
4680 ASSERT_EQ(-20, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X));
4681 ASSERT_EQ(10, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
4682
4683 // Enable Pointer Capture.
4684 mFakePolicy->setPointerCapture(true);
4685 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
4686 NotifyPointerCaptureChangedArgs captureArgs;
4687 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
4688 ASSERT_TRUE(captureArgs.request.enable);
4689
4690 // Move and verify rotation is not applied.
4691 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4692 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4693 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4694 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4695 ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
4696 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4697 ASSERT_EQ(10, args.pointerCoords[0].getX());
4698 ASSERT_EQ(20, args.pointerCoords[0].getY());
4699}
4700
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004701TEST_F(CursorInputMapperTest, ConfigureDisplayId_NoAssociatedViewport) {
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08004702 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004703
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004704 // Set up the default display.
4705 prepareDisplay(DISPLAY_ORIENTATION_90);
4706
4707 // Set up the secondary display as the display on which the pointer should be shown.
4708 // The InputDevice is not associated with any display.
4709 prepareSecondaryDisplay();
4710 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Garfield Tan888a6a42020-01-09 11:39:16 -08004711 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
4712
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004713 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004714 mFakePointerController->setPosition(100, 200);
4715 mFakePointerController->setButtonState(0);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004716
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004717 // Ensure input events are generated for the secondary display.
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00004718 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4719 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4720 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004721 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00004722 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4723 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
4724 WithCoords(110.0f, 220.0f))));
Michael Wright17db18e2020-06-26 20:51:44 +01004725 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004726}
4727
4728TEST_F(CursorInputMapperTest, ConfigureDisplayId_WithAssociatedViewport) {
4729 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4730
4731 // Set up the default display.
4732 prepareDisplay(DISPLAY_ORIENTATION_90);
4733
4734 // Set up the secondary display as the display on which the pointer should be shown,
4735 // and associate the InputDevice with the secondary display.
4736 prepareSecondaryDisplay();
4737 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
4738 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
4739 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
4740
4741 mFakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
4742 mFakePointerController->setPosition(100, 200);
4743 mFakePointerController->setButtonState(0);
4744
4745 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4746 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4747 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4748 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan739dca42022-09-09 20:12:01 +00004749 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4750 WithSource(AINPUT_SOURCE_MOUSE), WithDisplayId(SECONDARY_DISPLAY_ID),
4751 WithCoords(110.0f, 220.0f))));
Prabir Pradhanc13ff082022-09-08 22:03:30 +00004752 ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
4753}
4754
4755TEST_F(CursorInputMapperTest, ConfigureDisplayId_IgnoresEventsForMismatchedPointerDisplay) {
4756 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4757
4758 // Set up the default display as the display on which the pointer should be shown.
4759 prepareDisplay(DISPLAY_ORIENTATION_90);
4760 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
4761
4762 // Associate the InputDevice with the secondary display.
4763 prepareSecondaryDisplay();
4764 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, SECONDARY_DISPLAY_UNIQUE_ID);
4765 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
4766
4767 // The mapper should not generate any events because it is associated with a display that is
4768 // different from the pointer display.
4769 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
4770 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
4771 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4772 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08004773}
4774
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00004775// --- BluetoothCursorInputMapperTest ---
4776
4777class BluetoothCursorInputMapperTest : public CursorInputMapperTest {
4778protected:
4779 void SetUp() override {
4780 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
4781
4782 mFakePointerController = std::make_shared<FakePointerController>();
4783 mFakePolicy->setPointerController(mFakePointerController);
4784 }
4785};
4786
4787TEST_F(BluetoothCursorInputMapperTest, TimestampSmoothening) {
4788 addConfigurationProperty("cursor.mode", "pointer");
4789 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4790
4791 nsecs_t kernelEventTime = ARBITRARY_TIME;
4792 nsecs_t expectedEventTime = ARBITRARY_TIME;
4793 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4794 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4795 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4796 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4797 WithEventTime(expectedEventTime))));
4798
4799 // Process several events that come in quick succession, according to their timestamps.
4800 for (int i = 0; i < 3; i++) {
4801 constexpr static nsecs_t delta = ms2ns(1);
4802 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
4803 kernelEventTime += delta;
4804 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
4805
4806 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4807 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4808 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4809 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4810 WithEventTime(expectedEventTime))));
4811 }
4812}
4813
4814TEST_F(BluetoothCursorInputMapperTest, TimestampSmootheningIsCapped) {
4815 addConfigurationProperty("cursor.mode", "pointer");
4816 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4817
4818 nsecs_t expectedEventTime = ARBITRARY_TIME;
4819 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4820 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4821 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4822 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4823 WithEventTime(expectedEventTime))));
4824
4825 // Process several events with the same timestamp from the kernel.
4826 // Ensure that we do not generate events too far into the future.
4827 constexpr static int32_t numEvents =
4828 MAX_BLUETOOTH_SMOOTHING_DELTA / MIN_BLUETOOTH_TIMESTAMP_DELTA;
4829 for (int i = 0; i < numEvents; i++) {
4830 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
4831
4832 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4833 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4834 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4835 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4836 WithEventTime(expectedEventTime))));
4837 }
4838
4839 // By processing more events with the same timestamp, we should not generate events with a
4840 // timestamp that is more than the specified max time delta from the timestamp at its injection.
4841 const nsecs_t cappedEventTime = ARBITRARY_TIME + MAX_BLUETOOTH_SMOOTHING_DELTA;
4842 for (int i = 0; i < 3; i++) {
4843 process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 1);
4844 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
4845 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4846 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4847 WithEventTime(cappedEventTime))));
4848 }
4849}
4850
4851TEST_F(BluetoothCursorInputMapperTest, TimestampSmootheningNotUsed) {
4852 addConfigurationProperty("cursor.mode", "pointer");
4853 CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
4854
4855 nsecs_t kernelEventTime = ARBITRARY_TIME;
4856 nsecs_t expectedEventTime = ARBITRARY_TIME;
4857 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4858 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4859 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4860 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4861 WithEventTime(expectedEventTime))));
4862
4863 // If the next event has a timestamp that is sufficiently spaced out so that Bluetooth timestamp
4864 // smoothening is not needed, its timestamp is not affected.
4865 kernelEventTime += MAX_BLUETOOTH_SMOOTHING_DELTA + ms2ns(1);
4866 expectedEventTime = kernelEventTime;
4867
4868 process(mapper, kernelEventTime, READ_TIME, EV_REL, REL_X, 1);
4869 process(mapper, kernelEventTime, READ_TIME, EV_SYN, SYN_REPORT, 0);
4870 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4871 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
4872 WithEventTime(expectedEventTime))));
4873}
4874
Michael Wrightd02c5b62014-02-10 15:10:22 -08004875// --- TouchInputMapperTest ---
4876
4877class TouchInputMapperTest : public InputMapperTest {
4878protected:
4879 static const int32_t RAW_X_MIN;
4880 static const int32_t RAW_X_MAX;
4881 static const int32_t RAW_Y_MIN;
4882 static const int32_t RAW_Y_MAX;
4883 static const int32_t RAW_TOUCH_MIN;
4884 static const int32_t RAW_TOUCH_MAX;
4885 static const int32_t RAW_TOOL_MIN;
4886 static const int32_t RAW_TOOL_MAX;
4887 static const int32_t RAW_PRESSURE_MIN;
4888 static const int32_t RAW_PRESSURE_MAX;
4889 static const int32_t RAW_ORIENTATION_MIN;
4890 static const int32_t RAW_ORIENTATION_MAX;
4891 static const int32_t RAW_DISTANCE_MIN;
4892 static const int32_t RAW_DISTANCE_MAX;
4893 static const int32_t RAW_TILT_MIN;
4894 static const int32_t RAW_TILT_MAX;
4895 static const int32_t RAW_ID_MIN;
4896 static const int32_t RAW_ID_MAX;
4897 static const int32_t RAW_SLOT_MIN;
4898 static const int32_t RAW_SLOT_MAX;
4899 static const float X_PRECISION;
4900 static const float Y_PRECISION;
Santos Cordonfa5cf462017-04-05 10:37:00 -07004901 static const float X_PRECISION_VIRTUAL;
4902 static const float Y_PRECISION_VIRTUAL;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004903
4904 static const float GEOMETRIC_SCALE;
Jason Gerecke489fda82012-09-07 17:19:40 -07004905 static const TouchAffineTransformation AFFINE_TRANSFORM;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004906
4907 static const VirtualKeyDefinition VIRTUAL_KEYS[2];
4908
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07004909 const std::string UNIQUE_ID = "local:0";
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004910 const std::string SECONDARY_UNIQUE_ID = "local:1";
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07004911
Michael Wrightd02c5b62014-02-10 15:10:22 -08004912 enum Axes {
4913 POSITION = 1 << 0,
4914 TOUCH = 1 << 1,
4915 TOOL = 1 << 2,
4916 PRESSURE = 1 << 3,
4917 ORIENTATION = 1 << 4,
4918 MINOR = 1 << 5,
4919 ID = 1 << 6,
4920 DISTANCE = 1 << 7,
4921 TILT = 1 << 8,
4922 SLOT = 1 << 9,
4923 TOOL_TYPE = 1 << 10,
4924 };
4925
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004926 void prepareDisplay(int32_t orientation, std::optional<uint8_t> port = NO_PORT);
4927 void prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port = NO_PORT);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004928 void prepareVirtualDisplay(int32_t orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004929 void prepareVirtualKeys();
Jason Gerecke489fda82012-09-07 17:19:40 -07004930 void prepareLocationCalibration();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004931 int32_t toRawX(float displayX);
4932 int32_t toRawY(float displayY);
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07004933 int32_t toRotatedRawX(float displayX);
4934 int32_t toRotatedRawY(float displayY);
Jason Gerecke489fda82012-09-07 17:19:40 -07004935 float toCookedX(float rawX, float rawY);
4936 float toCookedY(float rawX, float rawY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004937 float toDisplayX(int32_t rawX);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004938 float toDisplayX(int32_t rawX, int32_t displayWidth);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004939 float toDisplayY(int32_t rawY);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004940 float toDisplayY(int32_t rawY, int32_t displayHeight);
4941
Michael Wrightd02c5b62014-02-10 15:10:22 -08004942};
4943
4944const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
4945const int32_t TouchInputMapperTest::RAW_X_MAX = 1019;
4946const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
4947const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009;
4948const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
4949const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
4950const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
4951const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
Michael Wrightaa449c92017-12-13 21:21:43 +00004952const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = 0;
4953const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = 255;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004954const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
4955const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
4956const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
4957const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
4958const int32_t TouchInputMapperTest::RAW_TILT_MIN = 0;
4959const int32_t TouchInputMapperTest::RAW_TILT_MAX = 150;
4960const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
4961const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
4962const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
4963const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
4964const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
4965const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
Santos Cordonfa5cf462017-04-05 10:37:00 -07004966const float TouchInputMapperTest::X_PRECISION_VIRTUAL =
4967 float(RAW_X_MAX - RAW_X_MIN + 1) / VIRTUAL_DISPLAY_WIDTH;
4968const float TouchInputMapperTest::Y_PRECISION_VIRTUAL =
4969 float(RAW_Y_MAX - RAW_Y_MIN + 1) / VIRTUAL_DISPLAY_HEIGHT;
Jason Gerecke489fda82012-09-07 17:19:40 -07004970const TouchAffineTransformation TouchInputMapperTest::AFFINE_TRANSFORM =
4971 TouchAffineTransformation(1, -2, 3, -4, 5, -6);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004972
4973const float TouchInputMapperTest::GEOMETRIC_SCALE =
4974 avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
4975 float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1));
4976
4977const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
4978 { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
4979 { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
4980};
4981
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004982void TouchInputMapperTest::prepareDisplay(int32_t orientation, std::optional<uint8_t> port) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01004983 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
4984 port, ViewportType::INTERNAL);
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07004985}
4986
4987void TouchInputMapperTest::prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port) {
4988 setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
4989 DISPLAY_ORIENTATION_0, SECONDARY_UNIQUE_ID, port, type);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004990}
4991
Santos Cordonfa5cf462017-04-05 10:37:00 -07004992void TouchInputMapperTest::prepareVirtualDisplay(int32_t orientation) {
Michael Wrightfe3de7d2020-07-02 19:05:30 +01004993 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH, VIRTUAL_DISPLAY_HEIGHT,
4994 orientation, VIRTUAL_DISPLAY_UNIQUE_ID, NO_PORT,
4995 ViewportType::VIRTUAL);
Santos Cordonfa5cf462017-04-05 10:37:00 -07004996}
4997
Michael Wrightd02c5b62014-02-10 15:10:22 -08004998void TouchInputMapperTest::prepareVirtualKeys() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08004999 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[0]);
5000 mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[1]);
5001 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
5002 mFakeEventHub->addKey(EVENTHUB_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005003}
5004
Jason Gerecke489fda82012-09-07 17:19:40 -07005005void TouchInputMapperTest::prepareLocationCalibration() {
5006 mFakePolicy->setTouchAffineTransformation(AFFINE_TRANSFORM);
5007}
5008
Michael Wrightd02c5b62014-02-10 15:10:22 -08005009int32_t TouchInputMapperTest::toRawX(float displayX) {
5010 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
5011}
5012
5013int32_t TouchInputMapperTest::toRawY(float displayY) {
5014 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
5015}
5016
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005017int32_t TouchInputMapperTest::toRotatedRawX(float displayX) {
5018 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_HEIGHT + RAW_X_MIN);
5019}
5020
5021int32_t TouchInputMapperTest::toRotatedRawY(float displayY) {
5022 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_WIDTH + RAW_Y_MIN);
5023}
5024
Jason Gerecke489fda82012-09-07 17:19:40 -07005025float TouchInputMapperTest::toCookedX(float rawX, float rawY) {
5026 AFFINE_TRANSFORM.applyTo(rawX, rawY);
5027 return rawX;
5028}
5029
5030float TouchInputMapperTest::toCookedY(float rawX, float rawY) {
5031 AFFINE_TRANSFORM.applyTo(rawX, rawY);
5032 return rawY;
5033}
5034
Michael Wrightd02c5b62014-02-10 15:10:22 -08005035float TouchInputMapperTest::toDisplayX(int32_t rawX) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005036 return toDisplayX(rawX, DISPLAY_WIDTH);
5037}
5038
5039float TouchInputMapperTest::toDisplayX(int32_t rawX, int32_t displayWidth) {
5040 return float(rawX - RAW_X_MIN) * displayWidth / (RAW_X_MAX - RAW_X_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005041}
5042
5043float TouchInputMapperTest::toDisplayY(int32_t rawY) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005044 return toDisplayY(rawY, DISPLAY_HEIGHT);
5045}
5046
5047float TouchInputMapperTest::toDisplayY(int32_t rawY, int32_t displayHeight) {
5048 return float(rawY - RAW_Y_MIN) * displayHeight / (RAW_Y_MAX - RAW_Y_MIN + 1);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005049}
5050
5051
5052// --- SingleTouchInputMapperTest ---
5053
5054class SingleTouchInputMapperTest : public TouchInputMapperTest {
5055protected:
5056 void prepareButtons();
5057 void prepareAxes(int axes);
5058
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005059 void processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
5060 void processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
5061 void processUp(SingleTouchInputMapper& mappery);
5062 void processPressure(SingleTouchInputMapper& mapper, int32_t pressure);
5063 void processToolMajor(SingleTouchInputMapper& mapper, int32_t toolMajor);
5064 void processDistance(SingleTouchInputMapper& mapper, int32_t distance);
5065 void processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, int32_t tiltY);
5066 void processKey(SingleTouchInputMapper& mapper, int32_t code, int32_t value);
5067 void processSync(SingleTouchInputMapper& mapper);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005068};
5069
5070void SingleTouchInputMapperTest::prepareButtons() {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005071 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005072}
5073
5074void SingleTouchInputMapperTest::prepareAxes(int axes) {
5075 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005076 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
5077 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005078 }
5079 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005080 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MIN,
5081 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005082 }
5083 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005084 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0,
5085 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005086 }
5087 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005088 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_DISTANCE, RAW_DISTANCE_MIN,
5089 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005090 }
5091 if (axes & TILT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08005092 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_X, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
5093 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_Y, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005094 }
5095}
5096
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005097void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005098 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
5099 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
5100 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005101}
5102
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005103void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005104 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
5105 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005106}
5107
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005108void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005109 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005110}
5111
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005112void SingleTouchInputMapperTest::processPressure(SingleTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005113 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005114}
5115
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005116void SingleTouchInputMapperTest::processToolMajor(SingleTouchInputMapper& mapper,
5117 int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005118 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005119}
5120
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005121void SingleTouchInputMapperTest::processDistance(SingleTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005122 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005123}
5124
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005125void SingleTouchInputMapperTest::processTilt(SingleTouchInputMapper& mapper, int32_t tiltX,
5126 int32_t tiltY) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005127 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_X, tiltX);
5128 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_Y, tiltY);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005129}
5130
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005131void SingleTouchInputMapperTest::processKey(SingleTouchInputMapper& mapper, int32_t code,
5132 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005133 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005134}
5135
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005136void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00005137 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005138}
5139
Michael Wrightd02c5b62014-02-10 15:10:22 -08005140TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005141 prepareButtons();
5142 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005143 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005144
Harry Cutts16a24cc2022-10-26 15:22:19 +00005145 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005146}
5147
Michael Wrightd02c5b62014-02-10 15:10:22 -08005148TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005149 prepareButtons();
5150 prepareAxes(POSITION);
5151 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005152 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005153
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005154 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005155}
5156
5157TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005158 addConfigurationProperty("touch.deviceType", "touchScreen");
5159 prepareDisplay(DISPLAY_ORIENTATION_0);
5160 prepareButtons();
5161 prepareAxes(POSITION);
5162 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005163 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005164
5165 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005166 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005167
5168 // Virtual key is down.
5169 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5170 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5171 processDown(mapper, x, y);
5172 processSync(mapper);
5173 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5174
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005175 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005176
5177 // Virtual key is up.
5178 processUp(mapper);
5179 processSync(mapper);
5180 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5181
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005182 ASSERT_EQ(AKEY_STATE_UP, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005183}
5184
5185TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005186 addConfigurationProperty("touch.deviceType", "touchScreen");
5187 prepareDisplay(DISPLAY_ORIENTATION_0);
5188 prepareButtons();
5189 prepareAxes(POSITION);
5190 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005191 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005192
5193 // Unknown key.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005194 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005195
5196 // Virtual key is down.
5197 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5198 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5199 processDown(mapper, x, y);
5200 processSync(mapper);
5201 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5202
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005203 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005204
5205 // Virtual key is up.
5206 processUp(mapper);
5207 processSync(mapper);
5208 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
5209
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005210 ASSERT_EQ(AKEY_STATE_UP, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005211}
5212
5213TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005214 addConfigurationProperty("touch.deviceType", "touchScreen");
5215 prepareDisplay(DISPLAY_ORIENTATION_0);
5216 prepareButtons();
5217 prepareAxes(POSITION);
5218 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005219 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005220
Michael Wrightd02c5b62014-02-10 15:10:22 -08005221 uint8_t flags[2] = { 0, 0 };
Siarhei Vishniakou74007942022-06-13 13:57:47 -07005222 ASSERT_TRUE(
5223 mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_HOME, AKEYCODE_A}, flags));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005224 ASSERT_TRUE(flags[0]);
5225 ASSERT_FALSE(flags[1]);
5226}
5227
5228TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005229 addConfigurationProperty("touch.deviceType", "touchScreen");
5230 prepareDisplay(DISPLAY_ORIENTATION_0);
5231 prepareButtons();
5232 prepareAxes(POSITION);
5233 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005234 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005235
arthurhungdcef2dc2020-08-11 14:47:50 +08005236 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005237
5238 NotifyKeyArgs args;
5239
5240 // Press virtual key.
5241 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5242 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5243 processDown(mapper, x, y);
5244 processSync(mapper);
5245
5246 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
5247 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
5248 ASSERT_EQ(DEVICE_ID, args.deviceId);
5249 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
5250 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
5251 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
5252 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
5253 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
5254 ASSERT_EQ(KEY_HOME, args.scanCode);
5255 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
5256 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
5257
5258 // Release virtual key.
5259 processUp(mapper);
5260 processSync(mapper);
5261
5262 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
5263 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
5264 ASSERT_EQ(DEVICE_ID, args.deviceId);
5265 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
5266 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
5267 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
5268 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
5269 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
5270 ASSERT_EQ(KEY_HOME, args.scanCode);
5271 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
5272 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
5273
5274 // Should not have sent any motions.
5275 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5276}
5277
5278TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005279 addConfigurationProperty("touch.deviceType", "touchScreen");
5280 prepareDisplay(DISPLAY_ORIENTATION_0);
5281 prepareButtons();
5282 prepareAxes(POSITION);
5283 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005284 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005285
arthurhungdcef2dc2020-08-11 14:47:50 +08005286 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005287
5288 NotifyKeyArgs keyArgs;
5289
5290 // Press virtual key.
5291 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
5292 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
5293 processDown(mapper, x, y);
5294 processSync(mapper);
5295
5296 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5297 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
5298 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
5299 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
5300 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
5301 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
5302 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
5303 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
5304 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
5305 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
5306 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
5307
5308 // Move out of bounds. This should generate a cancel and a pointer down since we moved
5309 // into the display area.
5310 y -= 100;
5311 processMove(mapper, x, y);
5312 processSync(mapper);
5313
5314 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
5315 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
5316 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
5317 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
5318 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
5319 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
5320 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
5321 | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
5322 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
5323 ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
5324 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
5325 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
5326
5327 NotifyMotionArgs motionArgs;
5328 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5329 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5330 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5331 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5332 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5333 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5334 ASSERT_EQ(0, motionArgs.flags);
5335 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5336 ASSERT_EQ(0, motionArgs.buttonState);
5337 ASSERT_EQ(0, motionArgs.edgeFlags);
5338 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5339 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5340 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5341 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5342 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5343 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5344 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5345 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5346
5347 // Keep moving out of bounds. Should generate a pointer move.
5348 y -= 50;
5349 processMove(mapper, x, y);
5350 processSync(mapper);
5351
5352 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5353 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5354 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5355 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5356 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5357 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5358 ASSERT_EQ(0, motionArgs.flags);
5359 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5360 ASSERT_EQ(0, motionArgs.buttonState);
5361 ASSERT_EQ(0, motionArgs.edgeFlags);
5362 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5363 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5364 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5365 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5366 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5367 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5368 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5369 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5370
5371 // Release out of bounds. Should generate a pointer up.
5372 processUp(mapper);
5373 processSync(mapper);
5374
5375 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5376 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5377 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5378 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5379 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5380 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5381 ASSERT_EQ(0, motionArgs.flags);
5382 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5383 ASSERT_EQ(0, motionArgs.buttonState);
5384 ASSERT_EQ(0, motionArgs.edgeFlags);
5385 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5386 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5387 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5388 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5389 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5390 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5391 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5392 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5393
5394 // Should not have sent any more keys or motions.
5395 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5396 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5397}
5398
5399TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005400 addConfigurationProperty("touch.deviceType", "touchScreen");
5401 prepareDisplay(DISPLAY_ORIENTATION_0);
5402 prepareButtons();
5403 prepareAxes(POSITION);
5404 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005405 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005406
arthurhungdcef2dc2020-08-11 14:47:50 +08005407 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005408
5409 NotifyMotionArgs motionArgs;
5410
5411 // Initially go down out of bounds.
5412 int32_t x = -10;
5413 int32_t y = -10;
5414 processDown(mapper, x, y);
5415 processSync(mapper);
5416
5417 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5418
5419 // Move into the display area. Should generate a pointer down.
5420 x = 50;
5421 y = 75;
5422 processMove(mapper, x, y);
5423 processSync(mapper);
5424
5425 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5426 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5427 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5428 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5429 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5430 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5431 ASSERT_EQ(0, motionArgs.flags);
5432 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5433 ASSERT_EQ(0, motionArgs.buttonState);
5434 ASSERT_EQ(0, motionArgs.edgeFlags);
5435 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5436 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5437 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5438 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5439 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5440 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5441 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5442 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5443
5444 // Release. Should generate a pointer up.
5445 processUp(mapper);
5446 processSync(mapper);
5447
5448 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5449 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5450 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5451 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5452 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5453 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5454 ASSERT_EQ(0, motionArgs.flags);
5455 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5456 ASSERT_EQ(0, motionArgs.buttonState);
5457 ASSERT_EQ(0, motionArgs.edgeFlags);
5458 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5459 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5460 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5461 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5462 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5463 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5464 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5465 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5466
5467 // Should not have sent any more keys or motions.
5468 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5469 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5470}
5471
Santos Cordonfa5cf462017-04-05 10:37:00 -07005472TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDisplay) {
Santos Cordonfa5cf462017-04-05 10:37:00 -07005473 addConfigurationProperty("touch.deviceType", "touchScreen");
5474 addConfigurationProperty("touch.displayId", VIRTUAL_DISPLAY_UNIQUE_ID);
5475
5476 prepareVirtualDisplay(DISPLAY_ORIENTATION_0);
5477 prepareButtons();
5478 prepareAxes(POSITION);
5479 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005480 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Santos Cordonfa5cf462017-04-05 10:37:00 -07005481
arthurhungdcef2dc2020-08-11 14:47:50 +08005482 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Santos Cordonfa5cf462017-04-05 10:37:00 -07005483
5484 NotifyMotionArgs motionArgs;
5485
5486 // Down.
5487 int32_t x = 100;
5488 int32_t y = 125;
5489 processDown(mapper, x, y);
5490 processSync(mapper);
5491
5492 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5493 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5494 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5495 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5496 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5497 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5498 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5499 ASSERT_EQ(0, motionArgs.flags);
5500 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5501 ASSERT_EQ(0, motionArgs.buttonState);
5502 ASSERT_EQ(0, motionArgs.edgeFlags);
5503 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5504 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5505 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5506 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5507 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5508 1, 0, 0, 0, 0, 0, 0, 0));
5509 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5510 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5511 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5512
5513 // Move.
5514 x += 50;
5515 y += 75;
5516 processMove(mapper, x, y);
5517 processSync(mapper);
5518
5519 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5520 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5521 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5522 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5523 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5524 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5525 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5526 ASSERT_EQ(0, motionArgs.flags);
5527 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5528 ASSERT_EQ(0, motionArgs.buttonState);
5529 ASSERT_EQ(0, motionArgs.edgeFlags);
5530 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5531 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5532 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5533 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5534 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5535 1, 0, 0, 0, 0, 0, 0, 0));
5536 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5537 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5538 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5539
5540 // Up.
5541 processUp(mapper);
5542 processSync(mapper);
5543
5544 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5545 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5546 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5547 ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
5548 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5549 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5550 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5551 ASSERT_EQ(0, motionArgs.flags);
5552 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5553 ASSERT_EQ(0, motionArgs.buttonState);
5554 ASSERT_EQ(0, motionArgs.edgeFlags);
5555 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5556 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5557 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5558 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5559 toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
5560 1, 0, 0, 0, 0, 0, 0, 0));
5561 ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
5562 ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
5563 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5564
5565 // Should not have sent any more keys or motions.
5566 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5567 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5568}
5569
Michael Wrightd02c5b62014-02-10 15:10:22 -08005570TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005571 addConfigurationProperty("touch.deviceType", "touchScreen");
5572 prepareDisplay(DISPLAY_ORIENTATION_0);
5573 prepareButtons();
5574 prepareAxes(POSITION);
5575 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005576 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005577
arthurhungdcef2dc2020-08-11 14:47:50 +08005578 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005579
5580 NotifyMotionArgs motionArgs;
5581
5582 // Down.
5583 int32_t x = 100;
5584 int32_t y = 125;
5585 processDown(mapper, x, y);
5586 processSync(mapper);
5587
5588 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5589 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5590 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5591 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5592 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5593 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5594 ASSERT_EQ(0, motionArgs.flags);
5595 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5596 ASSERT_EQ(0, motionArgs.buttonState);
5597 ASSERT_EQ(0, motionArgs.edgeFlags);
5598 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5599 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5600 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5601 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5602 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5603 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5604 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5605 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5606
5607 // Move.
5608 x += 50;
5609 y += 75;
5610 processMove(mapper, x, y);
5611 processSync(mapper);
5612
5613 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5614 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5615 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5616 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5617 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5618 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5619 ASSERT_EQ(0, motionArgs.flags);
5620 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5621 ASSERT_EQ(0, motionArgs.buttonState);
5622 ASSERT_EQ(0, motionArgs.edgeFlags);
5623 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5624 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5625 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5626 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5627 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5628 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5629 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5630 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5631
5632 // Up.
5633 processUp(mapper);
5634 processSync(mapper);
5635
5636 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5637 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
5638 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
5639 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
5640 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
5641 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5642 ASSERT_EQ(0, motionArgs.flags);
5643 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
5644 ASSERT_EQ(0, motionArgs.buttonState);
5645 ASSERT_EQ(0, motionArgs.edgeFlags);
5646 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
5647 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
5648 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
5649 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
5650 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
5651 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
5652 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
5653 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
5654
5655 // Should not have sent any more keys or motions.
5656 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5657 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5658}
5659
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005660TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_DoesNotRotateMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005661 addConfigurationProperty("touch.deviceType", "touchScreen");
5662 prepareButtons();
5663 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005664 // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
5665 // need to be rotated. Touchscreens are orientation-aware by default.
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005666 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005667
5668 NotifyMotionArgs args;
5669
5670 // Rotation 90.
5671 prepareDisplay(DISPLAY_ORIENTATION_90);
5672 processDown(mapper, toRawX(50), toRawY(75));
5673 processSync(mapper);
5674
5675 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5676 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5677 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5678
5679 processUp(mapper);
5680 processSync(mapper);
5681 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5682}
5683
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005684TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_RotatesMotions) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005685 addConfigurationProperty("touch.deviceType", "touchScreen");
5686 prepareButtons();
5687 prepareAxes(POSITION);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005688 // Since InputReader works in the un-rotated coordinate space, only devices that are not
5689 // orientation-aware are affected by display rotation.
5690 addConfigurationProperty("touch.orientationAware", "0");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005691 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005692
5693 NotifyMotionArgs args;
5694
5695 // Rotation 0.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005696 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005697 prepareDisplay(DISPLAY_ORIENTATION_0);
5698 processDown(mapper, toRawX(50), toRawY(75));
5699 processSync(mapper);
5700
5701 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5702 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5703 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5704
5705 processUp(mapper);
5706 processSync(mapper);
5707 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5708
5709 // Rotation 90.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005710 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005711 prepareDisplay(DISPLAY_ORIENTATION_90);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005712 processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005713 processSync(mapper);
5714
5715 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5716 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5717 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5718
5719 processUp(mapper);
5720 processSync(mapper);
5721 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5722
5723 // Rotation 180.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005724 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005725 prepareDisplay(DISPLAY_ORIENTATION_180);
5726 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
5727 processSync(mapper);
5728
5729 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5730 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5731 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5732
5733 processUp(mapper);
5734 processSync(mapper);
5735 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5736
5737 // Rotation 270.
Siarhei Vishniakou05a8fe22018-10-03 16:38:28 -07005738 clearViewports();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005739 prepareDisplay(DISPLAY_ORIENTATION_270);
Prabir Pradhanc14266f2021-05-12 15:56:24 -07005740 processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005741 processSync(mapper);
5742
5743 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5744 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5745 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5746
5747 processUp(mapper);
5748 processSync(mapper);
5749 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5750}
5751
Prabir Pradhanac1c74f2021-08-20 16:09:32 -07005752TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation0_RotatesMotions) {
5753 addConfigurationProperty("touch.deviceType", "touchScreen");
5754 prepareButtons();
5755 prepareAxes(POSITION);
5756 addConfigurationProperty("touch.orientationAware", "1");
5757 addConfigurationProperty("touch.orientation", "ORIENTATION_0");
5758 clearViewports();
5759 prepareDisplay(DISPLAY_ORIENTATION_0);
5760 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5761 NotifyMotionArgs args;
5762
5763 // Orientation 0.
5764 processDown(mapper, toRawX(50), toRawY(75));
5765 processSync(mapper);
5766
5767 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5768 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5769 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5770
5771 processUp(mapper);
5772 processSync(mapper);
5773 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5774}
5775
5776TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation90_RotatesMotions) {
5777 addConfigurationProperty("touch.deviceType", "touchScreen");
5778 prepareButtons();
5779 prepareAxes(POSITION);
5780 addConfigurationProperty("touch.orientationAware", "1");
5781 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
5782 clearViewports();
5783 prepareDisplay(DISPLAY_ORIENTATION_0);
5784 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5785 NotifyMotionArgs args;
5786
5787 // Orientation 90.
5788 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
5789 processSync(mapper);
5790
5791 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5792 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5793 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5794
5795 processUp(mapper);
5796 processSync(mapper);
5797 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5798}
5799
5800TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation180_RotatesMotions) {
5801 addConfigurationProperty("touch.deviceType", "touchScreen");
5802 prepareButtons();
5803 prepareAxes(POSITION);
5804 addConfigurationProperty("touch.orientationAware", "1");
5805 addConfigurationProperty("touch.orientation", "ORIENTATION_180");
5806 clearViewports();
5807 prepareDisplay(DISPLAY_ORIENTATION_0);
5808 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5809 NotifyMotionArgs args;
5810
5811 // Orientation 180.
5812 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
5813 processSync(mapper);
5814
5815 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5816 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5817 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5818
5819 processUp(mapper);
5820 processSync(mapper);
5821 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5822}
5823
5824TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation270_RotatesMotions) {
5825 addConfigurationProperty("touch.deviceType", "touchScreen");
5826 prepareButtons();
5827 prepareAxes(POSITION);
5828 addConfigurationProperty("touch.orientationAware", "1");
5829 addConfigurationProperty("touch.orientation", "ORIENTATION_270");
5830 clearViewports();
5831 prepareDisplay(DISPLAY_ORIENTATION_0);
5832 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5833 NotifyMotionArgs args;
5834
5835 // Orientation 270.
5836 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
5837 processSync(mapper);
5838
5839 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5840 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5841 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5842
5843 processUp(mapper);
5844 processSync(mapper);
5845 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5846}
5847
5848TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationSpecified_RotatesMotionWithDisplay) {
5849 addConfigurationProperty("touch.deviceType", "touchScreen");
5850 prepareButtons();
5851 prepareAxes(POSITION);
5852 // Since InputReader works in the un-rotated coordinate space, only devices that are not
5853 // orientation-aware are affected by display rotation.
5854 addConfigurationProperty("touch.orientationAware", "0");
5855 addConfigurationProperty("touch.orientation", "ORIENTATION_90");
5856 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
5857
5858 NotifyMotionArgs args;
5859
5860 // Orientation 90, Rotation 0.
5861 clearViewports();
5862 prepareDisplay(DISPLAY_ORIENTATION_0);
5863 processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
5864 processSync(mapper);
5865
5866 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5867 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5868 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5869
5870 processUp(mapper);
5871 processSync(mapper);
5872 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5873
5874 // Orientation 90, Rotation 90.
5875 clearViewports();
5876 prepareDisplay(DISPLAY_ORIENTATION_90);
5877 processDown(mapper, toRotatedRawX(50), toRotatedRawY(75));
5878 processSync(mapper);
5879
5880 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5881 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5882 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5883
5884 processUp(mapper);
5885 processSync(mapper);
5886 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5887
5888 // Orientation 90, Rotation 180.
5889 clearViewports();
5890 prepareDisplay(DISPLAY_ORIENTATION_180);
5891 processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
5892 processSync(mapper);
5893
5894 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5895 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5896 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5897
5898 processUp(mapper);
5899 processSync(mapper);
5900 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5901
5902 // Orientation 90, Rotation 270.
5903 clearViewports();
5904 prepareDisplay(DISPLAY_ORIENTATION_270);
5905 processDown(mapper, RAW_X_MAX - toRotatedRawX(50) + RAW_X_MIN,
5906 RAW_Y_MAX - toRotatedRawY(75) + RAW_Y_MIN);
5907 processSync(mapper);
5908
5909 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5910 EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
5911 EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
5912
5913 processUp(mapper);
5914 processSync(mapper);
5915 EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
5916}
5917
Michael Wrightd02c5b62014-02-10 15:10:22 -08005918TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005919 addConfigurationProperty("touch.deviceType", "touchScreen");
5920 prepareDisplay(DISPLAY_ORIENTATION_0);
5921 prepareButtons();
5922 prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005923 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005924
5925 // These calculations are based on the input device calibration documentation.
5926 int32_t rawX = 100;
5927 int32_t rawY = 200;
5928 int32_t rawPressure = 10;
5929 int32_t rawToolMajor = 12;
5930 int32_t rawDistance = 2;
5931 int32_t rawTiltX = 30;
5932 int32_t rawTiltY = 110;
5933
5934 float x = toDisplayX(rawX);
5935 float y = toDisplayY(rawY);
5936 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
5937 float size = float(rawToolMajor) / RAW_TOOL_MAX;
5938 float tool = float(rawToolMajor) * GEOMETRIC_SCALE;
5939 float distance = float(rawDistance);
5940
5941 float tiltCenter = (RAW_TILT_MAX + RAW_TILT_MIN) * 0.5f;
5942 float tiltScale = M_PI / 180;
5943 float tiltXAngle = (rawTiltX - tiltCenter) * tiltScale;
5944 float tiltYAngle = (rawTiltY - tiltCenter) * tiltScale;
5945 float orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
5946 float tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
5947
5948 processDown(mapper, rawX, rawY);
5949 processPressure(mapper, rawPressure);
5950 processToolMajor(mapper, rawToolMajor);
5951 processDistance(mapper, rawDistance);
5952 processTilt(mapper, rawTiltX, rawTiltY);
5953 processSync(mapper);
5954
5955 NotifyMotionArgs args;
5956 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5957 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5958 x, y, pressure, size, tool, tool, tool, tool, orientation, distance));
5959 ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
5960}
5961
Jason Gerecke489fda82012-09-07 17:19:40 -07005962TEST_F(SingleTouchInputMapperTest, Process_XYAxes_AffineCalibration) {
Jason Gerecke489fda82012-09-07 17:19:40 -07005963 addConfigurationProperty("touch.deviceType", "touchScreen");
5964 prepareDisplay(DISPLAY_ORIENTATION_0);
5965 prepareLocationCalibration();
5966 prepareButtons();
5967 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005968 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Jason Gerecke489fda82012-09-07 17:19:40 -07005969
5970 int32_t rawX = 100;
5971 int32_t rawY = 200;
5972
5973 float x = toDisplayX(toCookedX(rawX, rawY));
5974 float y = toDisplayY(toCookedY(rawX, rawY));
5975
5976 processDown(mapper, rawX, rawY);
5977 processSync(mapper);
5978
5979 NotifyMotionArgs args;
5980 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
5981 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
5982 x, y, 1, 0, 0, 0, 0, 0, 0, 0));
5983}
5984
Michael Wrightd02c5b62014-02-10 15:10:22 -08005985TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005986 addConfigurationProperty("touch.deviceType", "touchScreen");
5987 prepareDisplay(DISPLAY_ORIENTATION_0);
5988 prepareButtons();
5989 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08005990 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005991
5992 NotifyMotionArgs motionArgs;
5993 NotifyKeyArgs keyArgs;
5994
5995 processDown(mapper, 100, 200);
5996 processSync(mapper);
5997 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5998 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5999 ASSERT_EQ(0, motionArgs.buttonState);
6000
6001 // press BTN_LEFT, release BTN_LEFT
6002 processKey(mapper, BTN_LEFT, 1);
6003 processSync(mapper);
6004 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6005 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6006 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6007
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006008 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6009 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6010 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6011
Michael Wrightd02c5b62014-02-10 15:10:22 -08006012 processKey(mapper, BTN_LEFT, 0);
6013 processSync(mapper);
6014 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006015 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006016 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006017
6018 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006019 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006020 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006021
6022 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
6023 processKey(mapper, BTN_RIGHT, 1);
6024 processKey(mapper, BTN_MIDDLE, 1);
6025 processSync(mapper);
6026 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6027 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6028 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
6029 motionArgs.buttonState);
6030
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006031 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6032 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6033 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
6034
6035 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6036 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6037 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
6038 motionArgs.buttonState);
6039
Michael Wrightd02c5b62014-02-10 15:10:22 -08006040 processKey(mapper, BTN_RIGHT, 0);
6041 processSync(mapper);
6042 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006043 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006044 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006045
6046 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006047 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006048 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006049
6050 processKey(mapper, BTN_MIDDLE, 0);
6051 processSync(mapper);
6052 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006053 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006054 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006055
6056 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006057 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006058 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006059
6060 // press BTN_BACK, release BTN_BACK
6061 processKey(mapper, BTN_BACK, 1);
6062 processSync(mapper);
6063 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6064 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6065 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006066
Michael Wrightd02c5b62014-02-10 15:10:22 -08006067 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006068 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006069 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
6070
6071 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6072 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6073 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006074
6075 processKey(mapper, BTN_BACK, 0);
6076 processSync(mapper);
6077 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006078 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006079 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006080
6081 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006082 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006083 ASSERT_EQ(0, motionArgs.buttonState);
6084
Michael Wrightd02c5b62014-02-10 15:10:22 -08006085 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6086 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6087 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
6088
6089 // press BTN_SIDE, release BTN_SIDE
6090 processKey(mapper, BTN_SIDE, 1);
6091 processSync(mapper);
6092 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6093 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6094 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006095
Michael Wrightd02c5b62014-02-10 15:10:22 -08006096 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006097 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006098 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
6099
6100 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6101 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6102 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006103
6104 processKey(mapper, BTN_SIDE, 0);
6105 processSync(mapper);
6106 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006107 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006108 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006109
6110 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006111 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006112 ASSERT_EQ(0, motionArgs.buttonState);
6113
Michael Wrightd02c5b62014-02-10 15:10:22 -08006114 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6115 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6116 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
6117
6118 // press BTN_FORWARD, release BTN_FORWARD
6119 processKey(mapper, BTN_FORWARD, 1);
6120 processSync(mapper);
6121 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6122 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6123 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006124
Michael Wrightd02c5b62014-02-10 15:10:22 -08006125 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006126 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006127 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
6128
6129 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6130 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6131 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006132
6133 processKey(mapper, BTN_FORWARD, 0);
6134 processSync(mapper);
6135 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006136 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006137 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006138
6139 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006140 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006141 ASSERT_EQ(0, motionArgs.buttonState);
6142
Michael Wrightd02c5b62014-02-10 15:10:22 -08006143 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6144 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6145 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
6146
6147 // press BTN_EXTRA, release BTN_EXTRA
6148 processKey(mapper, BTN_EXTRA, 1);
6149 processSync(mapper);
6150 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6151 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
6152 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006153
Michael Wrightd02c5b62014-02-10 15:10:22 -08006154 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006155 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006156 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
6157
6158 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6159 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6160 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006161
6162 processKey(mapper, BTN_EXTRA, 0);
6163 processSync(mapper);
6164 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006165 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006166 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006167
6168 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006169 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006170 ASSERT_EQ(0, motionArgs.buttonState);
6171
Michael Wrightd02c5b62014-02-10 15:10:22 -08006172 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
6173 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
6174 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
6175
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006176 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6177
Michael Wrightd02c5b62014-02-10 15:10:22 -08006178 // press BTN_STYLUS, release BTN_STYLUS
6179 processKey(mapper, BTN_STYLUS, 1);
6180 processSync(mapper);
6181 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6182 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006183 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
6184
6185 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6186 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6187 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006188
6189 processKey(mapper, BTN_STYLUS, 0);
6190 processSync(mapper);
6191 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006192 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006193 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006194
6195 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006196 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006197 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006198
6199 // press BTN_STYLUS2, release BTN_STYLUS2
6200 processKey(mapper, BTN_STYLUS2, 1);
6201 processSync(mapper);
6202 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6203 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006204 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
6205
6206 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6207 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6208 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006209
6210 processKey(mapper, BTN_STYLUS2, 0);
6211 processSync(mapper);
6212 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006213 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006214 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006215
6216 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08006217 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08006218 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006219
6220 // release touch
6221 processUp(mapper);
6222 processSync(mapper);
6223 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6224 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6225 ASSERT_EQ(0, motionArgs.buttonState);
6226}
6227
6228TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006229 addConfigurationProperty("touch.deviceType", "touchScreen");
6230 prepareDisplay(DISPLAY_ORIENTATION_0);
6231 prepareButtons();
6232 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006233 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006234
6235 NotifyMotionArgs motionArgs;
6236
6237 // default tool type is finger
6238 processDown(mapper, 100, 200);
6239 processSync(mapper);
6240 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6241 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6242 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6243
6244 // eraser
6245 processKey(mapper, BTN_TOOL_RUBBER, 1);
6246 processSync(mapper);
6247 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6248 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6249 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
6250
6251 // stylus
6252 processKey(mapper, BTN_TOOL_RUBBER, 0);
6253 processKey(mapper, BTN_TOOL_PEN, 1);
6254 processSync(mapper);
6255 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6256 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6257 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6258
6259 // brush
6260 processKey(mapper, BTN_TOOL_PEN, 0);
6261 processKey(mapper, BTN_TOOL_BRUSH, 1);
6262 processSync(mapper);
6263 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6264 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6265 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6266
6267 // pencil
6268 processKey(mapper, BTN_TOOL_BRUSH, 0);
6269 processKey(mapper, BTN_TOOL_PENCIL, 1);
6270 processSync(mapper);
6271 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6272 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6273 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6274
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08006275 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08006276 processKey(mapper, BTN_TOOL_PENCIL, 0);
6277 processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
6278 processSync(mapper);
6279 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6280 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6281 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6282
6283 // mouse
6284 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
6285 processKey(mapper, BTN_TOOL_MOUSE, 1);
6286 processSync(mapper);
6287 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6288 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6289 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6290
6291 // lens
6292 processKey(mapper, BTN_TOOL_MOUSE, 0);
6293 processKey(mapper, BTN_TOOL_LENS, 1);
6294 processSync(mapper);
6295 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6296 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6297 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6298
6299 // double-tap
6300 processKey(mapper, BTN_TOOL_LENS, 0);
6301 processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
6302 processSync(mapper);
6303 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6304 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6305 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6306
6307 // triple-tap
6308 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
6309 processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
6310 processSync(mapper);
6311 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6312 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6313 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6314
6315 // quad-tap
6316 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
6317 processKey(mapper, BTN_TOOL_QUADTAP, 1);
6318 processSync(mapper);
6319 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6320 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6321 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6322
6323 // finger
6324 processKey(mapper, BTN_TOOL_QUADTAP, 0);
6325 processKey(mapper, BTN_TOOL_FINGER, 1);
6326 processSync(mapper);
6327 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6328 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6329 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6330
6331 // stylus trumps finger
6332 processKey(mapper, BTN_TOOL_PEN, 1);
6333 processSync(mapper);
6334 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6335 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6336 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
6337
6338 // eraser trumps stylus
6339 processKey(mapper, BTN_TOOL_RUBBER, 1);
6340 processSync(mapper);
6341 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6342 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6343 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
6344
6345 // mouse trumps eraser
6346 processKey(mapper, BTN_TOOL_MOUSE, 1);
6347 processSync(mapper);
6348 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6349 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6350 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
6351
6352 // back to default tool type
6353 processKey(mapper, BTN_TOOL_MOUSE, 0);
6354 processKey(mapper, BTN_TOOL_RUBBER, 0);
6355 processKey(mapper, BTN_TOOL_PEN, 0);
6356 processKey(mapper, BTN_TOOL_FINGER, 0);
6357 processSync(mapper);
6358 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6359 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6360 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
6361}
6362
6363TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006364 addConfigurationProperty("touch.deviceType", "touchScreen");
6365 prepareDisplay(DISPLAY_ORIENTATION_0);
6366 prepareButtons();
6367 prepareAxes(POSITION);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08006368 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006369 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006370
6371 NotifyMotionArgs motionArgs;
6372
6373 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
6374 processKey(mapper, BTN_TOOL_FINGER, 1);
6375 processMove(mapper, 100, 200);
6376 processSync(mapper);
6377 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6378 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6379 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6380 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6381
6382 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6383 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6384 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6385 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6386
6387 // move a little
6388 processMove(mapper, 150, 250);
6389 processSync(mapper);
6390 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6391 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6392 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6393 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6394
6395 // down when BTN_TOUCH is pressed, pressure defaults to 1
6396 processKey(mapper, BTN_TOUCH, 1);
6397 processSync(mapper);
6398 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6399 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6400 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6401 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6402
6403 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6404 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6405 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6406 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6407
6408 // up when BTN_TOUCH is released, hover restored
6409 processKey(mapper, BTN_TOUCH, 0);
6410 processSync(mapper);
6411 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6412 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6413 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6414 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6415
6416 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6417 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6418 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6419 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6420
6421 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6422 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6423 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6424 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6425
6426 // exit hover when pointer goes away
6427 processKey(mapper, BTN_TOOL_FINGER, 0);
6428 processSync(mapper);
6429 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6430 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6431 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6432 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6433}
6434
6435TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006436 addConfigurationProperty("touch.deviceType", "touchScreen");
6437 prepareDisplay(DISPLAY_ORIENTATION_0);
6438 prepareButtons();
6439 prepareAxes(POSITION | PRESSURE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08006440 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08006441
6442 NotifyMotionArgs motionArgs;
6443
6444 // initially hovering because pressure is 0
6445 processDown(mapper, 100, 200);
6446 processPressure(mapper, 0);
6447 processSync(mapper);
6448 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6449 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6450 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6451 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6452
6453 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6454 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6455 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6456 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
6457
6458 // move a little
6459 processMove(mapper, 150, 250);
6460 processSync(mapper);
6461 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6462 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6463 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6464 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6465
6466 // down when pressure is non-zero
6467 processPressure(mapper, RAW_PRESSURE_MAX);
6468 processSync(mapper);
6469 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6470 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6471 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6472 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6473
6474 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6475 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6476 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6477 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6478
6479 // up when pressure becomes 0, hover restored
6480 processPressure(mapper, 0);
6481 processSync(mapper);
6482 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6483 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6484 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6485 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
6486
6487 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6488 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
6489 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6490 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6491
6492 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6493 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
6494 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6495 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6496
6497 // exit hover when pointer goes away
6498 processUp(mapper);
6499 processSync(mapper);
6500 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6501 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
6502 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6503 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
6504}
6505
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006506TEST_F(SingleTouchInputMapperTest, Reset_CancelsOngoingGesture) {
6507 addConfigurationProperty("touch.deviceType", "touchScreen");
6508 prepareDisplay(DISPLAY_ORIENTATION_0);
6509 prepareButtons();
6510 prepareAxes(POSITION | PRESSURE);
6511 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6512
6513 // Touch down.
6514 processDown(mapper, 100, 200);
6515 processPressure(mapper, 1);
6516 processSync(mapper);
6517 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6518 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
6519
6520 // Reset the mapper. This should cancel the ongoing gesture.
6521 resetMapper(mapper, ARBITRARY_TIME);
6522 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6523 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
6524
6525 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6526}
6527
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006528TEST_F(SingleTouchInputMapperTest, Reset_RecreatesTouchState) {
6529 addConfigurationProperty("touch.deviceType", "touchScreen");
6530 prepareDisplay(DISPLAY_ORIENTATION_0);
6531 prepareButtons();
6532 prepareAxes(POSITION | PRESSURE);
6533 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6534
6535 // Set the initial state for the touch pointer.
6536 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 100);
6537 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 200);
6538 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MAX);
6539 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
6540
6541 // Reset the mapper. When the mapper is reset, we expect it to attempt to recreate the touch
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00006542 // state by reading the current axis values. Since there was no ongoing gesture, calling reset
6543 // does not generate any events.
6544 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006545
6546 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
6547 // the recreated touch state to generate a down event.
6548 processSync(mapper);
6549 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6550 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
6551
6552 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6553}
6554
lilinnan687e58f2022-07-19 16:00:50 +08006555TEST_F(SingleTouchInputMapperTest,
6556 Process_WhenViewportDisplayIdChanged_TouchIsCanceledAndDeviceIsReset) {
6557 addConfigurationProperty("touch.deviceType", "touchScreen");
6558 prepareDisplay(DISPLAY_ORIENTATION_0);
6559 prepareButtons();
6560 prepareAxes(POSITION);
6561 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6562 NotifyMotionArgs motionArgs;
6563
6564 // Down.
Prabir Pradhan3e5ec702022-07-29 16:26:24 +00006565 processDown(mapper, 100, 200);
lilinnan687e58f2022-07-19 16:00:50 +08006566 processSync(mapper);
6567
6568 // We should receive a down event
6569 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6570 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6571
6572 // Change display id
6573 clearViewports();
6574 prepareSecondaryDisplay(ViewportType::INTERNAL);
6575
6576 // We should receive a cancel event
6577 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6578 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
6579 // Then receive reset called
6580 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6581}
6582
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006583TEST_F(SingleTouchInputMapperTest,
6584 Process_WhenViewportActiveStatusChanged_TouchIsCanceledAndDeviceIsReset) {
6585 addConfigurationProperty("touch.deviceType", "touchScreen");
6586 prepareDisplay(DISPLAY_ORIENTATION_0);
6587 prepareButtons();
6588 prepareAxes(POSITION);
6589 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6590 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6591 NotifyMotionArgs motionArgs;
6592
6593 // Start a new gesture.
6594 processDown(mapper, 100, 200);
6595 processSync(mapper);
6596 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6597 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6598
6599 // Make the viewport inactive. This will put the device in disabled mode.
6600 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6601 viewport->isActive = false;
6602 mFakePolicy->updateViewport(*viewport);
6603 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
6604
6605 // We should receive a cancel event for the ongoing gesture.
6606 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6607 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
6608 // Then we should be notified that the device was reset.
6609 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6610
6611 // No events are generated while the viewport is inactive.
6612 processMove(mapper, 101, 201);
6613 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006614 processUp(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006615 processSync(mapper);
6616 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6617
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006618 // Start a new gesture while the viewport is still inactive.
6619 processDown(mapper, 300, 400);
6620 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 300);
6621 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 400);
6622 mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
6623 processSync(mapper);
6624
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006625 // Make the viewport active again. The device should resume processing events.
6626 viewport->isActive = true;
6627 mFakePolicy->updateViewport(*viewport);
6628 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
6629
6630 // The device is reset because it changes back to direct mode, without generating any events.
6631 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6632 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6633
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006634 // In the next sync, the touch state that was recreated when the device was reset is reported.
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006635 processSync(mapper);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00006636 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6637 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00006638
6639 // No more events.
6640 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6641 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
6642}
6643
Prabir Pradhan211ba622022-10-31 21:09:21 +00006644TEST_F(SingleTouchInputMapperTest, ButtonIsReleasedOnTouchUp) {
6645 addConfigurationProperty("touch.deviceType", "touchScreen");
6646 prepareDisplay(DISPLAY_ORIENTATION_0);
6647 prepareButtons();
6648 prepareAxes(POSITION);
6649 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6650 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
6651
6652 // Press a stylus button.
6653 processKey(mapper, BTN_STYLUS, 1);
6654 processSync(mapper);
6655
6656 // Start a touch gesture and ensure the BUTTON_PRESS event is generated.
6657 processDown(mapper, 100, 200);
6658 processSync(mapper);
6659 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6660 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
6661 WithCoords(toDisplayX(100), toDisplayY(200)),
6662 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
6663 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6664 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
6665 WithCoords(toDisplayX(100), toDisplayY(200)),
6666 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
6667
6668 // Release the touch gesture. Ensure that the BUTTON_RELEASE event is generated even though
6669 // the button has not actually been released, since there will be no pointers through which the
6670 // button state can be reported. The event is generated at the location of the pointer before
6671 // it went up.
6672 processUp(mapper);
6673 processSync(mapper);
6674 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6675 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
6676 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
6677 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6678 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
6679 WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
6680}
6681
Prabir Pradhan5632d622021-09-06 07:57:20 -07006682// --- TouchDisplayProjectionTest ---
6683
6684class TouchDisplayProjectionTest : public SingleTouchInputMapperTest {
6685public:
6686 // The values inside DisplayViewport are expected to be pre-rotated. This updates the current
6687 // DisplayViewport to pre-rotate the values. The viewport's physical display will be set to the
6688 // rotated equivalent of the given un-rotated physical display bounds.
6689 void configurePhysicalDisplay(int32_t orientation, Rect naturalPhysicalDisplay) {
6690 uint32_t inverseRotationFlags;
6691 auto width = DISPLAY_WIDTH;
6692 auto height = DISPLAY_HEIGHT;
6693 switch (orientation) {
6694 case DISPLAY_ORIENTATION_90:
6695 inverseRotationFlags = ui::Transform::ROT_270;
6696 std::swap(width, height);
6697 break;
6698 case DISPLAY_ORIENTATION_180:
6699 inverseRotationFlags = ui::Transform::ROT_180;
6700 break;
6701 case DISPLAY_ORIENTATION_270:
6702 inverseRotationFlags = ui::Transform::ROT_90;
6703 std::swap(width, height);
6704 break;
6705 case DISPLAY_ORIENTATION_0:
6706 inverseRotationFlags = ui::Transform::ROT_0;
6707 break;
6708 default:
6709 FAIL() << "Invalid orientation: " << orientation;
6710 }
6711
6712 const ui::Transform rotation(inverseRotationFlags, width, height);
6713 const Rect rotatedPhysicalDisplay = rotation.transform(naturalPhysicalDisplay);
6714
6715 std::optional<DisplayViewport> internalViewport =
6716 *mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
6717 DisplayViewport& v = *internalViewport;
6718 v.displayId = DISPLAY_ID;
6719 v.orientation = orientation;
6720
6721 v.logicalLeft = 0;
6722 v.logicalTop = 0;
6723 v.logicalRight = 100;
6724 v.logicalBottom = 100;
6725
6726 v.physicalLeft = rotatedPhysicalDisplay.left;
6727 v.physicalTop = rotatedPhysicalDisplay.top;
6728 v.physicalRight = rotatedPhysicalDisplay.right;
6729 v.physicalBottom = rotatedPhysicalDisplay.bottom;
6730
6731 v.deviceWidth = width;
6732 v.deviceHeight = height;
6733
6734 v.isActive = true;
6735 v.uniqueId = UNIQUE_ID;
6736 v.type = ViewportType::INTERNAL;
6737 mFakePolicy->updateViewport(v);
6738 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
6739 }
6740
6741 void assertReceivedMove(const Point& point) {
6742 NotifyMotionArgs motionArgs;
6743 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6744 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6745 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6746 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], point.x, point.y,
6747 1, 0, 0, 0, 0, 0, 0, 0));
6748 }
6749};
6750
6751TEST_F(TouchDisplayProjectionTest, IgnoresTouchesOutsidePhysicalDisplay) {
6752 addConfigurationProperty("touch.deviceType", "touchScreen");
6753 prepareDisplay(DISPLAY_ORIENTATION_0);
6754
6755 prepareButtons();
6756 prepareAxes(POSITION);
6757 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6758
6759 NotifyMotionArgs motionArgs;
6760
6761 // Configure the DisplayViewport such that the logical display maps to a subsection of
6762 // the display panel called the physical display. Here, the physical display is bounded by the
6763 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
6764 static const Rect kPhysicalDisplay{10, 20, 70, 160};
6765 static const std::array<Point, 6> kPointsOutsidePhysicalDisplay{
6766 {{-10, -10}, {0, 0}, {5, 100}, {50, 15}, {75, 100}, {50, 165}}};
6767
6768 for (auto orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90, DISPLAY_ORIENTATION_180,
6769 DISPLAY_ORIENTATION_270}) {
6770 configurePhysicalDisplay(orientation, kPhysicalDisplay);
6771
6772 // Touches outside the physical display should be ignored, and should not generate any
6773 // events. Ensure touches at the following points that lie outside of the physical display
6774 // area do not generate any events.
6775 for (const auto& point : kPointsOutsidePhysicalDisplay) {
6776 processDown(mapper, toRawX(point.x), toRawY(point.y));
6777 processSync(mapper);
6778 processUp(mapper);
6779 processSync(mapper);
6780 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled())
6781 << "Unexpected event generated for touch outside physical display at point: "
6782 << point.x << ", " << point.y;
6783 }
6784 }
6785}
6786
6787TEST_F(TouchDisplayProjectionTest, EmitsTouchDownAfterEnteringPhysicalDisplay) {
6788 addConfigurationProperty("touch.deviceType", "touchScreen");
6789 prepareDisplay(DISPLAY_ORIENTATION_0);
6790
6791 prepareButtons();
6792 prepareAxes(POSITION);
6793 SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6794
6795 NotifyMotionArgs motionArgs;
6796
6797 // Configure the DisplayViewport such that the logical display maps to a subsection of
6798 // the display panel called the physical display. Here, the physical display is bounded by the
6799 // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
6800 static const Rect kPhysicalDisplay{10, 20, 70, 160};
6801
6802 for (auto orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90, DISPLAY_ORIENTATION_180,
6803 DISPLAY_ORIENTATION_270}) {
6804 configurePhysicalDisplay(orientation, kPhysicalDisplay);
6805
6806 // Touches that start outside the physical display should be ignored until it enters the
6807 // physical display bounds, at which point it should generate a down event. Start a touch at
6808 // the point (5, 100), which is outside the physical display bounds.
6809 static const Point kOutsidePoint{5, 100};
6810 processDown(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
6811 processSync(mapper);
6812 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6813
6814 // Move the touch into the physical display area. This should generate a pointer down.
6815 processMove(mapper, toRawX(11), toRawY(21));
6816 processSync(mapper);
6817 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6818 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6819 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
6820 ASSERT_NO_FATAL_FAILURE(
6821 assertPointerCoords(motionArgs.pointerCoords[0], 11, 21, 1, 0, 0, 0, 0, 0, 0, 0));
6822
6823 // Move the touch inside the physical display area. This should generate a pointer move.
6824 processMove(mapper, toRawX(69), toRawY(159));
6825 processSync(mapper);
6826 assertReceivedMove({69, 159});
6827
6828 // Move outside the physical display area. Since the pointer is already down, this should
6829 // now continue generating events.
6830 processMove(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
6831 processSync(mapper);
6832 assertReceivedMove(kOutsidePoint);
6833
6834 // Release. This should generate a pointer up.
6835 processUp(mapper);
6836 processSync(mapper);
6837 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6838 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6839 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], kOutsidePoint.x,
6840 kOutsidePoint.y, 1, 0, 0, 0, 0, 0, 0, 0));
6841
6842 // Ensure no more events were generated.
6843 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6844 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6845 }
6846}
6847
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00006848// --- ExternalStylusFusionTest ---
6849
6850class ExternalStylusFusionTest : public SingleTouchInputMapperTest {
6851public:
6852 SingleTouchInputMapper& initializeInputMapperWithExternalStylus() {
6853 addConfigurationProperty("touch.deviceType", "touchScreen");
6854 prepareDisplay(DISPLAY_ORIENTATION_0);
6855 prepareButtons();
6856 prepareAxes(POSITION);
6857 auto& mapper = addMapperAndConfigure<SingleTouchInputMapper>();
6858
6859 mStylusState.when = ARBITRARY_TIME;
6860 mStylusState.pressure = 0.f;
6861 mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
6862 mReader->getContext()->setExternalStylusDevices({mExternalStylusDeviceInfo});
6863 configureDevice(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE);
6864 processExternalStylusState(mapper);
6865 return mapper;
6866 }
6867
6868 std::list<NotifyArgs> processExternalStylusState(InputMapper& mapper) {
6869 std::list<NotifyArgs> generatedArgs = mapper.updateExternalStylusState(mStylusState);
6870 for (const NotifyArgs& args : generatedArgs) {
6871 mFakeListener->notify(args);
6872 }
6873 // Loop the reader to flush the input listener queue.
6874 mReader->loopOnce();
6875 return generatedArgs;
6876 }
6877
6878protected:
6879 StylusState mStylusState{};
6880 static constexpr uint32_t EXPECTED_SOURCE =
6881 AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_BLUETOOTH_STYLUS;
6882
6883 void testStartFusedStylusGesture(SingleTouchInputMapper& mapper) {
6884 auto toolTypeSource =
6885 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
6886
6887 // The first pointer is withheld.
6888 processDown(mapper, 100, 200);
6889 processSync(mapper);
6890 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6891 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
6892 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
6893
6894 // The external stylus reports pressure. The withheld finger pointer is released as a
6895 // stylus.
6896 mStylusState.pressure = 1.f;
6897 processExternalStylusState(mapper);
6898 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6899 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
6900 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6901
6902 // Subsequent pointer events are not withheld.
6903 processMove(mapper, 101, 201);
6904 processSync(mapper);
6905 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6906 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
6907
6908 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6909 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6910 }
6911
6912 void testSuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
6913 ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
6914
6915 // Releasing the touch pointer ends the gesture.
6916 processUp(mapper);
6917 processSync(mapper);
6918 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6919 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(EXPECTED_SOURCE),
6920 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
6921
6922 mStylusState.pressure = 0.f;
6923 processExternalStylusState(mapper);
6924 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6925 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6926 }
6927
6928 void testUnsuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
6929 auto toolTypeSource =
6930 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER));
6931
6932 // The first pointer is withheld when an external stylus is connected,
6933 // and a timeout is requested.
6934 processDown(mapper, 100, 200);
6935 processSync(mapper);
6936 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6937 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
6938 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
6939
6940 // If the timeout expires early, it is requested again.
6941 handleTimeout(mapper, ARBITRARY_TIME + 1);
6942 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
6943 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
6944
6945 // When the timeout expires, the withheld touch is released as a finger pointer.
6946 handleTimeout(mapper, ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT);
6947 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6948 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
6949
6950 // Subsequent pointer events are not withheld.
6951 processMove(mapper, 101, 201);
6952 processSync(mapper);
6953 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6954 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
6955 processUp(mapper);
6956 processSync(mapper);
6957 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
6958 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP))));
6959
6960 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6961 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6962 }
6963
6964private:
6965 InputDeviceInfo mExternalStylusDeviceInfo{};
6966};
6967
6968TEST_F(ExternalStylusFusionTest, UsesBluetoothStylusSource) {
6969 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
6970 ASSERT_EQ(EXPECTED_SOURCE, mapper.getSources());
6971}
6972
6973TEST_F(ExternalStylusFusionTest, UnsuccessfulFusion) {
6974 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
6975 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
6976}
6977
6978TEST_F(ExternalStylusFusionTest, SuccessfulFusion_TouchFirst) {
6979 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
6980 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
6981}
6982
6983// Test a successful stylus fusion gesture where the pressure is reported by the external
6984// before the touch is reported by the touchscreen.
6985TEST_F(ExternalStylusFusionTest, SuccessfulFusion_PressureFirst) {
6986 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
6987 auto toolTypeSource =
6988 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
6989
6990 // The external stylus reports pressure first. It is ignored for now.
6991 mStylusState.pressure = 1.f;
6992 processExternalStylusState(mapper);
6993 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6994 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
6995
6996 // When the touch goes down afterwards, it is reported as a stylus pointer.
6997 processDown(mapper, 100, 200);
6998 processSync(mapper);
6999 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7000 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
7001 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7002
7003 processMove(mapper, 101, 201);
7004 processSync(mapper);
7005 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7006 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
7007 processUp(mapper);
7008 processSync(mapper);
7009 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7010 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP))));
7011
7012 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7013 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7014}
7015
7016TEST_F(ExternalStylusFusionTest, FusionIsRepeatedForEachNewGesture) {
7017 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7018
7019 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
7020 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
7021
7022 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
7023 ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
7024 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
7025 ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
7026}
7027
7028TEST_F(ExternalStylusFusionTest, FusedPointerReportsPressureChanges) {
7029 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7030 auto toolTypeSource =
7031 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
7032
7033 mStylusState.pressure = 0.8f;
7034 processExternalStylusState(mapper);
7035 processDown(mapper, 100, 200);
7036 processSync(mapper);
7037 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7038 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7039 WithPressure(0.8f))));
7040 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7041
7042 // The external stylus reports a pressure change. We wait for some time for a touch event.
7043 mStylusState.pressure = 0.6f;
7044 processExternalStylusState(mapper);
7045 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7046 ASSERT_NO_FATAL_FAILURE(
7047 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7048
7049 // If a touch is reported within the timeout, it reports the updated pressure.
7050 processMove(mapper, 101, 201);
7051 processSync(mapper);
7052 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7053 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7054 WithPressure(0.6f))));
7055 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7056
7057 // There is another pressure change.
7058 mStylusState.pressure = 0.5f;
7059 processExternalStylusState(mapper);
7060 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7061 ASSERT_NO_FATAL_FAILURE(
7062 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7063
7064 // If a touch is not reported within the timeout, a move event is generated to report
7065 // the new pressure.
7066 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
7067 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7068 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7069 WithPressure(0.5f))));
7070
7071 // If a zero pressure is reported before the touch goes up, the previous pressure value is
7072 // repeated indefinitely.
7073 mStylusState.pressure = 0.0f;
7074 processExternalStylusState(mapper);
7075 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7076 ASSERT_NO_FATAL_FAILURE(
7077 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7078 processMove(mapper, 102, 202);
7079 processSync(mapper);
7080 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7081 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7082 WithPressure(0.5f))));
7083 processMove(mapper, 103, 203);
7084 processSync(mapper);
7085 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7086 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7087 WithPressure(0.5f))));
7088
7089 processUp(mapper);
7090 processSync(mapper);
7091 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7092 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(EXPECTED_SOURCE),
7093 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
7094
7095 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7096 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7097}
7098
7099TEST_F(ExternalStylusFusionTest, FusedPointerReportsToolTypeChanges) {
7100 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7101 auto source = WithSource(EXPECTED_SOURCE);
7102
7103 mStylusState.pressure = 1.f;
7104 mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_ERASER;
7105 processExternalStylusState(mapper);
7106 processDown(mapper, 100, 200);
7107 processSync(mapper);
7108 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7109 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
7110 WithToolType(AMOTION_EVENT_TOOL_TYPE_ERASER))));
7111 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7112
7113 // The external stylus reports a tool change. We wait for some time for a touch event.
7114 mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
7115 processExternalStylusState(mapper);
7116 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7117 ASSERT_NO_FATAL_FAILURE(
7118 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7119
7120 // If a touch is reported within the timeout, it reports the updated pressure.
7121 processMove(mapper, 101, 201);
7122 processSync(mapper);
7123 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7124 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7125 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
7126 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7127
7128 // There is another tool type change.
7129 mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
7130 processExternalStylusState(mapper);
7131 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7132 ASSERT_NO_FATAL_FAILURE(
7133 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7134
7135 // If a touch is not reported within the timeout, a move event is generated to report
7136 // the new tool type.
7137 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
7138 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7139 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7140 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
7141
7142 processUp(mapper);
7143 processSync(mapper);
7144 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7145 AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_UP),
7146 WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))));
7147
7148 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7149 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7150}
7151
7152TEST_F(ExternalStylusFusionTest, FusedPointerReportsButtons) {
7153 SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
7154 auto toolTypeSource =
7155 AllOf(WithSource(EXPECTED_SOURCE), WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS));
7156
7157 ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
7158
7159 // The external stylus reports a button change. We wait for some time for a touch event.
7160 mStylusState.buttons = AMOTION_EVENT_BUTTON_STYLUS_PRIMARY;
7161 processExternalStylusState(mapper);
7162 ASSERT_NO_FATAL_FAILURE(
7163 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7164
7165 // If a touch is reported within the timeout, it reports the updated button state.
7166 processMove(mapper, 101, 201);
7167 processSync(mapper);
7168 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7169 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7170 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7171 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7172 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
7173 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7174 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7175
7176 // The button is now released.
7177 mStylusState.buttons = 0;
7178 processExternalStylusState(mapper);
7179 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7180 ASSERT_NO_FATAL_FAILURE(
7181 mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
7182
7183 // If a touch is not reported within the timeout, a move event is generated to report
7184 // the new button state.
7185 handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007186 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7187 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
7188 WithButtonState(0))));
7189 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan124ea442022-10-28 20:27:44 +00007190 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7191 WithButtonState(0))));
7192
7193 processUp(mapper);
7194 processSync(mapper);
7195 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
Prabir Pradhan7d04c4b2022-10-28 19:23:26 +00007196 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
7197
7198 ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
7199 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7200}
7201
Michael Wrightd02c5b62014-02-10 15:10:22 -08007202// --- MultiTouchInputMapperTest ---
7203
7204class MultiTouchInputMapperTest : public TouchInputMapperTest {
7205protected:
7206 void prepareAxes(int axes);
7207
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007208 void processPosition(MultiTouchInputMapper& mapper, int32_t x, int32_t y);
7209 void processTouchMajor(MultiTouchInputMapper& mapper, int32_t touchMajor);
7210 void processTouchMinor(MultiTouchInputMapper& mapper, int32_t touchMinor);
7211 void processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor);
7212 void processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor);
7213 void processOrientation(MultiTouchInputMapper& mapper, int32_t orientation);
7214 void processPressure(MultiTouchInputMapper& mapper, int32_t pressure);
7215 void processDistance(MultiTouchInputMapper& mapper, int32_t distance);
7216 void processId(MultiTouchInputMapper& mapper, int32_t id);
7217 void processSlot(MultiTouchInputMapper& mapper, int32_t slot);
7218 void processToolType(MultiTouchInputMapper& mapper, int32_t toolType);
7219 void processKey(MultiTouchInputMapper& mapper, int32_t code, int32_t value);
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00007220 void processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode, int32_t value);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007221 void processMTSync(MultiTouchInputMapper& mapper);
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00007222 void processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime = ARBITRARY_TIME,
7223 nsecs_t readTime = READ_TIME);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007224};
7225
7226void MultiTouchInputMapperTest::prepareAxes(int axes) {
7227 if (axes & POSITION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007228 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
7229 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007230 }
7231 if (axes & TOUCH) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007232 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN,
7233 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007234 if (axes & MINOR) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007235 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN,
7236 RAW_TOUCH_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007237 }
7238 }
7239 if (axes & TOOL) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007240 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7241 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007242 if (axes & MINOR) {
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08007243 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN,
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007244 RAW_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007245 }
7246 }
7247 if (axes & ORIENTATION) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007248 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_ORIENTATION, RAW_ORIENTATION_MIN,
7249 RAW_ORIENTATION_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007250 }
7251 if (axes & PRESSURE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007252 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, RAW_PRESSURE_MIN,
7253 RAW_PRESSURE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007254 }
7255 if (axes & DISTANCE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007256 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_DISTANCE, RAW_DISTANCE_MIN,
7257 RAW_DISTANCE_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007258 }
7259 if (axes & ID) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007260 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX, 0,
7261 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007262 }
7263 if (axes & SLOT) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007264 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
7265 mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007266 }
7267 if (axes & TOOL_TYPE) {
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08007268 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007269 }
7270}
7271
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007272void MultiTouchInputMapperTest::processPosition(MultiTouchInputMapper& mapper, int32_t x,
7273 int32_t y) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007274 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_X, x);
7275 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007276}
7277
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007278void MultiTouchInputMapperTest::processTouchMajor(MultiTouchInputMapper& mapper,
7279 int32_t touchMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007280 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007281}
7282
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007283void MultiTouchInputMapperTest::processTouchMinor(MultiTouchInputMapper& mapper,
7284 int32_t touchMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007285 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007286}
7287
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007288void MultiTouchInputMapperTest::processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007289 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007290}
7291
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007292void MultiTouchInputMapperTest::processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007293 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007294}
7295
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007296void MultiTouchInputMapperTest::processOrientation(MultiTouchInputMapper& mapper,
7297 int32_t orientation) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007298 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_ORIENTATION, orientation);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007299}
7300
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007301void MultiTouchInputMapperTest::processPressure(MultiTouchInputMapper& mapper, int32_t pressure) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007302 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_PRESSURE, pressure);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007303}
7304
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007305void MultiTouchInputMapperTest::processDistance(MultiTouchInputMapper& mapper, int32_t distance) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007306 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_DISTANCE, distance);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007307}
7308
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007309void MultiTouchInputMapperTest::processId(MultiTouchInputMapper& mapper, int32_t id) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007310 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TRACKING_ID, id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007311}
7312
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007313void MultiTouchInputMapperTest::processSlot(MultiTouchInputMapper& mapper, int32_t slot) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007314 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_SLOT, slot);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007315}
7316
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007317void MultiTouchInputMapperTest::processToolType(MultiTouchInputMapper& mapper, int32_t toolType) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007318 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007319}
7320
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007321void MultiTouchInputMapperTest::processKey(MultiTouchInputMapper& mapper, int32_t code,
7322 int32_t value) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007323 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007324}
7325
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00007326void MultiTouchInputMapperTest::processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode,
7327 int32_t value) {
7328 process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, usageCode);
7329 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, value);
7330}
7331
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007332void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper& mapper) {
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00007333 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_MT_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007334}
7335
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +00007336void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime,
7337 nsecs_t readTime) {
7338 process(mapper, eventTime, readTime, EV_SYN, SYN_REPORT, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007339}
7340
Michael Wrightd02c5b62014-02-10 15:10:22 -08007341TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007342 addConfigurationProperty("touch.deviceType", "touchScreen");
7343 prepareDisplay(DISPLAY_ORIENTATION_0);
7344 prepareAxes(POSITION);
7345 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007346 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007347
arthurhungdcef2dc2020-08-11 14:47:50 +08007348 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007349
7350 NotifyMotionArgs motionArgs;
7351
7352 // Two fingers down at once.
7353 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
7354 processPosition(mapper, x1, y1);
7355 processMTSync(mapper);
7356 processPosition(mapper, x2, y2);
7357 processMTSync(mapper);
7358 processSync(mapper);
7359
7360 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7361 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7362 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7363 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7364 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7365 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7366 ASSERT_EQ(0, motionArgs.flags);
7367 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7368 ASSERT_EQ(0, motionArgs.buttonState);
7369 ASSERT_EQ(0, motionArgs.edgeFlags);
7370 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7371 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7372 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7373 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7374 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7375 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7376 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7377 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7378
7379 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7380 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7381 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7382 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7383 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007384 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007385 ASSERT_EQ(0, motionArgs.flags);
7386 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7387 ASSERT_EQ(0, motionArgs.buttonState);
7388 ASSERT_EQ(0, motionArgs.edgeFlags);
7389 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7390 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7391 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7392 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7393 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7394 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7395 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7396 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7397 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7398 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7399 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7400 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7401
7402 // Move.
7403 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
7404 processPosition(mapper, x1, y1);
7405 processMTSync(mapper);
7406 processPosition(mapper, x2, y2);
7407 processMTSync(mapper);
7408 processSync(mapper);
7409
7410 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7411 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7412 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7413 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7414 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7415 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7416 ASSERT_EQ(0, motionArgs.flags);
7417 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7418 ASSERT_EQ(0, motionArgs.buttonState);
7419 ASSERT_EQ(0, motionArgs.edgeFlags);
7420 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7421 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7422 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7423 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7424 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7425 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7426 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7427 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7428 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7429 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7430 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7431 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7432
7433 // First finger up.
7434 x2 += 15; y2 -= 20;
7435 processPosition(mapper, x2, y2);
7436 processMTSync(mapper);
7437 processSync(mapper);
7438
7439 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7440 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7441 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7442 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7443 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007444 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007445 ASSERT_EQ(0, motionArgs.flags);
7446 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7447 ASSERT_EQ(0, motionArgs.buttonState);
7448 ASSERT_EQ(0, motionArgs.edgeFlags);
7449 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7450 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7451 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7452 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7453 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7454 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7455 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7456 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7457 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7458 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7459 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7460 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7461
7462 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7463 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7464 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7465 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7466 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7467 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7468 ASSERT_EQ(0, motionArgs.flags);
7469 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7470 ASSERT_EQ(0, motionArgs.buttonState);
7471 ASSERT_EQ(0, motionArgs.edgeFlags);
7472 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7473 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7474 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7475 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7476 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7477 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7478 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7479 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7480
7481 // Move.
7482 x2 += 20; y2 -= 25;
7483 processPosition(mapper, x2, y2);
7484 processMTSync(mapper);
7485 processSync(mapper);
7486
7487 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7488 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7489 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7490 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7491 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7492 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7493 ASSERT_EQ(0, motionArgs.flags);
7494 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7495 ASSERT_EQ(0, motionArgs.buttonState);
7496 ASSERT_EQ(0, motionArgs.edgeFlags);
7497 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7498 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7499 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7500 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7501 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7502 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7503 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7504 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7505
7506 // New finger down.
7507 int32_t x3 = 700, y3 = 300;
7508 processPosition(mapper, x2, y2);
7509 processMTSync(mapper);
7510 processPosition(mapper, x3, y3);
7511 processMTSync(mapper);
7512 processSync(mapper);
7513
7514 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7515 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7516 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7517 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7518 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007519 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007520 ASSERT_EQ(0, motionArgs.flags);
7521 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7522 ASSERT_EQ(0, motionArgs.buttonState);
7523 ASSERT_EQ(0, motionArgs.edgeFlags);
7524 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7525 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7526 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7527 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7528 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7529 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7530 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7531 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7532 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7533 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7534 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7535 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7536
7537 // Second finger up.
7538 x3 += 30; y3 -= 20;
7539 processPosition(mapper, x3, y3);
7540 processMTSync(mapper);
7541 processSync(mapper);
7542
7543 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7544 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7545 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7546 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7547 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007548 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007549 ASSERT_EQ(0, motionArgs.flags);
7550 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7551 ASSERT_EQ(0, motionArgs.buttonState);
7552 ASSERT_EQ(0, motionArgs.edgeFlags);
7553 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7554 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7555 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7556 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7557 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7558 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7559 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7560 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7561 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7562 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7563 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7564 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7565
7566 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7567 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7568 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7569 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7570 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7571 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7572 ASSERT_EQ(0, motionArgs.flags);
7573 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7574 ASSERT_EQ(0, motionArgs.buttonState);
7575 ASSERT_EQ(0, motionArgs.edgeFlags);
7576 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7577 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7578 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7579 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7580 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7581 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7582 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7583 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7584
7585 // Last finger up.
7586 processMTSync(mapper);
7587 processSync(mapper);
7588
7589 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7590 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
7591 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
7592 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
7593 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
7594 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7595 ASSERT_EQ(0, motionArgs.flags);
7596 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
7597 ASSERT_EQ(0, motionArgs.buttonState);
7598 ASSERT_EQ(0, motionArgs.edgeFlags);
7599 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7600 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7601 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7602 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7603 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7604 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
7605 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
7606 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
7607
7608 // Should not have sent any more keys or motions.
7609 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7610 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7611}
7612
Siarhei Vishniakou12c0fcb2021-12-17 13:40:44 -08007613TEST_F(MultiTouchInputMapperTest, AxisResolution_IsPopulated) {
7614 addConfigurationProperty("touch.deviceType", "touchScreen");
7615 prepareDisplay(DISPLAY_ORIENTATION_0);
7616
7617 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
7618 /*fuzz*/ 0, /*resolution*/ 10);
7619 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
7620 /*fuzz*/ 0, /*resolution*/ 11);
7621 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
7622 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 12);
7623 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
7624 /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 13);
7625 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7626 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 14);
7627 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
7628 /*flat*/ 0, /*flat*/ 0, /*resolution*/ 15);
7629
7630 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
7631
7632 // X and Y axes
7633 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_X, 10 / X_PRECISION);
7634 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_Y, 11 / Y_PRECISION);
7635 // Touch major and minor
7636 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR, 12 * GEOMETRIC_SCALE);
7637 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR, 13 * GEOMETRIC_SCALE);
7638 // Tool major and minor
7639 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR, 14 * GEOMETRIC_SCALE);
7640 assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR, 15 * GEOMETRIC_SCALE);
7641}
7642
7643TEST_F(MultiTouchInputMapperTest, TouchMajorAndMinorAxes_DoNotAppearIfNotSupported) {
7644 addConfigurationProperty("touch.deviceType", "touchScreen");
7645 prepareDisplay(DISPLAY_ORIENTATION_0);
7646
7647 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
7648 /*fuzz*/ 0, /*resolution*/ 10);
7649 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
7650 /*fuzz*/ 0, /*resolution*/ 11);
7651
7652 // We do not add ABS_MT_TOUCH_MAJOR / MINOR or ABS_MT_WIDTH_MAJOR / MINOR axes
7653
7654 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
7655
7656 // Touch major and minor
7657 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR);
7658 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR);
7659 // Tool major and minor
7660 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR);
7661 assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR);
7662}
7663
Michael Wrightd02c5b62014-02-10 15:10:22 -08007664TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007665 addConfigurationProperty("touch.deviceType", "touchScreen");
7666 prepareDisplay(DISPLAY_ORIENTATION_0);
7667 prepareAxes(POSITION | ID);
7668 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007669 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007670
arthurhungdcef2dc2020-08-11 14:47:50 +08007671 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007672
7673 NotifyMotionArgs motionArgs;
7674
7675 // Two fingers down at once.
7676 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
7677 processPosition(mapper, x1, y1);
7678 processId(mapper, 1);
7679 processMTSync(mapper);
7680 processPosition(mapper, x2, y2);
7681 processId(mapper, 2);
7682 processMTSync(mapper);
7683 processSync(mapper);
7684
7685 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7686 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7687 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7688 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7689 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7690 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7691 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7692
7693 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007694 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007695 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7696 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7697 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7698 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7699 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7700 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7701 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7702 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7703 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7704
7705 // Move.
7706 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
7707 processPosition(mapper, x1, y1);
7708 processId(mapper, 1);
7709 processMTSync(mapper);
7710 processPosition(mapper, x2, y2);
7711 processId(mapper, 2);
7712 processMTSync(mapper);
7713 processSync(mapper);
7714
7715 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7716 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7717 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7718 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7719 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7720 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7721 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7722 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7723 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7724 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7725 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7726
7727 // First finger up.
7728 x2 += 15; y2 -= 20;
7729 processPosition(mapper, x2, y2);
7730 processId(mapper, 2);
7731 processMTSync(mapper);
7732 processSync(mapper);
7733
7734 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007735 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007736 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7737 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7738 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7739 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7740 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7741 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7742 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7743 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7744 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7745
7746 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7747 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7748 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7749 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7750 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7751 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7752 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7753
7754 // Move.
7755 x2 += 20; y2 -= 25;
7756 processPosition(mapper, x2, y2);
7757 processId(mapper, 2);
7758 processMTSync(mapper);
7759 processSync(mapper);
7760
7761 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7762 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7763 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7764 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7765 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7766 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7767 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7768
7769 // New finger down.
7770 int32_t x3 = 700, y3 = 300;
7771 processPosition(mapper, x2, y2);
7772 processId(mapper, 2);
7773 processMTSync(mapper);
7774 processPosition(mapper, x3, y3);
7775 processId(mapper, 3);
7776 processMTSync(mapper);
7777 processSync(mapper);
7778
7779 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007780 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007781 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7782 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7783 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7784 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7785 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7786 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7787 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7788 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7789 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7790
7791 // Second finger up.
7792 x3 += 30; y3 -= 20;
7793 processPosition(mapper, x3, y3);
7794 processId(mapper, 3);
7795 processMTSync(mapper);
7796 processSync(mapper);
7797
7798 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007799 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007800 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7801 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7802 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7803 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7804 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7805 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7806 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7807 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7808 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7809
7810 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7811 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7812 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7813 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7814 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7815 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7816 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7817
7818 // Last finger up.
7819 processMTSync(mapper);
7820 processSync(mapper);
7821
7822 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7823 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7824 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7825 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7826 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7827 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7828 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7829
7830 // Should not have sent any more keys or motions.
7831 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7832 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7833}
7834
7835TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08007836 addConfigurationProperty("touch.deviceType", "touchScreen");
7837 prepareDisplay(DISPLAY_ORIENTATION_0);
7838 prepareAxes(POSITION | ID | SLOT);
7839 prepareVirtualKeys();
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08007840 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08007841
arthurhungdcef2dc2020-08-11 14:47:50 +08007842 mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007843
7844 NotifyMotionArgs motionArgs;
7845
7846 // Two fingers down at once.
7847 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
7848 processPosition(mapper, x1, y1);
7849 processId(mapper, 1);
7850 processSlot(mapper, 1);
7851 processPosition(mapper, x2, y2);
7852 processId(mapper, 2);
7853 processSync(mapper);
7854
7855 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7856 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7857 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7858 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7859 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7860 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7861 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7862
7863 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007864 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007865 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7866 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7867 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7868 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7869 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7870 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7871 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7872 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7873 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7874
7875 // Move.
7876 x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
7877 processSlot(mapper, 0);
7878 processPosition(mapper, x1, y1);
7879 processSlot(mapper, 1);
7880 processPosition(mapper, x2, y2);
7881 processSync(mapper);
7882
7883 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7884 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7885 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7886 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7887 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7888 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7889 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7890 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7891 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7892 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7893 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7894
7895 // First finger up.
7896 x2 += 15; y2 -= 20;
7897 processSlot(mapper, 0);
7898 processId(mapper, -1);
7899 processSlot(mapper, 1);
7900 processPosition(mapper, x2, y2);
7901 processSync(mapper);
7902
7903 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007904 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007905 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7906 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7907 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7908 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7909 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7910 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7911 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
7912 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7913 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7914
7915 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7916 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7917 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7918 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7919 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7920 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7921 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7922
7923 // Move.
7924 x2 += 20; y2 -= 25;
7925 processPosition(mapper, x2, y2);
7926 processSync(mapper);
7927
7928 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7929 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7930 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7931 ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
7932 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7933 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7934 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7935
7936 // New finger down.
7937 int32_t x3 = 700, y3 = 300;
7938 processPosition(mapper, x2, y2);
7939 processSlot(mapper, 0);
7940 processId(mapper, 3);
7941 processPosition(mapper, x3, y3);
7942 processSync(mapper);
7943
7944 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007945 ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007946 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7947 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7948 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7949 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7950 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7951 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7952 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7953 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7954 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7955
7956 // Second finger up.
7957 x3 += 30; y3 -= 20;
7958 processSlot(mapper, 1);
7959 processId(mapper, -1);
7960 processSlot(mapper, 0);
7961 processPosition(mapper, x3, y3);
7962 processSync(mapper);
7963
7964 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08007965 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08007966 ASSERT_EQ(size_t(2), motionArgs.pointerCount);
7967 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7968 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7969 ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
7970 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
7971 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7972 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7973 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
7974 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
7975
7976 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7977 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7978 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7979 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7980 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7981 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7982 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7983
7984 // Last finger up.
7985 processId(mapper, -1);
7986 processSync(mapper);
7987
7988 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7989 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7990 ASSERT_EQ(size_t(1), motionArgs.pointerCount);
7991 ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
7992 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
7993 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7994 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
7995
7996 // Should not have sent any more keys or motions.
7997 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7998 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7999}
8000
8001TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008002 addConfigurationProperty("touch.deviceType", "touchScreen");
8003 prepareDisplay(DISPLAY_ORIENTATION_0);
8004 prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008005 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008006
8007 // These calculations are based on the input device calibration documentation.
8008 int32_t rawX = 100;
8009 int32_t rawY = 200;
8010 int32_t rawTouchMajor = 7;
8011 int32_t rawTouchMinor = 6;
8012 int32_t rawToolMajor = 9;
8013 int32_t rawToolMinor = 8;
8014 int32_t rawPressure = 11;
8015 int32_t rawDistance = 0;
8016 int32_t rawOrientation = 3;
8017 int32_t id = 5;
8018
8019 float x = toDisplayX(rawX);
8020 float y = toDisplayY(rawY);
8021 float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
8022 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
8023 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
8024 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
8025 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
8026 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
8027 float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
8028 float distance = float(rawDistance);
8029
8030 processPosition(mapper, rawX, rawY);
8031 processTouchMajor(mapper, rawTouchMajor);
8032 processTouchMinor(mapper, rawTouchMinor);
8033 processToolMajor(mapper, rawToolMajor);
8034 processToolMinor(mapper, rawToolMinor);
8035 processPressure(mapper, rawPressure);
8036 processOrientation(mapper, rawOrientation);
8037 processDistance(mapper, rawDistance);
8038 processId(mapper, id);
8039 processMTSync(mapper);
8040 processSync(mapper);
8041
8042 NotifyMotionArgs args;
8043 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8044 ASSERT_EQ(0, args.pointerProperties[0].id);
8045 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8046 x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor,
8047 orientation, distance));
8048}
8049
8050TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008051 addConfigurationProperty("touch.deviceType", "touchScreen");
8052 prepareDisplay(DISPLAY_ORIENTATION_0);
8053 prepareAxes(POSITION | TOUCH | TOOL | MINOR);
8054 addConfigurationProperty("touch.size.calibration", "geometric");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008055 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008056
8057 // These calculations are based on the input device calibration documentation.
8058 int32_t rawX = 100;
8059 int32_t rawY = 200;
8060 int32_t rawTouchMajor = 140;
8061 int32_t rawTouchMinor = 120;
8062 int32_t rawToolMajor = 180;
8063 int32_t rawToolMinor = 160;
8064
8065 float x = toDisplayX(rawX);
8066 float y = toDisplayY(rawY);
8067 float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
8068 float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
8069 float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
8070 float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
8071 float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
8072
8073 processPosition(mapper, rawX, rawY);
8074 processTouchMajor(mapper, rawTouchMajor);
8075 processTouchMinor(mapper, rawTouchMinor);
8076 processToolMajor(mapper, rawToolMajor);
8077 processToolMinor(mapper, rawToolMinor);
8078 processMTSync(mapper);
8079 processSync(mapper);
8080
8081 NotifyMotionArgs args;
8082 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8083 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8084 x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
8085}
8086
8087TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008088 addConfigurationProperty("touch.deviceType", "touchScreen");
8089 prepareDisplay(DISPLAY_ORIENTATION_0);
8090 prepareAxes(POSITION | TOUCH | TOOL);
8091 addConfigurationProperty("touch.size.calibration", "diameter");
8092 addConfigurationProperty("touch.size.scale", "10");
8093 addConfigurationProperty("touch.size.bias", "160");
8094 addConfigurationProperty("touch.size.isSummed", "1");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008095 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008096
8097 // These calculations are based on the input device calibration documentation.
8098 // Note: We only provide a single common touch/tool value because the device is assumed
8099 // not to emit separate values for each pointer (isSummed = 1).
8100 int32_t rawX = 100;
8101 int32_t rawY = 200;
8102 int32_t rawX2 = 150;
8103 int32_t rawY2 = 250;
8104 int32_t rawTouchMajor = 5;
8105 int32_t rawToolMajor = 8;
8106
8107 float x = toDisplayX(rawX);
8108 float y = toDisplayY(rawY);
8109 float x2 = toDisplayX(rawX2);
8110 float y2 = toDisplayY(rawY2);
8111 float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX;
8112 float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f;
8113 float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f;
8114
8115 processPosition(mapper, rawX, rawY);
8116 processTouchMajor(mapper, rawTouchMajor);
8117 processToolMajor(mapper, rawToolMajor);
8118 processMTSync(mapper);
8119 processPosition(mapper, rawX2, rawY2);
8120 processTouchMajor(mapper, rawTouchMajor);
8121 processToolMajor(mapper, rawToolMajor);
8122 processMTSync(mapper);
8123 processSync(mapper);
8124
8125 NotifyMotionArgs args;
8126 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8127 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
8128
8129 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08008130 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008131 ASSERT_EQ(size_t(2), args.pointerCount);
8132 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8133 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
8134 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
8135 x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0));
8136}
8137
8138TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008139 addConfigurationProperty("touch.deviceType", "touchScreen");
8140 prepareDisplay(DISPLAY_ORIENTATION_0);
8141 prepareAxes(POSITION | TOUCH | TOOL);
8142 addConfigurationProperty("touch.size.calibration", "area");
8143 addConfigurationProperty("touch.size.scale", "43");
8144 addConfigurationProperty("touch.size.bias", "3");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008145 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008146
8147 // These calculations are based on the input device calibration documentation.
8148 int32_t rawX = 100;
8149 int32_t rawY = 200;
8150 int32_t rawTouchMajor = 5;
8151 int32_t rawToolMajor = 8;
8152
8153 float x = toDisplayX(rawX);
8154 float y = toDisplayY(rawY);
8155 float size = float(rawTouchMajor) / RAW_TOUCH_MAX;
8156 float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f;
8157 float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f;
8158
8159 processPosition(mapper, rawX, rawY);
8160 processTouchMajor(mapper, rawTouchMajor);
8161 processToolMajor(mapper, rawToolMajor);
8162 processMTSync(mapper);
8163 processSync(mapper);
8164
8165 NotifyMotionArgs args;
8166 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8167 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8168 x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
8169}
8170
8171TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008172 addConfigurationProperty("touch.deviceType", "touchScreen");
8173 prepareDisplay(DISPLAY_ORIENTATION_0);
8174 prepareAxes(POSITION | PRESSURE);
8175 addConfigurationProperty("touch.pressure.calibration", "amplitude");
8176 addConfigurationProperty("touch.pressure.scale", "0.01");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008177 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008178
Michael Wrightaa449c92017-12-13 21:21:43 +00008179 InputDeviceInfo info;
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008180 mapper.populateDeviceInfo(&info);
Michael Wrightaa449c92017-12-13 21:21:43 +00008181 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
8182 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TOUCHSCREEN,
8183 0.0f, RAW_PRESSURE_MAX * 0.01, 0.0f, 0.0f));
8184
Michael Wrightd02c5b62014-02-10 15:10:22 -08008185 // These calculations are based on the input device calibration documentation.
8186 int32_t rawX = 100;
8187 int32_t rawY = 200;
8188 int32_t rawPressure = 60;
8189
8190 float x = toDisplayX(rawX);
8191 float y = toDisplayY(rawY);
8192 float pressure = float(rawPressure) * 0.01f;
8193
8194 processPosition(mapper, rawX, rawY);
8195 processPressure(mapper, rawPressure);
8196 processMTSync(mapper);
8197 processSync(mapper);
8198
8199 NotifyMotionArgs args;
8200 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8201 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
8202 x, y, pressure, 0, 0, 0, 0, 0, 0, 0));
8203}
8204
8205TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008206 addConfigurationProperty("touch.deviceType", "touchScreen");
8207 prepareDisplay(DISPLAY_ORIENTATION_0);
8208 prepareAxes(POSITION | ID | SLOT);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008209 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008210
8211 NotifyMotionArgs motionArgs;
8212 NotifyKeyArgs keyArgs;
8213
8214 processId(mapper, 1);
8215 processPosition(mapper, 100, 200);
8216 processSync(mapper);
8217 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8218 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8219 ASSERT_EQ(0, motionArgs.buttonState);
8220
8221 // press BTN_LEFT, release BTN_LEFT
8222 processKey(mapper, BTN_LEFT, 1);
8223 processSync(mapper);
8224 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8225 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8226 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
8227
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008228 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8229 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8230 ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
8231
Michael Wrightd02c5b62014-02-10 15:10:22 -08008232 processKey(mapper, BTN_LEFT, 0);
8233 processSync(mapper);
8234 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008235 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008236 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008237
8238 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008239 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008240 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008241
8242 // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
8243 processKey(mapper, BTN_RIGHT, 1);
8244 processKey(mapper, BTN_MIDDLE, 1);
8245 processSync(mapper);
8246 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8247 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8248 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
8249 motionArgs.buttonState);
8250
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008251 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8252 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8253 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
8254
8255 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8256 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8257 ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
8258 motionArgs.buttonState);
8259
Michael Wrightd02c5b62014-02-10 15:10:22 -08008260 processKey(mapper, BTN_RIGHT, 0);
8261 processSync(mapper);
8262 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008263 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008264 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008265
8266 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008267 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008268 ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008269
8270 processKey(mapper, BTN_MIDDLE, 0);
8271 processSync(mapper);
8272 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008273 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008274 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008275
8276 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008277 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008278 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008279
8280 // press BTN_BACK, release BTN_BACK
8281 processKey(mapper, BTN_BACK, 1);
8282 processSync(mapper);
8283 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8284 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8285 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008286
Michael Wrightd02c5b62014-02-10 15:10:22 -08008287 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008288 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008289 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
8290
8291 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8292 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8293 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008294
8295 processKey(mapper, BTN_BACK, 0);
8296 processSync(mapper);
8297 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008298 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008299 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008300
8301 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008302 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008303 ASSERT_EQ(0, motionArgs.buttonState);
8304
Michael Wrightd02c5b62014-02-10 15:10:22 -08008305 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8306 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8307 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
8308
8309 // press BTN_SIDE, release BTN_SIDE
8310 processKey(mapper, BTN_SIDE, 1);
8311 processSync(mapper);
8312 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8313 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8314 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008315
Michael Wrightd02c5b62014-02-10 15:10:22 -08008316 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008317 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008318 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
8319
8320 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8321 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8322 ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008323
8324 processKey(mapper, BTN_SIDE, 0);
8325 processSync(mapper);
8326 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008327 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008328 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008329
8330 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008331 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008332 ASSERT_EQ(0, motionArgs.buttonState);
8333
Michael Wrightd02c5b62014-02-10 15:10:22 -08008334 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8335 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8336 ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
8337
8338 // press BTN_FORWARD, release BTN_FORWARD
8339 processKey(mapper, BTN_FORWARD, 1);
8340 processSync(mapper);
8341 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8342 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8343 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008344
Michael Wrightd02c5b62014-02-10 15:10:22 -08008345 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008346 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008347 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
8348
8349 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8350 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8351 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008352
8353 processKey(mapper, BTN_FORWARD, 0);
8354 processSync(mapper);
8355 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008356 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008357 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008358
8359 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008360 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008361 ASSERT_EQ(0, motionArgs.buttonState);
8362
Michael Wrightd02c5b62014-02-10 15:10:22 -08008363 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8364 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8365 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
8366
8367 // press BTN_EXTRA, release BTN_EXTRA
8368 processKey(mapper, BTN_EXTRA, 1);
8369 processSync(mapper);
8370 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8371 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
8372 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008373
Michael Wrightd02c5b62014-02-10 15:10:22 -08008374 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008375 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008376 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
8377
8378 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8379 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8380 ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008381
8382 processKey(mapper, BTN_EXTRA, 0);
8383 processSync(mapper);
8384 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008385 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008386 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008387
8388 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008389 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008390 ASSERT_EQ(0, motionArgs.buttonState);
8391
Michael Wrightd02c5b62014-02-10 15:10:22 -08008392 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
8393 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
8394 ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
8395
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008396 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
8397
Michael Wrightd02c5b62014-02-10 15:10:22 -08008398 // press BTN_STYLUS, release BTN_STYLUS
8399 processKey(mapper, BTN_STYLUS, 1);
8400 processSync(mapper);
8401 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8402 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008403 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
8404
8405 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8406 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8407 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008408
8409 processKey(mapper, BTN_STYLUS, 0);
8410 processSync(mapper);
8411 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008412 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008413 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008414
8415 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008416 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008417 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008418
8419 // press BTN_STYLUS2, release BTN_STYLUS2
8420 processKey(mapper, BTN_STYLUS2, 1);
8421 processSync(mapper);
8422 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8423 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008424 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
8425
8426 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8427 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
8428 ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008429
8430 processKey(mapper, BTN_STYLUS2, 0);
8431 processSync(mapper);
8432 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008433 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008434 ASSERT_EQ(0, motionArgs.buttonState);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008435
8436 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Michael Wrightd02c5b62014-02-10 15:10:22 -08008437 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
Vladislav Kaznacheevfb752582016-12-16 14:17:06 -08008438 ASSERT_EQ(0, motionArgs.buttonState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08008439
8440 // release touch
8441 processId(mapper, -1);
8442 processSync(mapper);
8443 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8444 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8445 ASSERT_EQ(0, motionArgs.buttonState);
8446}
8447
Prabir Pradhan4f05b5f2022-10-11 21:24:07 +00008448TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleMappedStylusButtons) {
8449 addConfigurationProperty("touch.deviceType", "touchScreen");
8450 prepareDisplay(DISPLAY_ORIENTATION_0);
8451 prepareAxes(POSITION | ID | SLOT);
8452 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8453
8454 mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_STYLUS_BUTTON_PRIMARY, 0);
8455 mFakeEventHub->addKey(EVENTHUB_ID, 0, 0xabcd, AKEYCODE_STYLUS_BUTTON_SECONDARY, 0);
8456
8457 // Touch down.
8458 processId(mapper, 1);
8459 processPosition(mapper, 100, 200);
8460 processSync(mapper);
8461 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8462 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));
8463
8464 // Press and release button mapped to the primary stylus button.
8465 processKey(mapper, BTN_A, 1);
8466 processSync(mapper);
8467 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8468 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8469 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
8470 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8471 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
8472 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
8473
8474 processKey(mapper, BTN_A, 0);
8475 processSync(mapper);
8476 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8477 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
8478 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8479 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
8480
8481 // Press and release the HID usage mapped to the secondary stylus button.
8482 processHidUsage(mapper, 0xabcd, 1);
8483 processSync(mapper);
8484 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8485 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8486 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
8487 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8488 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
8489 WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
8490
8491 processHidUsage(mapper, 0xabcd, 0);
8492 processSync(mapper);
8493 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8494 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
8495 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8496 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
8497
8498 // Release touch.
8499 processId(mapper, -1);
8500 processSync(mapper);
8501 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8502 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
8503}
8504
Michael Wrightd02c5b62014-02-10 15:10:22 -08008505TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008506 addConfigurationProperty("touch.deviceType", "touchScreen");
8507 prepareDisplay(DISPLAY_ORIENTATION_0);
8508 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008509 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008510
8511 NotifyMotionArgs motionArgs;
8512
8513 // default tool type is finger
8514 processId(mapper, 1);
8515 processPosition(mapper, 100, 200);
8516 processSync(mapper);
8517 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8518 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8519 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8520
8521 // eraser
8522 processKey(mapper, BTN_TOOL_RUBBER, 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_ERASER, motionArgs.pointerProperties[0].toolType);
8527
8528 // stylus
8529 processKey(mapper, BTN_TOOL_RUBBER, 0);
8530 processKey(mapper, BTN_TOOL_PEN, 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 // brush
8537 processKey(mapper, BTN_TOOL_PEN, 0);
8538 processKey(mapper, BTN_TOOL_BRUSH, 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
8544 // pencil
8545 processKey(mapper, BTN_TOOL_BRUSH, 0);
8546 processKey(mapper, BTN_TOOL_PENCIL, 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
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08008552 // air-brush
Michael Wrightd02c5b62014-02-10 15:10:22 -08008553 processKey(mapper, BTN_TOOL_PENCIL, 0);
8554 processKey(mapper, BTN_TOOL_AIRBRUSH, 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_STYLUS, motionArgs.pointerProperties[0].toolType);
8559
8560 // mouse
8561 processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
8562 processKey(mapper, BTN_TOOL_MOUSE, 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 // lens
8569 processKey(mapper, BTN_TOOL_MOUSE, 0);
8570 processKey(mapper, BTN_TOOL_LENS, 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_MOUSE, motionArgs.pointerProperties[0].toolType);
8575
8576 // double-tap
8577 processKey(mapper, BTN_TOOL_LENS, 0);
8578 processKey(mapper, BTN_TOOL_DOUBLETAP, 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 // triple-tap
8585 processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
8586 processKey(mapper, BTN_TOOL_TRIPLETAP, 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 // quad-tap
8593 processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
8594 processKey(mapper, BTN_TOOL_QUADTAP, 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 // finger
8601 processKey(mapper, BTN_TOOL_QUADTAP, 0);
8602 processKey(mapper, BTN_TOOL_FINGER, 1);
8603 processSync(mapper);
8604 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8605 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8606 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8607
8608 // stylus trumps finger
8609 processKey(mapper, BTN_TOOL_PEN, 1);
8610 processSync(mapper);
8611 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8612 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8613 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8614
8615 // eraser trumps stylus
8616 processKey(mapper, BTN_TOOL_RUBBER, 1);
8617 processSync(mapper);
8618 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8619 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8620 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
8621
8622 // mouse trumps eraser
8623 processKey(mapper, BTN_TOOL_MOUSE, 1);
8624 processSync(mapper);
8625 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8626 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8627 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
8628
8629 // MT tool type trumps BTN tool types: MT_TOOL_FINGER
8630 processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
8631 processSync(mapper);
8632 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8633 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8634 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8635
8636 // MT tool type trumps BTN tool types: MT_TOOL_PEN
8637 processToolType(mapper, MT_TOOL_PEN);
8638 processSync(mapper);
8639 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8640 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8641 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
8642
8643 // back to default tool type
8644 processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
8645 processKey(mapper, BTN_TOOL_MOUSE, 0);
8646 processKey(mapper, BTN_TOOL_RUBBER, 0);
8647 processKey(mapper, BTN_TOOL_PEN, 0);
8648 processKey(mapper, BTN_TOOL_FINGER, 0);
8649 processSync(mapper);
8650 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8651 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8652 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
8653}
8654
8655TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008656 addConfigurationProperty("touch.deviceType", "touchScreen");
8657 prepareDisplay(DISPLAY_ORIENTATION_0);
8658 prepareAxes(POSITION | ID | SLOT);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08008659 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008660 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008661
8662 NotifyMotionArgs motionArgs;
8663
8664 // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
8665 processId(mapper, 1);
8666 processPosition(mapper, 100, 200);
8667 processSync(mapper);
8668 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8669 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8670 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8671 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8672
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(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8677
8678 // move a little
8679 processPosition(mapper, 150, 250);
8680 processSync(mapper);
8681 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8682 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, 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 // down when BTN_TOUCH is pressed, pressure defaults to 1
8687 processKey(mapper, BTN_TOUCH, 1);
8688 processSync(mapper);
8689 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8690 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8691 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8692 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8693
8694 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8695 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, 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 // up when BTN_TOUCH is released, hover restored
8700 processKey(mapper, BTN_TOUCH, 0);
8701 processSync(mapper);
8702 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8703 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8704 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8705 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8706
8707 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8708 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8709 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8710 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8711
8712 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8713 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, 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 // exit hover when pointer goes away
8718 processId(mapper, -1);
8719 processSync(mapper);
8720 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8721 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8722 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8723 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8724}
8725
8726TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08008727 addConfigurationProperty("touch.deviceType", "touchScreen");
8728 prepareDisplay(DISPLAY_ORIENTATION_0);
8729 prepareAxes(POSITION | ID | SLOT | PRESSURE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008730 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Michael Wrightd02c5b62014-02-10 15:10:22 -08008731
8732 NotifyMotionArgs motionArgs;
8733
8734 // initially hovering because pressure is 0
8735 processId(mapper, 1);
8736 processPosition(mapper, 100, 200);
8737 processPressure(mapper, 0);
8738 processSync(mapper);
8739 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8740 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8741 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8742 toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8743
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(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
8748
8749 // move a little
8750 processPosition(mapper, 150, 250);
8751 processSync(mapper);
8752 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8753 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, 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 // down when pressure becomes non-zero
8758 processPressure(mapper, RAW_PRESSURE_MAX);
8759 processSync(mapper);
8760 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8761 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8762 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8763 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8764
8765 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8766 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, 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 // up when pressure becomes 0, hover restored
8771 processPressure(mapper, 0);
8772 processSync(mapper);
8773 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8774 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8775 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8776 toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
8777
8778 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8779 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
8780 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8781 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8782
8783 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8784 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, 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 // exit hover when pointer goes away
8789 processId(mapper, -1);
8790 processSync(mapper);
8791 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8792 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
8793 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
8794 toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
8795}
8796
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008797/**
8798 * Set the input device port <--> display port associations, and check that the
8799 * events are routed to the display that matches the display port.
8800 * This can be checked by looking at the displayId of the resulting NotifyMotionArgs.
8801 */
8802TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) {
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008803 const std::string usb2 = "USB2";
8804 const uint8_t hdmi1 = 0;
8805 const uint8_t hdmi2 = 1;
8806 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +01008807 constexpr ViewportType type = ViewportType::EXTERNAL;
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008808
8809 addConfigurationProperty("touch.deviceType", "touchScreen");
8810 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008811 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8158e7e2018-10-15 14:28:20 -07008812
8813 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
8814 mFakePolicy->addInputPortAssociation(usb2, hdmi2);
8815
8816 // We are intentionally not adding the viewport for display 1 yet. Since the port association
8817 // for this input device is specified, and the matching viewport is not present,
8818 // the input device should be disabled (at the mapper level).
8819
8820 // Add viewport for display 2 on hdmi2
8821 prepareSecondaryDisplay(type, hdmi2);
8822 // Send a touch event
8823 processPosition(mapper, 100, 100);
8824 processSync(mapper);
8825 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8826
8827 // Add viewport for display 1 on hdmi1
8828 prepareDisplay(DISPLAY_ORIENTATION_0, hdmi1);
8829 // Send a touch event again
8830 processPosition(mapper, 100, 100);
8831 processSync(mapper);
8832
8833 NotifyMotionArgs args;
8834 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8835 ASSERT_EQ(DISPLAY_ID, args.displayId);
8836}
Michael Wrightd02c5b62014-02-10 15:10:22 -08008837
Arthur Hung6d5b4b22022-01-21 07:21:10 +00008838TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayUniqueId) {
8839 addConfigurationProperty("touch.deviceType", "touchScreen");
8840 prepareAxes(POSITION);
8841 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8842
8843 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
8844
8845 prepareDisplay(DISPLAY_ORIENTATION_0);
8846 prepareVirtualDisplay(DISPLAY_ORIENTATION_0);
8847
8848 // Send a touch event
8849 processPosition(mapper, 100, 100);
8850 processSync(mapper);
8851
8852 NotifyMotionArgs args;
8853 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8854 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
8855}
8856
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008857TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
Garfield Tan888a6a42020-01-09 11:39:16 -08008858 // Setup for second display.
Michael Wright17db18e2020-06-26 20:51:44 +01008859 std::shared_ptr<FakePointerController> fakePointerController =
8860 std::make_shared<FakePointerController>();
Garfield Tan888a6a42020-01-09 11:39:16 -08008861 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008862 fakePointerController->setPosition(100, 200);
8863 fakePointerController->setButtonState(0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00008864 mFakePolicy->setPointerController(fakePointerController);
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008865
Garfield Tan888a6a42020-01-09 11:39:16 -08008866 mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01008867 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Garfield Tan888a6a42020-01-09 11:39:16 -08008868
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008869 prepareDisplay(DISPLAY_ORIENTATION_0);
8870 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08008871 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008872
Harry Cutts16a24cc2022-10-26 15:22:19 +00008873 // Check source is a touchpad that would obtain the PointerController.
8874 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Arthur Hungc7ad2d02018-12-18 17:41:29 +08008875
8876 NotifyMotionArgs motionArgs;
8877 processPosition(mapper, 100, 100);
8878 processSync(mapper);
8879
8880 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8881 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
8882 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
8883}
8884
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00008885/**
Siarhei Vishniakou58ba3d12021-02-11 01:31:07 +00008886 * Ensure that the readTime is set to the SYN_REPORT value when processing touch events.
8887 */
8888TEST_F(MultiTouchInputMapperTest, Process_SendsReadTime) {
8889 addConfigurationProperty("touch.deviceType", "touchScreen");
8890 prepareAxes(POSITION);
8891 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8892
8893 prepareDisplay(DISPLAY_ORIENTATION_0);
8894 process(mapper, 10, 11 /*readTime*/, EV_ABS, ABS_MT_TRACKING_ID, 1);
8895 process(mapper, 15, 16 /*readTime*/, EV_ABS, ABS_MT_POSITION_X, 100);
8896 process(mapper, 20, 21 /*readTime*/, EV_ABS, ABS_MT_POSITION_Y, 100);
8897 process(mapper, 25, 26 /*readTime*/, EV_SYN, SYN_REPORT, 0);
8898
8899 NotifyMotionArgs args;
8900 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8901 ASSERT_EQ(26, args.readTime);
8902
8903 process(mapper, 30, 31 /*readTime*/, EV_ABS, ABS_MT_POSITION_X, 110);
8904 process(mapper, 30, 32 /*readTime*/, EV_ABS, ABS_MT_POSITION_Y, 220);
8905 process(mapper, 30, 33 /*readTime*/, EV_SYN, SYN_REPORT, 0);
8906
8907 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8908 ASSERT_EQ(33, args.readTime);
8909}
8910
8911/**
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00008912 * When the viewport is not active (isActive=false), the touch mapper should be disabled and the
8913 * events should not be delivered to the listener.
8914 */
8915TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) {
8916 addConfigurationProperty("touch.deviceType", "touchScreen");
Yuncheol Heo50c19b12022-11-02 20:33:08 -07008917 // Don't set touch.enableForInactiveViewport to verify the default behavior.
Siarhei Vishniakou6f778462020-12-09 23:39:07 +00008918 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
8919 DISPLAY_ORIENTATION_0, false /*isActive*/, UNIQUE_ID, NO_PORT,
8920 ViewportType::INTERNAL);
8921 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8922 prepareAxes(POSITION);
8923 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8924
8925 NotifyMotionArgs motionArgs;
8926 processPosition(mapper, 100, 100);
8927 processSync(mapper);
8928
8929 mFakeListener->assertNotifyMotionWasNotCalled();
8930}
8931
Yuncheol Heo50c19b12022-11-02 20:33:08 -07008932/**
8933 * When the viewport is not active (isActive=false) and touch.enableForInactiveViewport is true,
8934 * the touch mapper can process the events and the events can be delivered to the listener.
8935 */
8936TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreProcessed) {
8937 addConfigurationProperty("touch.deviceType", "touchScreen");
8938 addConfigurationProperty("touch.enableForInactiveViewport", "1");
8939 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
8940 DISPLAY_ORIENTATION_0, false /*isActive*/, UNIQUE_ID, NO_PORT,
8941 ViewportType::INTERNAL);
8942 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8943 prepareAxes(POSITION);
8944 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8945
8946 NotifyMotionArgs motionArgs;
8947 processPosition(mapper, 100, 100);
8948 processSync(mapper);
8949
8950 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8951 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8952}
8953
Garfield Tanc734e4f2021-01-15 20:01:39 -08008954TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) {
8955 addConfigurationProperty("touch.deviceType", "touchScreen");
Yuncheol Heo50c19b12022-11-02 20:33:08 -07008956 addConfigurationProperty("touch.enableForInactiveViewport", "0");
Garfield Tanc734e4f2021-01-15 20:01:39 -08008957 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
8958 DISPLAY_ORIENTATION_0, true /*isActive*/, UNIQUE_ID, NO_PORT,
8959 ViewportType::INTERNAL);
8960 std::optional<DisplayViewport> optionalDisplayViewport =
8961 mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
8962 ASSERT_TRUE(optionalDisplayViewport.has_value());
8963 DisplayViewport displayViewport = *optionalDisplayViewport;
8964
8965 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8966 prepareAxes(POSITION);
8967 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
8968
8969 // Finger down
8970 int32_t x = 100, y = 100;
8971 processPosition(mapper, x, y);
8972 processSync(mapper);
8973
8974 NotifyMotionArgs motionArgs;
8975 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8976 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8977
8978 // Deactivate display viewport
8979 displayViewport.isActive = false;
8980 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
8981 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8982
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00008983 // The ongoing touch should be canceled immediately
8984 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8985 EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
8986
8987 // Finger move is ignored
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->assertNotifyMotionWasNotCalled());
Garfield Tanc734e4f2021-01-15 20:01:39 -08008992
8993 // Reactivate display viewport
8994 displayViewport.isActive = true;
8995 ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
8996 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
8997
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00008998 // Finger move again starts new gesture
Garfield Tanc734e4f2021-01-15 20:01:39 -08008999 x += 10, y += 10;
9000 processPosition(mapper, x, y);
9001 processSync(mapper);
Prabir Pradhanc0bdeef2022-08-05 22:32:11 +00009002 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9003 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
Garfield Tanc734e4f2021-01-15 20:01:39 -08009004}
9005
Arthur Hung7c645402019-01-25 17:45:42 +08009006TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
9007 // Setup the first touch screen device.
Arthur Hung7c645402019-01-25 17:45:42 +08009008 prepareAxes(POSITION | ID | SLOT);
9009 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009010 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung7c645402019-01-25 17:45:42 +08009011
9012 // Create the second touch screen device, and enable multi fingers.
9013 const std::string USB2 = "USB2";
arthurhungdcef2dc2020-08-11 14:47:50 +08009014 const std::string DEVICE_NAME2 = "TOUCHSCREEN2";
Arthur Hung2c9a3342019-07-23 14:18:59 +08009015 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009016 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
arthurhungdcef2dc2020-08-11 14:47:50 +08009017 std::shared_ptr<InputDevice> device2 =
9018 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
Dominik Laskowski2f01d772022-03-23 16:01:29 -07009019 ftl::Flags<InputDeviceClass>(0));
arthurhungdcef2dc2020-08-11 14:47:50 +08009020
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009021 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
9022 0 /*flat*/, 0 /*fuzz*/);
9023 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
9024 0 /*flat*/, 0 /*fuzz*/);
9025 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
9026 0 /*flat*/, 0 /*fuzz*/);
9027 mFakeEventHub->addAbsoluteAxis(SECOND_EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
9028 0 /*flat*/, 0 /*fuzz*/);
9029 mFakeEventHub->setAbsoluteAxisValue(SECOND_EVENTHUB_ID, ABS_MT_SLOT, 0 /*value*/);
9030 mFakeEventHub->addConfigurationProperty(SECOND_EVENTHUB_ID, String8("touch.deviceType"),
9031 String8("touchScreen"));
Arthur Hung7c645402019-01-25 17:45:42 +08009032
9033 // Setup the second touch screen device.
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009034 MultiTouchInputMapper& mapper2 = device2->addMapper<MultiTouchInputMapper>(SECOND_EVENTHUB_ID);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009035 std::list<NotifyArgs> unused =
9036 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9037 0 /*changes*/);
9038 unused += device2->reset(ARBITRARY_TIME);
Arthur Hung7c645402019-01-25 17:45:42 +08009039
9040 // Setup PointerController.
Michael Wright17db18e2020-06-26 20:51:44 +01009041 std::shared_ptr<FakePointerController> fakePointerController =
9042 std::make_shared<FakePointerController>();
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009043 mFakePolicy->setPointerController(fakePointerController);
Arthur Hung7c645402019-01-25 17:45:42 +08009044
9045 // Setup policy for associated displays and show touches.
9046 const uint8_t hdmi1 = 0;
9047 const uint8_t hdmi2 = 1;
9048 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
9049 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
9050 mFakePolicy->setShowTouches(true);
9051
9052 // Create displays.
9053 prepareDisplay(DISPLAY_ORIENTATION_0, hdmi1);
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009054 prepareSecondaryDisplay(ViewportType::EXTERNAL, hdmi2);
Arthur Hung7c645402019-01-25 17:45:42 +08009055
9056 // Default device will reconfigure above, need additional reconfiguration for another device.
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009057 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9058 InputReaderConfiguration::CHANGE_DISPLAY_INFO |
9059 InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
Arthur Hung7c645402019-01-25 17:45:42 +08009060
9061 // Two fingers down at default display.
9062 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
9063 processPosition(mapper, x1, y1);
9064 processId(mapper, 1);
9065 processSlot(mapper, 1);
9066 processPosition(mapper, x2, y2);
9067 processId(mapper, 2);
9068 processSync(mapper);
9069
9070 std::map<int32_t, std::vector<int32_t>>::const_iterator iter =
9071 fakePointerController->getSpots().find(DISPLAY_ID);
9072 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
9073 ASSERT_EQ(size_t(2), iter->second.size());
9074
9075 // Two fingers down at second display.
9076 processPosition(mapper2, x1, y1);
9077 processId(mapper2, 1);
9078 processSlot(mapper2, 1);
9079 processPosition(mapper2, x2, y2);
9080 processId(mapper2, 2);
9081 processSync(mapper2);
9082
9083 iter = fakePointerController->getSpots().find(SECONDARY_DISPLAY_ID);
9084 ASSERT_TRUE(iter != fakePointerController->getSpots().end());
9085 ASSERT_EQ(size_t(2), iter->second.size());
Prabir Pradhan197e0862022-07-01 14:28:00 +00009086
9087 // Disable the show touches configuration and ensure the spots are cleared.
9088 mFakePolicy->setShowTouches(false);
Siarhei Vishniakou2935db72022-09-22 13:35:22 -07009089 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9090 InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
Prabir Pradhan197e0862022-07-01 14:28:00 +00009091
9092 ASSERT_TRUE(fakePointerController->getSpots().empty());
Arthur Hung7c645402019-01-25 17:45:42 +08009093}
9094
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009095TEST_F(MultiTouchInputMapperTest, VideoFrames_ReceivedByListener) {
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009096 prepareAxes(POSITION);
9097 addConfigurationProperty("touch.deviceType", "touchScreen");
9098 prepareDisplay(DISPLAY_ORIENTATION_0);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009099 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009100
9101 NotifyMotionArgs motionArgs;
9102 // Unrotated video frame
9103 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9104 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009105 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou6b76bdf2019-02-15 20:01:35 -06009106 processPosition(mapper, 100, 200);
9107 processSync(mapper);
9108 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9109 ASSERT_EQ(frames, motionArgs.videoFrames);
9110
9111 // Subsequent touch events should not have any videoframes
9112 // This is implemented separately in FakeEventHub,
9113 // but that should match the behaviour of TouchVideoDevice.
9114 processPosition(mapper, 200, 200);
9115 processSync(mapper);
9116 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9117 ASSERT_EQ(std::vector<TouchVideoFrame>(), motionArgs.videoFrames);
9118}
9119
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009120TEST_F(MultiTouchInputMapperTest, VideoFrames_AreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009121 prepareAxes(POSITION);
9122 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009123 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009124 // Unrotated video frame
9125 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9126 NotifyMotionArgs motionArgs;
9127
9128 // Test all 4 orientations
9129 for (int32_t orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90,
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009130 DISPLAY_ORIENTATION_180, DISPLAY_ORIENTATION_270}) {
9131 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
9132 clearViewports();
9133 prepareDisplay(orientation);
9134 std::vector<TouchVideoFrame> frames{frame};
9135 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
9136 processPosition(mapper, 100, 200);
9137 processSync(mapper);
9138 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9139 ASSERT_EQ(frames, motionArgs.videoFrames);
9140 }
9141}
9142
9143TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_AreRotated) {
9144 prepareAxes(POSITION);
9145 addConfigurationProperty("touch.deviceType", "touchScreen");
9146 // Since InputReader works in the un-rotated coordinate space, only devices that are not
9147 // orientation-aware are affected by display rotation.
9148 addConfigurationProperty("touch.orientationAware", "0");
9149 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9150 // Unrotated video frame
9151 TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9152 NotifyMotionArgs motionArgs;
9153
9154 // Test all 4 orientations
9155 for (int32_t orientation : {DISPLAY_ORIENTATION_0, DISPLAY_ORIENTATION_90,
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009156 DISPLAY_ORIENTATION_180, DISPLAY_ORIENTATION_270}) {
9157 SCOPED_TRACE("Orientation " + StringPrintf("%i", orientation));
9158 clearViewports();
9159 prepareDisplay(orientation);
9160 std::vector<TouchVideoFrame> frames{frame};
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009161 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009162 processPosition(mapper, 100, 200);
9163 processSync(mapper);
9164 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009165 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
9166 // compared to the display. This is so that when the window transform (which contains the
9167 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
9168 // window's coordinate space.
9169 frames[0].rotate(getInverseRotation(orientation));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009170 ASSERT_EQ(frames, motionArgs.videoFrames);
lilinnan687e58f2022-07-19 16:00:50 +08009171
9172 // Release finger.
9173 processSync(mapper);
9174 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009175 }
9176}
9177
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009178TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreNotRotated) {
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009179 prepareAxes(POSITION);
9180 addConfigurationProperty("touch.deviceType", "touchScreen");
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009181 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009182 // Unrotated video frames. There's no rule that they must all have the same dimensions,
9183 // so mix these.
9184 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9185 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
9186 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
9187 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
9188 NotifyMotionArgs motionArgs;
9189
9190 prepareDisplay(DISPLAY_ORIENTATION_90);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009191 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009192 processPosition(mapper, 100, 200);
9193 processSync(mapper);
9194 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Prabir Pradhanc14266f2021-05-12 15:56:24 -07009195 ASSERT_EQ(frames, motionArgs.videoFrames);
9196}
9197
9198TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_MultipleFramesAreRotated) {
9199 prepareAxes(POSITION);
9200 addConfigurationProperty("touch.deviceType", "touchScreen");
9201 // Since InputReader works in the un-rotated coordinate space, only devices that are not
9202 // orientation-aware are affected by display rotation.
9203 addConfigurationProperty("touch.orientationAware", "0");
9204 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9205 // Unrotated video frames. There's no rule that they must all have the same dimensions,
9206 // so mix these.
9207 TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
9208 TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
9209 TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
9210 std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
9211 NotifyMotionArgs motionArgs;
9212
9213 prepareDisplay(DISPLAY_ORIENTATION_90);
9214 mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
9215 processPosition(mapper, 100, 200);
9216 processSync(mapper);
9217 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9218 std::for_each(frames.begin(), frames.end(), [](TouchVideoFrame& frame) {
9219 // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
9220 // compared to the display. This is so that when the window transform (which contains the
9221 // display rotation) is applied later by InputDispatcher, the coordinates end up in the
9222 // window's coordinate space.
9223 frame.rotate(getInverseRotation(DISPLAY_ORIENTATION_90));
9224 });
Siarhei Vishniakou8154bbd2019-02-15 17:21:03 -06009225 ASSERT_EQ(frames, motionArgs.videoFrames);
9226}
9227
Arthur Hung9da14732019-09-02 16:16:58 +08009228/**
9229 * If we had defined port associations, but the viewport is not ready, the touch device would be
9230 * expected to be disabled, and it should be enabled after the viewport has found.
9231 */
9232TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) {
Arthur Hung9da14732019-09-02 16:16:58 +08009233 constexpr uint8_t hdmi2 = 1;
9234 const std::string secondaryUniqueId = "uniqueId2";
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009235 constexpr ViewportType type = ViewportType::EXTERNAL;
Arthur Hung9da14732019-09-02 16:16:58 +08009236
9237 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi2);
9238
9239 addConfigurationProperty("touch.deviceType", "touchScreen");
9240 prepareAxes(POSITION);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009241 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung9da14732019-09-02 16:16:58 +08009242
9243 ASSERT_EQ(mDevice->isEnabled(), false);
9244
9245 // Add display on hdmi2, the device should be enabled and can receive touch event.
9246 prepareSecondaryDisplay(type, hdmi2);
9247 ASSERT_EQ(mDevice->isEnabled(), true);
9248
9249 // Send a touch event.
9250 processPosition(mapper, 100, 100);
9251 processSync(mapper);
9252
9253 NotifyMotionArgs args;
9254 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9255 ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
9256}
9257
Arthur Hung421eb1c2020-01-16 00:09:42 +08009258TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
Arthur Hung421eb1c2020-01-16 00:09:42 +08009259 addConfigurationProperty("touch.deviceType", "touchScreen");
9260 prepareDisplay(DISPLAY_ORIENTATION_0);
9261 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009262 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +08009263
9264 NotifyMotionArgs motionArgs;
9265
9266 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
9267 // finger down
9268 processId(mapper, 1);
9269 processPosition(mapper, x1, y1);
9270 processSync(mapper);
9271 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9272 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9273 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9274
9275 // finger move
9276 processId(mapper, 1);
9277 processPosition(mapper, x2, y2);
9278 processSync(mapper);
9279 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9280 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9281 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9282
9283 // finger up.
9284 processId(mapper, -1);
9285 processSync(mapper);
9286 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9287 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9288 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9289
9290 // new finger down
9291 processId(mapper, 1);
9292 processPosition(mapper, x3, y3);
9293 processSync(mapper);
9294 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9295 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9296 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9297}
9298
9299/**
arthurhungcc7f9802020-04-30 17:55:40 +08009300 * Test single touch should be canceled when received the MT_TOOL_PALM event, and the following
9301 * MOVE and UP events should be ignored.
Arthur Hung421eb1c2020-01-16 00:09:42 +08009302 */
arthurhungcc7f9802020-04-30 17:55:40 +08009303TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_SinglePointer) {
Arthur Hung421eb1c2020-01-16 00:09:42 +08009304 addConfigurationProperty("touch.deviceType", "touchScreen");
9305 prepareDisplay(DISPLAY_ORIENTATION_0);
9306 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
Nathaniel R. Lewisf4916ef2020-01-14 11:57:18 -08009307 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Arthur Hung421eb1c2020-01-16 00:09:42 +08009308
9309 NotifyMotionArgs motionArgs;
9310
9311 // default tool type is finger
9312 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
arthurhungcc7f9802020-04-30 17:55:40 +08009313 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009314 processPosition(mapper, x1, y1);
9315 processSync(mapper);
9316 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9317 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9318 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9319
9320 // Tool changed to MT_TOOL_PALM expect sending the cancel event.
9321 processToolType(mapper, MT_TOOL_PALM);
9322 processSync(mapper);
9323 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9324 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
9325
9326 // Ignore the following MOVE and UP events if had detect a palm event.
arthurhungcc7f9802020-04-30 17:55:40 +08009327 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009328 processPosition(mapper, x2, y2);
9329 processSync(mapper);
9330 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9331
9332 // finger up.
arthurhungcc7f9802020-04-30 17:55:40 +08009333 processId(mapper, INVALID_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009334 processSync(mapper);
9335 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9336
9337 // new finger down
arthurhungcc7f9802020-04-30 17:55:40 +08009338 processId(mapper, FIRST_TRACKING_ID);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009339 processToolType(mapper, MT_TOOL_FINGER);
Arthur Hung421eb1c2020-01-16 00:09:42 +08009340 processPosition(mapper, x3, y3);
9341 processSync(mapper);
9342 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9343 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9344 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9345}
9346
arthurhungbf89a482020-04-17 17:37:55 +08009347/**
arthurhungcc7f9802020-04-30 17:55:40 +08009348 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
9349 * and the rest active fingers could still be allowed to receive the events
arthurhungbf89a482020-04-17 17:37:55 +08009350 */
arthurhungcc7f9802020-04-30 17:55:40 +08009351TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_TwoPointers) {
arthurhungbf89a482020-04-17 17:37:55 +08009352 addConfigurationProperty("touch.deviceType", "touchScreen");
9353 prepareDisplay(DISPLAY_ORIENTATION_0);
9354 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
9355 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9356
9357 NotifyMotionArgs motionArgs;
9358
9359 // default tool type is finger
arthurhungcc7f9802020-04-30 17:55:40 +08009360 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
9361 processId(mapper, FIRST_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08009362 processPosition(mapper, x1, y1);
9363 processSync(mapper);
9364 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9365 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9366 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9367
9368 // Second finger down.
arthurhungcc7f9802020-04-30 17:55:40 +08009369 processSlot(mapper, SECOND_SLOT);
9370 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08009371 processPosition(mapper, x2, y2);
arthurhungcc7f9802020-04-30 17:55:40 +08009372 processSync(mapper);
9373 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009374 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009375 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
9376
9377 // If the tool type of the first finger changes to MT_TOOL_PALM,
9378 // we expect to receive ACTION_POINTER_UP with cancel flag.
9379 processSlot(mapper, FIRST_SLOT);
9380 processId(mapper, FIRST_TRACKING_ID);
9381 processToolType(mapper, MT_TOOL_PALM);
9382 processSync(mapper);
9383 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009384 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009385 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9386
9387 // The following MOVE events of second finger should be processed.
9388 processSlot(mapper, SECOND_SLOT);
9389 processId(mapper, SECOND_TRACKING_ID);
9390 processPosition(mapper, x2 + 1, y2 + 1);
9391 processSync(mapper);
9392 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9393 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9394 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9395
9396 // First finger up. It used to be in palm mode, and we already generated ACTION_POINTER_UP for
9397 // it. Second finger receive move.
9398 processSlot(mapper, FIRST_SLOT);
9399 processId(mapper, INVALID_TRACKING_ID);
9400 processSync(mapper);
9401 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9402 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9403 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9404
9405 // Second finger keeps moving.
9406 processSlot(mapper, SECOND_SLOT);
9407 processId(mapper, SECOND_TRACKING_ID);
9408 processPosition(mapper, x2 + 2, y2 + 2);
9409 processSync(mapper);
9410 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9411 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9412 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9413
9414 // Second finger up.
9415 processId(mapper, INVALID_TRACKING_ID);
9416 processSync(mapper);
9417 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9418 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9419 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9420}
9421
9422/**
9423 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event, if only 1 finger
9424 * is active, it should send CANCEL after receiving the MT_TOOL_PALM event.
9425 */
9426TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_ShouldCancelWhenAllTouchIsPalm) {
9427 addConfigurationProperty("touch.deviceType", "touchScreen");
9428 prepareDisplay(DISPLAY_ORIENTATION_0);
9429 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
9430 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9431
9432 NotifyMotionArgs motionArgs;
9433
9434 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
9435 // First finger down.
9436 processId(mapper, FIRST_TRACKING_ID);
9437 processPosition(mapper, x1, y1);
9438 processSync(mapper);
9439 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9440 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9441 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9442
9443 // Second finger down.
9444 processSlot(mapper, SECOND_SLOT);
9445 processId(mapper, SECOND_TRACKING_ID);
9446 processPosition(mapper, x2, y2);
arthurhungbf89a482020-04-17 17:37:55 +08009447 processSync(mapper);
9448 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009449 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungbf89a482020-04-17 17:37:55 +08009450 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9451
arthurhungcc7f9802020-04-30 17:55:40 +08009452 // If the tool type of the first finger changes to MT_TOOL_PALM,
9453 // we expect to receive ACTION_POINTER_UP with cancel flag.
9454 processSlot(mapper, FIRST_SLOT);
9455 processId(mapper, FIRST_TRACKING_ID);
9456 processToolType(mapper, MT_TOOL_PALM);
9457 processSync(mapper);
9458 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009459 ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009460 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9461
9462 // Second finger keeps moving.
9463 processSlot(mapper, SECOND_SLOT);
9464 processId(mapper, SECOND_TRACKING_ID);
9465 processPosition(mapper, x2 + 1, y2 + 1);
9466 processSync(mapper);
9467 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9468 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9469
9470 // second finger becomes palm, receive cancel due to only 1 finger is active.
9471 processId(mapper, SECOND_TRACKING_ID);
arthurhungbf89a482020-04-17 17:37:55 +08009472 processToolType(mapper, MT_TOOL_PALM);
9473 processSync(mapper);
9474 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9475 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
9476
arthurhungcc7f9802020-04-30 17:55:40 +08009477 // third finger down.
9478 processSlot(mapper, THIRD_SLOT);
9479 processId(mapper, THIRD_TRACKING_ID);
9480 processToolType(mapper, MT_TOOL_FINGER);
arthurhungbf89a482020-04-17 17:37:55 +08009481 processPosition(mapper, x3, y3);
9482 processSync(mapper);
arthurhungbf89a482020-04-17 17:37:55 +08009483 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9484 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9485 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
arthurhungcc7f9802020-04-30 17:55:40 +08009486 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9487
9488 // third finger move
9489 processId(mapper, THIRD_TRACKING_ID);
9490 processPosition(mapper, x3 + 1, y3 + 1);
9491 processSync(mapper);
9492 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9493 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9494
9495 // first finger up, third finger receive move.
9496 processSlot(mapper, FIRST_SLOT);
9497 processId(mapper, INVALID_TRACKING_ID);
9498 processSync(mapper);
9499 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9500 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9501 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9502
9503 // second finger up, third finger receive move.
9504 processSlot(mapper, SECOND_SLOT);
9505 processId(mapper, INVALID_TRACKING_ID);
9506 processSync(mapper);
9507 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9508 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9509 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9510
9511 // third finger up.
9512 processSlot(mapper, THIRD_SLOT);
9513 processId(mapper, INVALID_TRACKING_ID);
9514 processSync(mapper);
9515 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9516 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9517 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9518}
9519
9520/**
9521 * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
9522 * and the active finger could still be allowed to receive the events
9523 */
9524TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_KeepFirstPointer) {
9525 addConfigurationProperty("touch.deviceType", "touchScreen");
9526 prepareDisplay(DISPLAY_ORIENTATION_0);
9527 prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
9528 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9529
9530 NotifyMotionArgs motionArgs;
9531
9532 // default tool type is finger
9533 constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
9534 processId(mapper, FIRST_TRACKING_ID);
9535 processPosition(mapper, x1, y1);
9536 processSync(mapper);
9537 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9538 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9539 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9540
9541 // Second finger down.
9542 processSlot(mapper, SECOND_SLOT);
9543 processId(mapper, SECOND_TRACKING_ID);
9544 processPosition(mapper, x2, y2);
9545 processSync(mapper);
9546 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009547 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009548 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
9549
9550 // If the tool type of the second finger changes to MT_TOOL_PALM,
9551 // we expect to receive ACTION_POINTER_UP with cancel flag.
9552 processId(mapper, SECOND_TRACKING_ID);
9553 processToolType(mapper, MT_TOOL_PALM);
9554 processSync(mapper);
9555 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009556 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
arthurhungcc7f9802020-04-30 17:55:40 +08009557 ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
9558
9559 // The following MOVE event should be processed.
9560 processSlot(mapper, FIRST_SLOT);
9561 processId(mapper, FIRST_TRACKING_ID);
9562 processPosition(mapper, x1 + 1, y1 + 1);
9563 processSync(mapper);
9564 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9565 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9566 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9567
9568 // second finger up.
9569 processSlot(mapper, SECOND_SLOT);
9570 processId(mapper, INVALID_TRACKING_ID);
9571 processSync(mapper);
9572 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9573 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9574
9575 // first finger keep moving
9576 processSlot(mapper, FIRST_SLOT);
9577 processId(mapper, FIRST_TRACKING_ID);
9578 processPosition(mapper, x1 + 2, y1 + 2);
9579 processSync(mapper);
9580 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9581 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9582
9583 // first finger up.
9584 processId(mapper, INVALID_TRACKING_ID);
9585 processSync(mapper);
9586 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9587 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9588 ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
arthurhungbf89a482020-04-17 17:37:55 +08009589}
9590
Arthur Hung9ad18942021-06-19 02:04:46 +00009591/**
9592 * Test multi-touch should sent ACTION_POINTER_UP/ACTION_UP when received the INVALID_TRACKING_ID,
9593 * to prevent the driver side may send unexpected data after set tracking id as INVALID_TRACKING_ID
9594 * cause slot be valid again.
9595 */
9596TEST_F(MultiTouchInputMapperTest, Process_MultiTouch_WithInvalidTrackingId) {
9597 addConfigurationProperty("touch.deviceType", "touchScreen");
9598 prepareDisplay(DISPLAY_ORIENTATION_0);
9599 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9600 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9601
9602 NotifyMotionArgs motionArgs;
9603
9604 constexpr int32_t x1 = 100, y1 = 200, x2 = 0, y2 = 0;
9605 // First finger down.
9606 processId(mapper, FIRST_TRACKING_ID);
9607 processPosition(mapper, x1, y1);
9608 processPressure(mapper, RAW_PRESSURE_MAX);
9609 processSync(mapper);
9610 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9611 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
9612 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9613
9614 // First finger move.
9615 processId(mapper, FIRST_TRACKING_ID);
9616 processPosition(mapper, x1 + 1, y1 + 1);
9617 processPressure(mapper, RAW_PRESSURE_MAX);
9618 processSync(mapper);
9619 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9620 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
9621 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9622
9623 // Second finger down.
9624 processSlot(mapper, SECOND_SLOT);
9625 processId(mapper, SECOND_TRACKING_ID);
9626 processPosition(mapper, x2, y2);
9627 processPressure(mapper, RAW_PRESSURE_MAX);
9628 processSync(mapper);
9629 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009630 ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
Arthur Hung9ad18942021-06-19 02:04:46 +00009631 ASSERT_EQ(uint32_t(2), motionArgs.pointerCount);
9632
9633 // second finger up with some unexpected data.
9634 processSlot(mapper, SECOND_SLOT);
9635 processId(mapper, INVALID_TRACKING_ID);
9636 processPosition(mapper, x2, y2);
9637 processSync(mapper);
9638 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009639 ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
Arthur Hung9ad18942021-06-19 02:04:46 +00009640 ASSERT_EQ(uint32_t(2), motionArgs.pointerCount);
9641
9642 // first finger up with some unexpected data.
9643 processSlot(mapper, FIRST_SLOT);
9644 processId(mapper, INVALID_TRACKING_ID);
9645 processPosition(mapper, x2, y2);
9646 processPressure(mapper, RAW_PRESSURE_MAX);
9647 processSync(mapper);
9648 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9649 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
9650 ASSERT_EQ(uint32_t(1), motionArgs.pointerCount);
9651}
9652
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009653TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState) {
9654 addConfigurationProperty("touch.deviceType", "touchScreen");
9655 prepareDisplay(DISPLAY_ORIENTATION_0);
9656 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9657 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9658
9659 // First finger down.
9660 processId(mapper, FIRST_TRACKING_ID);
9661 processPosition(mapper, 100, 200);
9662 processPressure(mapper, RAW_PRESSURE_MAX);
9663 processSync(mapper);
9664 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9665 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
9666
9667 // Second finger down.
9668 processSlot(mapper, SECOND_SLOT);
9669 processId(mapper, SECOND_TRACKING_ID);
9670 processPosition(mapper, 300, 400);
9671 processPressure(mapper, RAW_PRESSURE_MAX);
9672 processSync(mapper);
9673 ASSERT_NO_FATAL_FAILURE(
9674 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(ACTION_POINTER_1_DOWN)));
9675
9676 // Reset the mapper. When the mapper is reset, we expect the current multi-touch state to be
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00009677 // preserved. Resetting should cancel the ongoing gesture.
9678 resetMapper(mapper, ARBITRARY_TIME);
9679 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9680 WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009681
9682 // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
9683 // the existing touch state to generate a down event.
9684 processPosition(mapper, 301, 302);
9685 processSync(mapper);
9686 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9687 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
9688 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9689 AllOf(WithMotionAction(ACTION_POINTER_1_DOWN), WithPressure(1.f))));
9690
9691 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9692}
9693
9694TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState_NoPointersDown) {
9695 addConfigurationProperty("touch.deviceType", "touchScreen");
9696 prepareDisplay(DISPLAY_ORIENTATION_0);
9697 prepareAxes(POSITION | ID | SLOT | PRESSURE);
9698 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9699
9700 // First finger touches down and releases.
9701 processId(mapper, FIRST_TRACKING_ID);
9702 processPosition(mapper, 100, 200);
9703 processPressure(mapper, RAW_PRESSURE_MAX);
9704 processSync(mapper);
9705 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9706 WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
9707 processId(mapper, INVALID_TRACKING_ID);
9708 processSync(mapper);
9709 ASSERT_NO_FATAL_FAILURE(
9710 mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
9711
9712 // Reset the mapper. When the mapper is reset, we expect it to restore the latest
9713 // raw state where no pointers are down.
Prabir Pradhanf5b4d7a2022-10-03 15:45:50 +00009714 resetMapper(mapper, ARBITRARY_TIME);
Prabir Pradhanafabcde2022-09-27 19:32:43 +00009715 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9716
9717 // Send an empty sync frame. Since there are no pointers, no events are generated.
9718 processSync(mapper);
9719 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
9720}
9721
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +00009722TEST_F(MultiTouchInputMapperTest, StylusSourceIsAddedDynamicallyFromToolType) {
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009723 addConfigurationProperty("touch.deviceType", "touchScreen");
9724 prepareDisplay(DISPLAY_ORIENTATION_0);
9725 prepareAxes(POSITION | ID | SLOT | PRESSURE | TOOL_TYPE);
9726 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +00009727 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009728
9729 // Even if the device supports reporting the ABS_MT_TOOL_TYPE axis, which could give it the
9730 // ability to report MT_TOOL_PEN, we do not report the device as coming from a stylus source.
9731 // Due to limitations in the evdev protocol, we cannot say for certain that a device is capable
9732 // of reporting stylus events just because it supports ABS_MT_TOOL_TYPE.
9733 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
9734
9735 // However, if the device ever ends up reporting an event with MT_TOOL_PEN, it should be
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +00009736 // reported with the stylus source.
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009737 processId(mapper, FIRST_TRACKING_ID);
9738 processToolType(mapper, MT_TOOL_PEN);
9739 processPosition(mapper, 100, 200);
9740 processPressure(mapper, RAW_PRESSURE_MAX);
9741 processSync(mapper);
9742 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9743 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
9744 WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
9745 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
9746
Prabir Pradhan5d0d97d2022-11-17 01:06:01 +00009747 // Now that we know the device supports styluses, ensure that the device is re-configured with
9748 // the stylus source.
9749 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, mapper.getSources());
9750 {
9751 const auto& devices = mReader->getInputDevices();
9752 auto deviceInfo =
9753 std::find_if(devices.begin(), devices.end(),
9754 [](const InputDeviceInfo& info) { return info.getId() == DEVICE_ID; });
9755 LOG_ALWAYS_FATAL_IF(deviceInfo == devices.end(), "Cannot find InputDevice");
9756 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, deviceInfo->getSources());
9757 }
9758
9759 // Ensure the device was not reset to prevent interruptions of any ongoing gestures.
9760 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
9761
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009762 processId(mapper, INVALID_TRACKING_ID);
9763 processSync(mapper);
9764 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
9765 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
9766 WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
9767 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
Prabir Pradhanf9a41282022-10-25 17:15:50 +00009768}
9769
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009770// --- MultiTouchInputMapperTest_ExternalDevice ---
9771
9772class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
9773protected:
Chris Yea52ade12020-08-27 16:49:20 -07009774 void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL); }
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009775};
9776
9777/**
9778 * Expect fallback to internal viewport if device is external and external viewport is not present.
9779 */
9780TEST_F(MultiTouchInputMapperTest_ExternalDevice, Viewports_Fallback) {
9781 prepareAxes(POSITION);
9782 addConfigurationProperty("touch.deviceType", "touchScreen");
9783 prepareDisplay(DISPLAY_ORIENTATION_0);
9784 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9785
9786 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
9787
9788 NotifyMotionArgs motionArgs;
9789
9790 // Expect the event to be sent to the internal viewport,
9791 // because an external viewport is not present.
9792 processPosition(mapper, 100, 100);
9793 processSync(mapper);
9794 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9795 ASSERT_EQ(ADISPLAY_ID_DEFAULT, motionArgs.displayId);
9796
9797 // Expect the event to be sent to the external viewport if it is present.
Michael Wrightfe3de7d2020-07-02 19:05:30 +01009798 prepareSecondaryDisplay(ViewportType::EXTERNAL);
Nathaniel R. Lewisa7b82e12020-02-12 15:40:45 -08009799 processPosition(mapper, 100, 100);
9800 processSync(mapper);
9801 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
9802 ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
9803}
Arthur Hung4197f6b2020-03-16 15:39:59 +08009804
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009805TEST_F(MultiTouchInputMapperTest, Process_TouchpadCapture) {
9806 // we need a pointer controller for mouse mode of touchpad (start pointer at 0,0)
9807 std::shared_ptr<FakePointerController> fakePointerController =
9808 std::make_shared<FakePointerController>();
9809 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
9810 fakePointerController->setPosition(0, 0);
9811 fakePointerController->setButtonState(0);
9812
9813 // prepare device and capture
9814 prepareDisplay(DISPLAY_ORIENTATION_0);
9815 prepareAxes(POSITION | ID | SLOT);
9816 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
9817 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
9818 mFakePolicy->setPointerCapture(true);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009819 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009820 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9821
9822 // captured touchpad should be a touchpad source
9823 NotifyDeviceResetArgs resetArgs;
9824 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
9825 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
9826
Siarhei Vishniakou1983a712021-06-04 19:27:09 +00009827 InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
Chris Yef74dc422020-09-02 22:41:50 -07009828
9829 const InputDeviceInfo::MotionRange* relRangeX =
9830 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, AINPUT_SOURCE_TOUCHPAD);
9831 ASSERT_NE(relRangeX, nullptr);
9832 ASSERT_EQ(relRangeX->min, -(RAW_X_MAX - RAW_X_MIN));
9833 ASSERT_EQ(relRangeX->max, RAW_X_MAX - RAW_X_MIN);
9834 const InputDeviceInfo::MotionRange* relRangeY =
9835 deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, AINPUT_SOURCE_TOUCHPAD);
9836 ASSERT_NE(relRangeY, nullptr);
9837 ASSERT_EQ(relRangeY->min, -(RAW_Y_MAX - RAW_Y_MIN));
9838 ASSERT_EQ(relRangeY->max, RAW_Y_MAX - RAW_Y_MIN);
9839
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009840 // run captured pointer tests - note that this is unscaled, so input listener events should be
9841 // identical to what the hardware sends (accounting for any
9842 // calibration).
9843 // FINGER 0 DOWN
Chris Ye364fdb52020-08-05 15:07:56 -07009844 processSlot(mapper, 0);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009845 processId(mapper, 1);
9846 processPosition(mapper, 100 + RAW_X_MIN, 100 + RAW_Y_MIN);
9847 processKey(mapper, BTN_TOUCH, 1);
9848 processSync(mapper);
9849
9850 // expect coord[0] to contain initial location of touch 0
9851 NotifyMotionArgs args;
9852 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9853 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
9854 ASSERT_EQ(1U, args.pointerCount);
9855 ASSERT_EQ(0, args.pointerProperties[0].id);
9856 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, args.source);
9857 ASSERT_NO_FATAL_FAILURE(
9858 assertPointerCoords(args.pointerCoords[0], 100, 100, 1, 0, 0, 0, 0, 0, 0, 0));
9859
9860 // FINGER 1 DOWN
9861 processSlot(mapper, 1);
9862 processId(mapper, 2);
9863 processPosition(mapper, 560 + RAW_X_MIN, 154 + RAW_Y_MIN);
9864 processSync(mapper);
9865
9866 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
9867 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
Siarhei Vishniakou5fd3e012021-12-30 15:20:32 -08009868 ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009869 ASSERT_EQ(2U, args.pointerCount);
9870 ASSERT_EQ(0, args.pointerProperties[0].id);
9871 ASSERT_EQ(1, args.pointerProperties[1].id);
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], 560, 154, 1, 0, 0, 0, 0, 0, 0, 0));
9876
9877 // FINGER 1 MOVE
9878 processPosition(mapper, 540 + RAW_X_MIN, 690 + RAW_Y_MIN);
9879 processSync(mapper);
9880
9881 // expect coord[0] to contain previous location, coord[1] to contain new touch 1 location
9882 // from move
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], 100, 100, 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 // FINGER 0 MOVE
9891 processSlot(mapper, 0);
9892 processPosition(mapper, 50 + RAW_X_MIN, 800 + RAW_Y_MIN);
9893 processSync(mapper);
9894
9895 // expect coord[0] to contain new touch 0 location, coord[1] to contain previous location
9896 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9897 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9898 ASSERT_NO_FATAL_FAILURE(
9899 assertPointerCoords(args.pointerCoords[0], 50, 800, 1, 0, 0, 0, 0, 0, 0, 0));
9900 ASSERT_NO_FATAL_FAILURE(
9901 assertPointerCoords(args.pointerCoords[1], 540, 690, 1, 0, 0, 0, 0, 0, 0, 0));
9902
9903 // BUTTON DOWN
9904 processKey(mapper, BTN_LEFT, 1);
9905 processSync(mapper);
9906
9907 // touchinputmapper design sends a move before button press
9908 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9909 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9910 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9911 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
9912
9913 // BUTTON UP
9914 processKey(mapper, BTN_LEFT, 0);
9915 processSync(mapper);
9916
9917 // touchinputmapper design sends a move after button release
9918 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9919 ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
9920 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9921 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9922
9923 // FINGER 0 UP
9924 processId(mapper, -1);
9925 processSync(mapper);
9926 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9927 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | 0x0000, args.action);
9928
9929 // FINGER 1 MOVE
9930 processSlot(mapper, 1);
9931 processPosition(mapper, 320 + RAW_X_MIN, 900 + RAW_Y_MIN);
9932 processSync(mapper);
9933
9934 // expect coord[0] to contain new location of touch 1, and properties[0].id to contain 1
9935 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9936 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
9937 ASSERT_EQ(1U, args.pointerCount);
9938 ASSERT_EQ(1, args.pointerProperties[0].id);
9939 ASSERT_NO_FATAL_FAILURE(
9940 assertPointerCoords(args.pointerCoords[0], 320, 900, 1, 0, 0, 0, 0, 0, 0, 0));
9941
9942 // FINGER 1 UP
9943 processId(mapper, -1);
9944 processKey(mapper, BTN_TOUCH, 0);
9945 processSync(mapper);
9946 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9947 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
9948
Harry Cutts16a24cc2022-10-26 15:22:19 +00009949 // A non captured touchpad should have a mouse and touchpad source.
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009950 mFakePolicy->setPointerCapture(false);
9951 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
9952 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
Harry Cutts16a24cc2022-10-26 15:22:19 +00009953 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009954}
9955
9956TEST_F(MultiTouchInputMapperTest, Process_UnCapturedTouchpadPointer) {
9957 std::shared_ptr<FakePointerController> fakePointerController =
9958 std::make_shared<FakePointerController>();
9959 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
9960 fakePointerController->setPosition(0, 0);
9961 fakePointerController->setButtonState(0);
9962
9963 // prepare device and capture
9964 prepareDisplay(DISPLAY_ORIENTATION_0);
9965 prepareAxes(POSITION | ID | SLOT);
9966 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
9967 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +00009968 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -08009969 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
9970 // run uncaptured pointer tests - pushes out generic events
9971 // FINGER 0 DOWN
9972 processId(mapper, 3);
9973 processPosition(mapper, 100, 100);
9974 processKey(mapper, BTN_TOUCH, 1);
9975 processSync(mapper);
9976
9977 // start at (100,100), cursor should be at (0,0) * scale
9978 NotifyMotionArgs args;
9979 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9980 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
9981 ASSERT_NO_FATAL_FAILURE(
9982 assertPointerCoords(args.pointerCoords[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
9983
9984 // FINGER 0 MOVE
9985 processPosition(mapper, 200, 200);
9986 processSync(mapper);
9987
9988 // compute scaling to help with touch position checking
9989 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
9990 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
9991 float scale =
9992 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
9993
9994 // translate from (100,100) -> (200,200), cursor should have changed to (100,100) * scale)
9995 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
9996 ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
9997 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 100 * scale, 100 * scale, 0,
9998 0, 0, 0, 0, 0, 0, 0));
9999}
10000
10001TEST_F(MultiTouchInputMapperTest, WhenCapturedAndNotCaptured_GetSources) {
10002 std::shared_ptr<FakePointerController> fakePointerController =
10003 std::make_shared<FakePointerController>();
10004
10005 prepareDisplay(DISPLAY_ORIENTATION_0);
10006 prepareAxes(POSITION | ID | SLOT);
10007 mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
Prabir Pradhan2853b7a2021-08-23 14:08:51 +000010008 mFakePolicy->setPointerController(fakePointerController);
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010009 mFakePolicy->setPointerCapture(false);
10010 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10011
Harry Cutts16a24cc2022-10-26 15:22:19 +000010012 // An uncaptured touchpad should be a pointer device, with additional touchpad source.
10013 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010014
Harry Cutts16a24cc2022-10-26 15:22:19 +000010015 // A captured touchpad should just have a touchpad source.
Nathaniel R. Lewisd5665332018-02-22 13:31:42 -080010016 mFakePolicy->setPointerCapture(true);
10017 configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
10018 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
10019}
10020
Prabir Pradhan2f37bcb2022-11-08 20:41:28 +000010021// --- BluetoothMultiTouchInputMapperTest ---
10022
10023class BluetoothMultiTouchInputMapperTest : public MultiTouchInputMapperTest {
10024protected:
10025 void SetUp() override {
10026 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
10027 }
10028};
10029
10030TEST_F(BluetoothMultiTouchInputMapperTest, TimestampSmoothening) {
10031 addConfigurationProperty("touch.deviceType", "touchScreen");
10032 prepareDisplay(DISPLAY_ORIENTATION_0);
10033 prepareAxes(POSITION | ID | SLOT | PRESSURE);
10034 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10035
10036 nsecs_t kernelEventTime = ARBITRARY_TIME;
10037 nsecs_t expectedEventTime = ARBITRARY_TIME;
10038 // Touch down.
10039 processId(mapper, FIRST_TRACKING_ID);
10040 processPosition(mapper, 100, 200);
10041 processPressure(mapper, RAW_PRESSURE_MAX);
10042 processSync(mapper, ARBITRARY_TIME);
10043 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10044 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithEventTime(ARBITRARY_TIME))));
10045
10046 // Process several events that come in quick succession, according to their timestamps.
10047 for (int i = 0; i < 3; i++) {
10048 constexpr static nsecs_t delta = ms2ns(1);
10049 static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
10050 kernelEventTime += delta;
10051 expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
10052
10053 processPosition(mapper, 101 + i, 201 + i);
10054 processSync(mapper, kernelEventTime);
10055 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10056 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
10057 WithEventTime(expectedEventTime))));
10058 }
10059
10060 // Release the touch.
10061 processId(mapper, INVALID_TRACKING_ID);
10062 processPressure(mapper, RAW_PRESSURE_MIN);
10063 processSync(mapper, ARBITRARY_TIME + ms2ns(50));
10064 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10065 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
10066 WithEventTime(ARBITRARY_TIME + ms2ns(50)))));
10067}
10068
10069// --- MultiTouchPointerModeTest ---
10070
HQ Liue6983c72022-04-19 22:14:56 +000010071class MultiTouchPointerModeTest : public MultiTouchInputMapperTest {
10072protected:
10073 float mPointerMovementScale;
10074 float mPointerXZoomScale;
10075 void preparePointerMode(int xAxisResolution, int yAxisResolution) {
10076 addConfigurationProperty("touch.deviceType", "pointer");
10077 std::shared_ptr<FakePointerController> fakePointerController =
10078 std::make_shared<FakePointerController>();
10079 fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
10080 fakePointerController->setPosition(0, 0);
10081 fakePointerController->setButtonState(0);
10082 prepareDisplay(DISPLAY_ORIENTATION_0);
10083
10084 prepareAxes(POSITION);
10085 prepareAbsoluteAxisResolution(xAxisResolution, yAxisResolution);
10086 // In order to enable swipe and freeform gesture in pointer mode, pointer capture
10087 // needs to be disabled, and the pointer gesture needs to be enabled.
10088 mFakePolicy->setPointerCapture(false);
10089 mFakePolicy->setPointerGestureEnabled(true);
10090 mFakePolicy->setPointerController(fakePointerController);
10091
10092 float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
10093 float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
10094 mPointerMovementScale =
10095 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
10096 mPointerXZoomScale =
10097 mFakePolicy->getPointerGestureZoomSpeedRatio() * displayDiagonal / rawDiagonal;
10098 }
10099
10100 void prepareAbsoluteAxisResolution(int xAxisResolution, int yAxisResolution) {
10101 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
10102 /*flat*/ 0,
10103 /*fuzz*/ 0, /*resolution*/ xAxisResolution);
10104 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
10105 /*flat*/ 0,
10106 /*fuzz*/ 0, /*resolution*/ yAxisResolution);
10107 }
10108};
10109
10110/**
10111 * Two fingers down on a pointer mode touch pad. The width
10112 * of the two finger is larger than 1/4 of the touch pack diagnal length. However, it
10113 * is smaller than the fixed min physical length 30mm. Two fingers' distance must
10114 * be greater than the both value to be freeform gesture, so that after two
10115 * fingers start to move downwards, the gesture should be swipe.
10116 */
10117TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) {
10118 // The min freeform gesture width is 25units/mm x 30mm = 750
10119 // which is greater than fraction of the diagnal length of the touchpad (349).
10120 // Thus, MaxSwipWidth is 750.
10121 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10122 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10123 NotifyMotionArgs motionArgs;
10124
10125 // Two fingers down at once.
10126 // The two fingers are 450 units apart, expects the current gesture to be PRESS
10127 // Pointer's initial position is used the [0,0] coordinate.
10128 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
10129
10130 processId(mapper, FIRST_TRACKING_ID);
10131 processPosition(mapper, x1, y1);
10132 processMTSync(mapper);
10133 processId(mapper, SECOND_TRACKING_ID);
10134 processPosition(mapper, x2, y2);
10135 processMTSync(mapper);
10136 processSync(mapper);
10137
10138 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10139 ASSERT_EQ(1U, motionArgs.pointerCount);
10140 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10141 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010142 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010143 ASSERT_NO_FATAL_FAILURE(
10144 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
10145
10146 // It should be recognized as a SWIPE gesture when two fingers start to move down,
10147 // that there should be 1 pointer.
10148 int32_t movingDistance = 200;
10149 y1 += movingDistance;
10150 y2 += movingDistance;
10151
10152 processId(mapper, FIRST_TRACKING_ID);
10153 processPosition(mapper, x1, y1);
10154 processMTSync(mapper);
10155 processId(mapper, SECOND_TRACKING_ID);
10156 processPosition(mapper, x2, y2);
10157 processMTSync(mapper);
10158 processSync(mapper);
10159
10160 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10161 ASSERT_EQ(1U, motionArgs.pointerCount);
10162 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10163 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010164 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010165 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
10166 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10167 0, 0, 0, 0));
10168}
10169
10170/**
10171 * Two fingers down on a pointer mode touch pad. The width of the two finger is larger
10172 * than the minimum freeform gesture width, 30mm. However, it is smaller than 1/4 of
10173 * the touch pack diagnal length. Two fingers' distance must be greater than the both
10174 * value to be freeform gesture, so that after two fingers start to move downwards,
10175 * the gesture should be swipe.
10176 */
10177TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) {
10178 // The min freeform gesture width is 5units/mm x 30mm = 150
10179 // which is greater than fraction of the diagnal length of the touchpad (349).
10180 // Thus, MaxSwipWidth is the fraction of the diagnal length, 349.
10181 preparePointerMode(5 /*xResolution*/, 5 /*yResolution*/);
10182 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10183 NotifyMotionArgs motionArgs;
10184
10185 // Two fingers down at once.
10186 // The two fingers are 250 units apart, expects the current gesture to be PRESS
10187 // Pointer's initial position is used the [0,0] coordinate.
10188 int32_t x1 = 100, y1 = 125, x2 = 350, y2 = 125;
10189
10190 processId(mapper, FIRST_TRACKING_ID);
10191 processPosition(mapper, x1, y1);
10192 processMTSync(mapper);
10193 processId(mapper, SECOND_TRACKING_ID);
10194 processPosition(mapper, x2, y2);
10195 processMTSync(mapper);
10196 processSync(mapper);
10197
10198 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10199 ASSERT_EQ(1U, motionArgs.pointerCount);
10200 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10201 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010202 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010203 ASSERT_NO_FATAL_FAILURE(
10204 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
10205
10206 // It should be recognized as a SWIPE gesture when two fingers start to move down,
10207 // and there should be 1 pointer.
10208 int32_t movingDistance = 200;
10209 y1 += movingDistance;
10210 y2 += movingDistance;
10211
10212 processId(mapper, FIRST_TRACKING_ID);
10213 processPosition(mapper, x1, y1);
10214 processMTSync(mapper);
10215 processId(mapper, SECOND_TRACKING_ID);
10216 processPosition(mapper, x2, y2);
10217 processMTSync(mapper);
10218 processSync(mapper);
10219
10220 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10221 ASSERT_EQ(1U, motionArgs.pointerCount);
10222 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10223 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010224 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010225 // New coordinate is the scaled relative coordinate from the initial coordinate.
10226 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
10227 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10228 0, 0, 0, 0));
10229}
10230
10231/**
10232 * Touch the touch pad with two fingers with a distance wider than the minimum freeform
10233 * gesture width and 1/4 of the diagnal length of the touchpad. Expect to receive
10234 * freeform gestures after two fingers start to move downwards.
10235 */
10236TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) {
10237 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10238 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10239
10240 NotifyMotionArgs motionArgs;
10241
10242 // Two fingers down at once. Wider than the max swipe width.
10243 // The gesture is expected to be PRESS, then transformed to FREEFORM
10244 int32_t x1 = 100, y1 = 125, x2 = 900, y2 = 125;
10245
10246 processId(mapper, FIRST_TRACKING_ID);
10247 processPosition(mapper, x1, y1);
10248 processMTSync(mapper);
10249 processId(mapper, SECOND_TRACKING_ID);
10250 processPosition(mapper, x2, y2);
10251 processMTSync(mapper);
10252 processSync(mapper);
10253
10254 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10255 ASSERT_EQ(1U, motionArgs.pointerCount);
10256 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10257 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010258 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010259 // One pointer for PRESS, and its coordinate is used as the origin for pointer coordinates.
10260 ASSERT_NO_FATAL_FAILURE(
10261 assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
10262
10263 int32_t movingDistance = 200;
10264
10265 // Move two fingers down, expect a cancel event because gesture is changing to freeform,
10266 // then two down events for two pointers.
10267 y1 += movingDistance;
10268 y2 += movingDistance;
10269
10270 processId(mapper, FIRST_TRACKING_ID);
10271 processPosition(mapper, x1, y1);
10272 processMTSync(mapper);
10273 processId(mapper, SECOND_TRACKING_ID);
10274 processPosition(mapper, x2, y2);
10275 processMTSync(mapper);
10276 processSync(mapper);
10277
10278 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10279 // The previous PRESS gesture is cancelled, because it is transformed to freeform
10280 ASSERT_EQ(1U, motionArgs.pointerCount);
10281 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
10282 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10283 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
10284 ASSERT_EQ(1U, motionArgs.pointerCount);
10285 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10286 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10287 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010288 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010289 ASSERT_EQ(2U, motionArgs.pointerCount);
10290 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN, motionArgs.action & AMOTION_EVENT_ACTION_MASK);
10291 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010292 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010293 // Two pointers' scaled relative coordinates from their initial centroid.
10294 // Initial y coordinates are 0 as y1 and y2 have the same value.
10295 float cookedX1 = (x1 - x2) / 2 * mPointerXZoomScale;
10296 float cookedX2 = (x2 - x1) / 2 * mPointerXZoomScale;
10297 // When pointers move, the new coordinates equal to the initial coordinates plus
10298 // scaled moving distance.
10299 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
10300 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10301 0, 0, 0, 0));
10302 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
10303 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
10304 0, 0, 0, 0));
10305
10306 // Move two fingers down again, expect one MOVE motion event.
10307 y1 += movingDistance;
10308 y2 += movingDistance;
10309
10310 processId(mapper, FIRST_TRACKING_ID);
10311 processPosition(mapper, x1, y1);
10312 processMTSync(mapper);
10313 processId(mapper, SECOND_TRACKING_ID);
10314 processPosition(mapper, x2, y2);
10315 processMTSync(mapper);
10316 processSync(mapper);
10317
10318 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10319 ASSERT_EQ(2U, motionArgs.pointerCount);
10320 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10321 ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
Harry Cutts2800fb02022-09-15 13:49:23 +000010322 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
HQ Liue6983c72022-04-19 22:14:56 +000010323 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
10324 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
10325 0, 0, 0, 0, 0));
10326 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
10327 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
10328 0, 0, 0, 0, 0));
10329}
10330
Harry Cutts39b7ca22022-10-05 15:55:48 +000010331TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) {
10332 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10333 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10334 NotifyMotionArgs motionArgs;
10335
10336 // Place two fingers down.
10337 int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
10338
10339 processId(mapper, FIRST_TRACKING_ID);
10340 processPosition(mapper, x1, y1);
10341 processMTSync(mapper);
10342 processId(mapper, SECOND_TRACKING_ID);
10343 processPosition(mapper, x2, y2);
10344 processMTSync(mapper);
10345 processSync(mapper);
10346
10347 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10348 ASSERT_EQ(1U, motionArgs.pointerCount);
10349 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
10350 ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
10351 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET));
10352 ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET));
10353
10354 // Move the two fingers down and to the left.
10355 int32_t movingDistance = 200;
10356 x1 -= movingDistance;
10357 y1 += movingDistance;
10358 x2 -= movingDistance;
10359 y2 += movingDistance;
10360
10361 processId(mapper, FIRST_TRACKING_ID);
10362 processPosition(mapper, x1, y1);
10363 processMTSync(mapper);
10364 processId(mapper, SECOND_TRACKING_ID);
10365 processPosition(mapper, x2, y2);
10366 processMTSync(mapper);
10367 processSync(mapper);
10368
10369 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
10370 ASSERT_EQ(1U, motionArgs.pointerCount);
10371 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
10372 ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
10373 ASSERT_LT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET), 0);
10374 ASSERT_GT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET), 0);
10375}
10376
Prabir Pradhanb80b6c02022-11-02 20:05:13 +000010377TEST_F(MultiTouchPointerModeTest, WhenViewportActiveStatusChanged_PointerGestureIsReset) {
10378 preparePointerMode(25 /*xResolution*/, 25 /*yResolution*/);
10379 mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
10380 MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
10381 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
10382
10383 // Start a stylus gesture.
10384 processKey(mapper, BTN_TOOL_PEN, 1);
10385 processId(mapper, FIRST_TRACKING_ID);
10386 processPosition(mapper, 100, 200);
10387 processSync(mapper);
10388 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10389 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
10390 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10391 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10392 // TODO(b/257078296): Pointer mode generates extra event.
10393 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10394 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
10395 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10396 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10397 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10398
10399 // Make the viewport inactive. This will put the device in disabled mode, and the ongoing stylus
10400 // gesture should be disabled.
10401 auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
10402 viewport->isActive = false;
10403 mFakePolicy->updateViewport(*viewport);
10404 configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
10405 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10406 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
10407 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10408 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10409 // TODO(b/257078296): Pointer mode generates extra event.
10410 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
10411 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
10412 WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
10413 WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS))));
10414 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
10415}
10416
Arthur Hung6d5b4b22022-01-21 07:21:10 +000010417// --- JoystickInputMapperTest ---
10418
10419class JoystickInputMapperTest : public InputMapperTest {
10420protected:
10421 static const int32_t RAW_X_MIN;
10422 static const int32_t RAW_X_MAX;
10423 static const int32_t RAW_Y_MIN;
10424 static const int32_t RAW_Y_MAX;
10425
10426 void SetUp() override {
10427 InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL);
10428 }
10429 void prepareAxes() {
10430 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
10431 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
10432 }
10433
10434 void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) {
10435 process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value);
10436 }
10437
10438 void processSync(JoystickInputMapper& mapper) {
10439 process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
10440 }
10441
10442 void prepareVirtualDisplay(int32_t orientation) {
10443 setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH,
10444 VIRTUAL_DISPLAY_HEIGHT, orientation, VIRTUAL_DISPLAY_UNIQUE_ID,
10445 NO_PORT, ViewportType::VIRTUAL);
10446 }
10447};
10448
10449const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767;
10450const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767;
10451const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767;
10452const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767;
10453
10454TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
10455 prepareAxes();
10456 JoystickInputMapper& mapper = addMapperAndConfigure<JoystickInputMapper>();
10457
10458 mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
10459
10460 prepareVirtualDisplay(DISPLAY_ORIENTATION_0);
10461
10462 // Send an axis event
10463 processAxis(mapper, ABS_X, 100);
10464 processSync(mapper);
10465
10466 NotifyMotionArgs args;
10467 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10468 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
10469
10470 // Send another axis event
10471 processAxis(mapper, ABS_Y, 100);
10472 processSync(mapper);
10473
10474 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
10475 ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
10476}
10477
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010478// --- PeripheralControllerTest ---
Chris Yee2b1e5c2021-03-10 22:45:12 -080010479
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010480class PeripheralControllerTest : public testing::Test {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010481protected:
10482 static const char* DEVICE_NAME;
10483 static const char* DEVICE_LOCATION;
10484 static const int32_t DEVICE_ID;
10485 static const int32_t DEVICE_GENERATION;
10486 static const int32_t DEVICE_CONTROLLER_NUMBER;
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010487 static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
Chris Yee2b1e5c2021-03-10 22:45:12 -080010488 static const int32_t EVENTHUB_ID;
10489
10490 std::shared_ptr<FakeEventHub> mFakeEventHub;
10491 sp<FakeInputReaderPolicy> mFakePolicy;
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010492 std::unique_ptr<TestInputListener> mFakeListener;
Chris Yee2b1e5c2021-03-10 22:45:12 -080010493 std::unique_ptr<InstrumentedInputReader> mReader;
10494 std::shared_ptr<InputDevice> mDevice;
10495
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010496 virtual void SetUp(ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010497 mFakeEventHub = std::make_unique<FakeEventHub>();
Siarhei Vishniakouaed7ad02022-08-03 15:04:33 -070010498 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010499 mFakeListener = std::make_unique<TestInputListener>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010500 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010501 *mFakeListener);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010502 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
10503 }
10504
10505 void SetUp() override { SetUp(DEVICE_CLASSES); }
10506
10507 void TearDown() override {
Siarhei Vishniakou18050092021-09-01 13:32:49 -070010508 mFakeListener.reset();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010509 mFakePolicy.clear();
10510 }
10511
Siarhei Vishniakou2935db72022-09-22 13:35:22 -070010512 std::list<NotifyArgs> configureDevice(uint32_t changes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010513 if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
10514 mReader->requestRefreshConfiguration(changes);
10515 mReader->loopOnce();
10516 }
Siarhei Vishniakou2935db72022-09-22 13:35:22 -070010517 return mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010518 }
10519
10520 std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
10521 const std::string& location, int32_t eventHubId,
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010522 ftl::Flags<InputDeviceClass> classes) {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010523 InputDeviceIdentifier identifier;
10524 identifier.name = name;
10525 identifier.location = location;
10526 std::shared_ptr<InputDevice> device =
10527 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
10528 identifier);
10529 mReader->pushNextDevice(device);
10530 mFakeEventHub->addDevice(eventHubId, name, classes);
10531 mReader->loopOnce();
10532 return device;
10533 }
10534
10535 template <class T, typename... Args>
10536 T& addControllerAndConfigure(Args... args) {
10537 T& controller = mDevice->addController<T>(EVENTHUB_ID, args...);
10538
10539 return controller;
10540 }
10541};
10542
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010543const char* PeripheralControllerTest::DEVICE_NAME = "device";
10544const char* PeripheralControllerTest::DEVICE_LOCATION = "BLUETOOTH";
10545const int32_t PeripheralControllerTest::DEVICE_ID = END_RESERVED_ID + 1000;
10546const int32_t PeripheralControllerTest::DEVICE_GENERATION = 2;
10547const int32_t PeripheralControllerTest::DEVICE_CONTROLLER_NUMBER = 0;
Dominik Laskowski2f01d772022-03-23 16:01:29 -070010548const ftl::Flags<InputDeviceClass> PeripheralControllerTest::DEVICE_CLASSES =
10549 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010550const int32_t PeripheralControllerTest::EVENTHUB_ID = 1;
Chris Yee2b1e5c2021-03-10 22:45:12 -080010551
10552// --- BatteryControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010553class BatteryControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010554protected:
10555 void SetUp() override {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010556 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::BATTERY);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010557 }
10558};
10559
10560TEST_F(BatteryControllerTest, GetBatteryCapacity) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010561 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010562
Harry Cuttsa5b71292022-11-28 12:56:17 +000010563 ASSERT_TRUE(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY));
10564 ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
10565 FakeEventHub::BATTERY_CAPACITY);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010566}
10567
10568TEST_F(BatteryControllerTest, GetBatteryStatus) {
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010569 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010570
Harry Cuttsa5b71292022-11-28 12:56:17 +000010571 ASSERT_TRUE(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY));
10572 ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
10573 FakeEventHub::BATTERY_STATUS);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010574}
10575
10576// --- LightControllerTest ---
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010577class LightControllerTest : public PeripheralControllerTest {
Chris Yee2b1e5c2021-03-10 22:45:12 -080010578protected:
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010579 void SetUp() override {
10580 PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::LIGHT);
10581 }
Chris Yee2b1e5c2021-03-10 22:45:12 -080010582};
10583
Chris Ye85758332021-05-16 23:05:17 -070010584TEST_F(LightControllerTest, MonoLight) {
10585 RawLightInfo infoMono = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010586 .name = "mono_light",
Chris Ye85758332021-05-16 23:05:17 -070010587 .maxBrightness = 255,
10588 .flags = InputLightClass::BRIGHTNESS,
10589 .path = ""};
10590 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010591
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010592 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010593 InputDeviceInfo info;
10594 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010595 std::vector<InputDeviceLightInfo> lights = info.getLights();
10596 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010597 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10598 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10599
10600 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
10601 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
10602}
10603
10604TEST_F(LightControllerTest, MonoKeyboardBacklight) {
10605 RawLightInfo infoMono = {.id = 1,
10606 .name = "mono_keyboard_backlight",
10607 .maxBrightness = 255,
10608 .flags = InputLightClass::BRIGHTNESS |
10609 InputLightClass::KEYBOARD_BACKLIGHT,
10610 .path = ""};
10611 mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
10612
10613 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10614 InputDeviceInfo info;
10615 controller.populateDeviceInfo(&info);
10616 std::vector<InputDeviceLightInfo> lights = info.getLights();
10617 ASSERT_EQ(1U, lights.size());
10618 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10619 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010620
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010621 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
10622 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010623}
10624
10625TEST_F(LightControllerTest, RGBLight) {
10626 RawLightInfo infoRed = {.id = 1,
10627 .name = "red",
10628 .maxBrightness = 255,
10629 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
10630 .path = ""};
10631 RawLightInfo infoGreen = {.id = 2,
10632 .name = "green",
10633 .maxBrightness = 255,
10634 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
10635 .path = ""};
10636 RawLightInfo infoBlue = {.id = 3,
10637 .name = "blue",
10638 .maxBrightness = 255,
10639 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
10640 .path = ""};
10641 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10642 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10643 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10644
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010645 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010646 InputDeviceInfo info;
10647 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010648 std::vector<InputDeviceLightInfo> lights = info.getLights();
10649 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010650 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10651 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10652 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10653
10654 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10655 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10656}
10657
10658TEST_F(LightControllerTest, CorrectRGBKeyboardBacklight) {
10659 RawLightInfo infoRed = {.id = 1,
10660 .name = "red_keyboard_backlight",
10661 .maxBrightness = 255,
10662 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED |
10663 InputLightClass::KEYBOARD_BACKLIGHT,
10664 .path = ""};
10665 RawLightInfo infoGreen = {.id = 2,
10666 .name = "green_keyboard_backlight",
10667 .maxBrightness = 255,
10668 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN |
10669 InputLightClass::KEYBOARD_BACKLIGHT,
10670 .path = ""};
10671 RawLightInfo infoBlue = {.id = 3,
10672 .name = "blue_keyboard_backlight",
10673 .maxBrightness = 255,
10674 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE |
10675 InputLightClass::KEYBOARD_BACKLIGHT,
10676 .path = ""};
10677 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10678 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10679 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10680
10681 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10682 InputDeviceInfo info;
10683 controller.populateDeviceInfo(&info);
10684 std::vector<InputDeviceLightInfo> lights = info.getLights();
10685 ASSERT_EQ(1U, lights.size());
10686 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10687 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10688 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10689
10690 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10691 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10692}
10693
10694TEST_F(LightControllerTest, IncorrectRGBKeyboardBacklight) {
10695 RawLightInfo infoRed = {.id = 1,
10696 .name = "red",
10697 .maxBrightness = 255,
10698 .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
10699 .path = ""};
10700 RawLightInfo infoGreen = {.id = 2,
10701 .name = "green",
10702 .maxBrightness = 255,
10703 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
10704 .path = ""};
10705 RawLightInfo infoBlue = {.id = 3,
10706 .name = "blue",
10707 .maxBrightness = 255,
10708 .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
10709 .path = ""};
10710 RawLightInfo infoGlobal = {.id = 3,
10711 .name = "global_keyboard_backlight",
10712 .maxBrightness = 255,
10713 .flags = InputLightClass::BRIGHTNESS | InputLightClass::GLOBAL |
10714 InputLightClass::KEYBOARD_BACKLIGHT,
10715 .path = ""};
10716 mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
10717 mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
10718 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
10719 mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoGlobal));
10720
10721 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10722 InputDeviceInfo info;
10723 controller.populateDeviceInfo(&info);
10724 std::vector<InputDeviceLightInfo> lights = info.getLights();
10725 ASSERT_EQ(1U, lights.size());
10726 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10727 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10728 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010729
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010730 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10731 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010732}
10733
10734TEST_F(LightControllerTest, MultiColorRGBLight) {
10735 RawLightInfo infoColor = {.id = 1,
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010736 .name = "multi_color",
Chris Yee2b1e5c2021-03-10 22:45:12 -080010737 .maxBrightness = 255,
10738 .flags = InputLightClass::BRIGHTNESS |
10739 InputLightClass::MULTI_INTENSITY |
10740 InputLightClass::MULTI_INDEX,
10741 .path = ""};
10742
10743 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
10744
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010745 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010746 InputDeviceInfo info;
10747 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010748 std::vector<InputDeviceLightInfo> lights = info.getLights();
10749 ASSERT_EQ(1U, lights.size());
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010750 ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
10751 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10752 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
10753
10754 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10755 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
10756}
10757
10758TEST_F(LightControllerTest, MultiColorRGBKeyboardBacklight) {
10759 RawLightInfo infoColor = {.id = 1,
10760 .name = "multi_color_keyboard_backlight",
10761 .maxBrightness = 255,
10762 .flags = InputLightClass::BRIGHTNESS |
10763 InputLightClass::MULTI_INTENSITY |
10764 InputLightClass::MULTI_INDEX |
10765 InputLightClass::KEYBOARD_BACKLIGHT,
10766 .path = ""};
10767
10768 mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
10769
10770 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
10771 InputDeviceInfo info;
10772 controller.populateDeviceInfo(&info);
10773 std::vector<InputDeviceLightInfo> lights = info.getLights();
10774 ASSERT_EQ(1U, lights.size());
10775 ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
10776 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10777 ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010778
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010779 ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10780 ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010781}
10782
10783TEST_F(LightControllerTest, PlayerIdLight) {
10784 RawLightInfo info1 = {.id = 1,
10785 .name = "player1",
10786 .maxBrightness = 255,
10787 .flags = InputLightClass::BRIGHTNESS,
10788 .path = ""};
10789 RawLightInfo info2 = {.id = 2,
10790 .name = "player2",
10791 .maxBrightness = 255,
10792 .flags = InputLightClass::BRIGHTNESS,
10793 .path = ""};
10794 RawLightInfo info3 = {.id = 3,
10795 .name = "player3",
10796 .maxBrightness = 255,
10797 .flags = InputLightClass::BRIGHTNESS,
10798 .path = ""};
10799 RawLightInfo info4 = {.id = 4,
10800 .name = "player4",
10801 .maxBrightness = 255,
10802 .flags = InputLightClass::BRIGHTNESS,
10803 .path = ""};
10804 mFakeEventHub->addRawLightInfo(info1.id, std::move(info1));
10805 mFakeEventHub->addRawLightInfo(info2.id, std::move(info2));
10806 mFakeEventHub->addRawLightInfo(info3.id, std::move(info3));
10807 mFakeEventHub->addRawLightInfo(info4.id, std::move(info4));
10808
Chris Ye1dd2e5c2021-04-04 23:12:41 -070010809 PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
Chris Yee2b1e5c2021-03-10 22:45:12 -080010810 InputDeviceInfo info;
10811 controller.populateDeviceInfo(&info);
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010812 std::vector<InputDeviceLightInfo> lights = info.getLights();
10813 ASSERT_EQ(1U, lights.size());
10814 ASSERT_EQ(InputDeviceLightType::PLAYER_ID, lights[0].type);
Vaibhav Devmurari82b37d62022-09-12 13:36:48 +000010815 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
10816 ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
Chris Yee2b1e5c2021-03-10 22:45:12 -080010817
Siarhei Vishniakou1983a712021-06-04 19:27:09 +000010818 ASSERT_FALSE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
10819 ASSERT_TRUE(controller.setLightPlayerId(lights[0].id, LIGHT_PLAYER_ID));
10820 ASSERT_EQ(controller.getLightPlayerId(lights[0].id).value_or(-1), LIGHT_PLAYER_ID);
Chris Yee2b1e5c2021-03-10 22:45:12 -080010821}
10822
Michael Wrightd02c5b62014-02-10 15:10:22 -080010823} // namespace android