blob: 5f43bd225b56bdd7e328282312580715e3247930 [file] [log] [blame]
Harry Cuttse6512e12022-11-28 18:44:01 +00001/*
2 * Copyright 2022 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
17#include "InputMapperTest.h"
18
19#include <InputReaderBase.h>
20#include <gtest/gtest.h>
21#include <ui/Rotation.h>
Harry Cutts1b5bde42023-12-18 16:08:29 +000022#include <utils/Timers.h>
Harry Cuttse6512e12022-11-28 18:44:01 +000023
24namespace android {
25
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070026using testing::Return;
27
Harry Cutts7ecbb992023-12-18 14:45:09 +000028void InputMapperUnitTest::SetUpWithBus(int bus) {
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070029 mFakePointerController = std::make_shared<FakePointerController>();
30 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
Siarhei Vishniakou5197ce62023-09-19 08:27:05 -070031 mFakePointerController->setPosition(INITIAL_CURSOR_X, INITIAL_CURSOR_Y);
Byoungho Jungee6268f2023-10-30 17:27:26 +090032 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070033
34 EXPECT_CALL(mMockInputReaderContext, getPointerController(DEVICE_ID))
35 .WillRepeatedly(Return(mFakePointerController));
36
Byoungho Jungee6268f2023-10-30 17:27:26 +090037 EXPECT_CALL(mMockInputReaderContext, getPolicy()).WillRepeatedly(Return(mFakePolicy.get()));
38
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070039 EXPECT_CALL(mMockInputReaderContext, getEventHub()).WillRepeatedly(Return(&mMockEventHub));
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070040
Harry Cutts1b5bde42023-12-18 16:08:29 +000041 mIdentifier.name = "device";
42 mIdentifier.location = "USB1";
Harry Cutts7ecbb992023-12-18 14:45:09 +000043 mIdentifier.bus = bus;
Harry Cutts1b5bde42023-12-18 16:08:29 +000044 EXPECT_CALL(mMockEventHub, getDeviceIdentifier(EVENTHUB_ID))
45 .WillRepeatedly(Return(mIdentifier));
Harry Cutts7ecbb992023-12-18 14:45:09 +000046 EXPECT_CALL(mMockEventHub, getConfiguration(EVENTHUB_ID)).WillRepeatedly([&](int32_t) {
47 return mPropertyMap;
48 });
Harry Cutts1b5bde42023-12-18 16:08:29 +000049}
50
51void InputMapperUnitTest::createDevice() {
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070052 mDevice = std::make_unique<InputDevice>(&mMockInputReaderContext, DEVICE_ID,
Harry Cutts1b5bde42023-12-18 16:08:29 +000053 /*generation=*/2, mIdentifier);
54 mDevice->addEmptyEventHubDevice(EVENTHUB_ID);
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070055 mDeviceContext = std::make_unique<InputDeviceContext>(*mDevice, EVENTHUB_ID);
Harry Cutts1b5bde42023-12-18 16:08:29 +000056 std::list<NotifyArgs> _ =
57 mDevice->configure(systemTime(), mReaderConfiguration, /*changes=*/{});
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070058}
59
60void InputMapperUnitTest::setupAxis(int axis, bool valid, int32_t min, int32_t max,
61 int32_t resolution) {
62 EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis, testing::_))
63 .WillRepeatedly([=](int32_t, int32_t, RawAbsoluteAxisInfo* outAxisInfo) {
64 outAxisInfo->valid = valid;
65 outAxisInfo->minValue = min;
66 outAxisInfo->maxValue = max;
67 outAxisInfo->flat = 0;
68 outAxisInfo->fuzz = 0;
69 outAxisInfo->resolution = resolution;
70 return valid ? OK : -1;
71 });
72}
73
74void InputMapperUnitTest::expectScanCodes(bool present, std::set<int> scanCodes) {
75 for (const auto& scanCode : scanCodes) {
76 EXPECT_CALL(mMockEventHub, hasScanCode(EVENTHUB_ID, scanCode))
77 .WillRepeatedly(testing::Return(present));
78 }
79}
80
81void InputMapperUnitTest::setScanCodeState(KeyState state, std::set<int> scanCodes) {
82 for (const auto& scanCode : scanCodes) {
83 EXPECT_CALL(mMockEventHub, getScanCodeState(EVENTHUB_ID, scanCode))
84 .WillRepeatedly(testing::Return(static_cast<int>(state)));
85 }
86}
87
88void InputMapperUnitTest::setKeyCodeState(KeyState state, std::set<int> keyCodes) {
89 for (const auto& keyCode : keyCodes) {
90 EXPECT_CALL(mMockEventHub, getKeyCodeState(EVENTHUB_ID, keyCode))
91 .WillRepeatedly(testing::Return(static_cast<int>(state)));
92 }
93}
94
95std::list<NotifyArgs> InputMapperUnitTest::process(int32_t type, int32_t code, int32_t value) {
Arpit Singh82e413e2023-10-10 19:30:58 +000096 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
97 return process(when, type, code, value);
98}
99
100std::list<NotifyArgs> InputMapperUnitTest::process(nsecs_t when, int32_t type, int32_t code,
101 int32_t value) {
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -0700102 RawEvent event;
Arpit Singh82e413e2023-10-10 19:30:58 +0000103 event.when = when;
104 event.readTime = when;
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -0700105 event.deviceId = mMapper->getDeviceContext().getEventHubId();
106 event.type = type;
107 event.code = code;
108 event.value = value;
109 return mMapper->process(&event);
110}
111
Harry Cuttse6512e12022-11-28 18:44:01 +0000112const char* InputMapperTest::DEVICE_NAME = "device";
113const char* InputMapperTest::DEVICE_LOCATION = "USB1";
114const ftl::Flags<InputDeviceClass> InputMapperTest::DEVICE_CLASSES =
115 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
116
117void InputMapperTest::SetUp(ftl::Flags<InputDeviceClass> classes, int bus) {
118 mFakeEventHub = std::make_unique<FakeEventHub>();
119 mFakePolicy = sp<FakeInputReaderPolicy>::make();
120 mFakeListener = std::make_unique<TestInputListener>();
121 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy, *mFakeListener);
122 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes, bus);
123 // Consume the device reset notification generated when adding a new device.
124 mFakeListener->assertNotifyDeviceResetWasCalled();
125}
126
127void InputMapperTest::SetUp() {
128 SetUp(DEVICE_CLASSES);
129}
130
131void InputMapperTest::TearDown() {
132 mFakeListener.reset();
133 mFakePolicy.clear();
134}
135
136void InputMapperTest::addConfigurationProperty(const char* key, const char* value) {
137 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, key, value);
138}
139
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000140std::list<NotifyArgs> InputMapperTest::configureDevice(ConfigurationChanges changes) {
141 using namespace ftl::flag_operators;
142 if (!changes.any() ||
143 (changes.any(InputReaderConfiguration::Change::DISPLAY_INFO |
144 InputReaderConfiguration::Change::POINTER_CAPTURE |
145 InputReaderConfiguration::Change::DEVICE_TYPE))) {
Harry Cuttse6512e12022-11-28 18:44:01 +0000146 mReader->requestRefreshConfiguration(changes);
147 mReader->loopOnce();
148 }
149 std::list<NotifyArgs> out =
150 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
151 // Loop the reader to flush the input listener queue.
152 for (const NotifyArgs& args : out) {
153 mFakeListener->notify(args);
154 }
155 mReader->loopOnce();
156 return out;
157}
158
159std::shared_ptr<InputDevice> InputMapperTest::newDevice(int32_t deviceId, const std::string& name,
160 const std::string& location,
161 int32_t eventHubId,
162 ftl::Flags<InputDeviceClass> classes,
163 int bus) {
164 InputDeviceIdentifier identifier;
165 identifier.name = name;
166 identifier.location = location;
167 identifier.bus = bus;
168 std::shared_ptr<InputDevice> device =
169 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
170 identifier);
171 mReader->pushNextDevice(device);
172 mFakeEventHub->addDevice(eventHubId, name, classes, bus);
173 mReader->loopOnce();
174 return device;
175}
176
177void InputMapperTest::setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
178 ui::Rotation orientation,
179 const std::string& uniqueId,
180 std::optional<uint8_t> physicalPort,
181 ViewportType viewportType) {
182 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, /* isActive= */ true,
183 uniqueId, physicalPort, viewportType);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000184 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Harry Cuttse6512e12022-11-28 18:44:01 +0000185}
186
187void InputMapperTest::clearViewports() {
188 mFakePolicy->clearViewports();
189}
190
191std::list<NotifyArgs> InputMapperTest::process(InputMapper& mapper, nsecs_t when, nsecs_t readTime,
192 int32_t type, int32_t code, int32_t value) {
193 RawEvent event;
194 event.when = when;
195 event.readTime = readTime;
196 event.deviceId = mapper.getDeviceContext().getEventHubId();
197 event.type = type;
198 event.code = code;
199 event.value = value;
200 std::list<NotifyArgs> processArgList = mapper.process(&event);
201 for (const NotifyArgs& args : processArgList) {
202 mFakeListener->notify(args);
203 }
204 // Loop the reader to flush the input listener queue.
205 mReader->loopOnce();
206 return processArgList;
207}
208
209void InputMapperTest::resetMapper(InputMapper& mapper, nsecs_t when) {
210 const auto resetArgs = mapper.reset(when);
211 for (const auto args : resetArgs) {
212 mFakeListener->notify(args);
213 }
214 // Loop the reader to flush the input listener queue.
215 mReader->loopOnce();
216}
217
218std::list<NotifyArgs> InputMapperTest::handleTimeout(InputMapper& mapper, nsecs_t when) {
219 std::list<NotifyArgs> generatedArgs = mapper.timeoutExpired(when);
220 for (const NotifyArgs& args : generatedArgs) {
221 mFakeListener->notify(args);
222 }
223 // Loop the reader to flush the input listener queue.
224 mReader->loopOnce();
225 return generatedArgs;
226}
227
Harry Cutts7ecbb992023-12-18 14:45:09 +0000228void assertMotionRange(const InputDeviceInfo& info, int32_t axis, uint32_t source, float min,
229 float max, float flat, float fuzz) {
Harry Cuttse6512e12022-11-28 18:44:01 +0000230 const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
231 ASSERT_TRUE(range != nullptr) << "Axis: " << axis << " Source: " << source;
232 ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
233 ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
234 ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
235 ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
236 ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
237 ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
238}
239
Harry Cutts7ecbb992023-12-18 14:45:09 +0000240void assertPointerCoords(const PointerCoords& coords, float x, float y, float pressure, float size,
241 float touchMajor, float touchMinor, float toolMajor, float toolMinor,
242 float orientation, float distance, float scaledAxisEpsilon) {
Harry Cuttse6512e12022-11-28 18:44:01 +0000243 ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), scaledAxisEpsilon);
244 ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), scaledAxisEpsilon);
245 ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
246 ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
247 ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), scaledAxisEpsilon);
248 ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), scaledAxisEpsilon);
249 ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), scaledAxisEpsilon);
250 ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), scaledAxisEpsilon);
251 ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
252 ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
253}
254
Harry Cuttse6512e12022-11-28 18:44:01 +0000255} // namespace android