blob: 8235c90da636f512b03b081de47d793784f24120 [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
Harry Cuttsd256daa2024-01-05 11:47:36 +000024#include "NotifyArgs.h"
25
Harry Cuttse6512e12022-11-28 18:44:01 +000026namespace android {
27
Harry Cuttsd256daa2024-01-05 11:47:36 +000028using testing::_;
Prabir Pradhan31d05c42024-07-24 21:19:08 +000029using testing::NiceMock;
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070030using testing::Return;
Prabir Pradhan31d05c42024-07-24 21:19:08 +000031using testing::ReturnRef;
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070032
Harry Cutts7ecbb992023-12-18 14:45:09 +000033void InputMapperUnitTest::SetUpWithBus(int bus) {
Byoungho Jungee6268f2023-10-30 17:27:26 +090034 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070035
Byoungho Jungee6268f2023-10-30 17:27:26 +090036 EXPECT_CALL(mMockInputReaderContext, getPolicy()).WillRepeatedly(Return(mFakePolicy.get()));
37
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070038 EXPECT_CALL(mMockInputReaderContext, getEventHub()).WillRepeatedly(Return(&mMockEventHub));
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070039
Harry Cutts1b5bde42023-12-18 16:08:29 +000040 mIdentifier.name = "device";
41 mIdentifier.location = "USB1";
Harry Cutts7ecbb992023-12-18 14:45:09 +000042 mIdentifier.bus = bus;
Harry Cutts1b5bde42023-12-18 16:08:29 +000043 EXPECT_CALL(mMockEventHub, getDeviceIdentifier(EVENTHUB_ID))
44 .WillRepeatedly(Return(mIdentifier));
Harry Cutts7ecbb992023-12-18 14:45:09 +000045 EXPECT_CALL(mMockEventHub, getConfiguration(EVENTHUB_ID)).WillRepeatedly([&](int32_t) {
46 return mPropertyMap;
47 });
Harry Cutts1b5bde42023-12-18 16:08:29 +000048
Prabir Pradhan31d05c42024-07-24 21:19:08 +000049 mDevice = std::make_unique<NiceMock<MockInputDevice>>(&mMockInputReaderContext, DEVICE_ID,
50 /*generation=*/2, mIdentifier);
51 ON_CALL((*mDevice), getConfiguration).WillByDefault(ReturnRef(mPropertyMap));
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070052 mDeviceContext = std::make_unique<InputDeviceContext>(*mDevice, EVENTHUB_ID);
53}
54
55void InputMapperUnitTest::setupAxis(int axis, bool valid, int32_t min, int32_t max,
Harry Cutts68ce2f62024-11-07 16:49:46 +000056 int32_t resolution, int32_t flat, int32_t fuzz) {
Harry Cutts207674d2024-06-06 18:53:41 +000057 EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis))
58 .WillRepeatedly(Return(valid ? std::optional<RawAbsoluteAxisInfo>{{
Harry Cutts207674d2024-06-06 18:53:41 +000059 .minValue = min,
60 .maxValue = max,
Harry Cutts68ce2f62024-11-07 16:49:46 +000061 .flat = flat,
62 .fuzz = fuzz,
Harry Cutts207674d2024-06-06 18:53:41 +000063 .resolution = resolution,
64 }}
65 : std::nullopt));
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070066}
67
68void InputMapperUnitTest::expectScanCodes(bool present, std::set<int> scanCodes) {
69 for (const auto& scanCode : scanCodes) {
70 EXPECT_CALL(mMockEventHub, hasScanCode(EVENTHUB_ID, scanCode))
71 .WillRepeatedly(testing::Return(present));
72 }
73}
74
75void InputMapperUnitTest::setScanCodeState(KeyState state, std::set<int> scanCodes) {
76 for (const auto& scanCode : scanCodes) {
77 EXPECT_CALL(mMockEventHub, getScanCodeState(EVENTHUB_ID, scanCode))
78 .WillRepeatedly(testing::Return(static_cast<int>(state)));
79 }
80}
81
82void InputMapperUnitTest::setKeyCodeState(KeyState state, std::set<int> keyCodes) {
83 for (const auto& keyCode : keyCodes) {
84 EXPECT_CALL(mMockEventHub, getKeyCodeState(EVENTHUB_ID, keyCode))
85 .WillRepeatedly(testing::Return(static_cast<int>(state)));
86 }
87}
88
Harry Cuttsaa931df2024-07-15 14:54:36 +000089void InputMapperUnitTest::setSwitchState(int32_t state, std::set<int32_t> switchCodes) {
90 for (const auto& switchCode : switchCodes) {
91 EXPECT_CALL(mMockEventHub, getSwitchState(EVENTHUB_ID, switchCode))
92 .WillRepeatedly(testing::Return(static_cast<int>(state)));
93 }
94}
95
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070096std::list<NotifyArgs> InputMapperUnitTest::process(int32_t type, int32_t code, int32_t value) {
Arpit Singh82e413e2023-10-10 19:30:58 +000097 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
98 return process(when, type, code, value);
99}
100
101std::list<NotifyArgs> InputMapperUnitTest::process(nsecs_t when, int32_t type, int32_t code,
102 int32_t value) {
Harry Cuttsd62330d2024-11-11 13:43:13 +0000103 return process(when, when, type, code, value);
104}
105
106std::list<NotifyArgs> InputMapperUnitTest::process(nsecs_t when, nsecs_t readTime, int32_t type,
107 int32_t code, int32_t value) {
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -0700108 RawEvent event;
Arpit Singh82e413e2023-10-10 19:30:58 +0000109 event.when = when;
Harry Cuttsd62330d2024-11-11 13:43:13 +0000110 event.readTime = readTime;
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -0700111 event.deviceId = mMapper->getDeviceContext().getEventHubId();
112 event.type = type;
113 event.code = code;
114 event.value = value;
Harry Cuttsa32a1192024-06-04 15:10:31 +0000115 return mMapper->process(event);
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -0700116}
117
Harry Cuttse6512e12022-11-28 18:44:01 +0000118const char* InputMapperTest::DEVICE_NAME = "device";
119const char* InputMapperTest::DEVICE_LOCATION = "USB1";
120const ftl::Flags<InputDeviceClass> InputMapperTest::DEVICE_CLASSES =
121 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
122
123void InputMapperTest::SetUp(ftl::Flags<InputDeviceClass> classes, int bus) {
124 mFakeEventHub = std::make_unique<FakeEventHub>();
125 mFakePolicy = sp<FakeInputReaderPolicy>::make();
126 mFakeListener = std::make_unique<TestInputListener>();
127 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy, *mFakeListener);
128 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes, bus);
129 // Consume the device reset notification generated when adding a new device.
130 mFakeListener->assertNotifyDeviceResetWasCalled();
131}
132
133void InputMapperTest::SetUp() {
134 SetUp(DEVICE_CLASSES);
135}
136
137void InputMapperTest::TearDown() {
138 mFakeListener.reset();
139 mFakePolicy.clear();
140}
141
142void InputMapperTest::addConfigurationProperty(const char* key, const char* value) {
143 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, key, value);
144}
145
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000146std::list<NotifyArgs> InputMapperTest::configureDevice(ConfigurationChanges changes) {
147 using namespace ftl::flag_operators;
148 if (!changes.any() ||
149 (changes.any(InputReaderConfiguration::Change::DISPLAY_INFO |
150 InputReaderConfiguration::Change::POINTER_CAPTURE |
151 InputReaderConfiguration::Change::DEVICE_TYPE))) {
Harry Cuttse6512e12022-11-28 18:44:01 +0000152 mReader->requestRefreshConfiguration(changes);
153 mReader->loopOnce();
154 }
155 std::list<NotifyArgs> out =
156 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
157 // Loop the reader to flush the input listener queue.
158 for (const NotifyArgs& args : out) {
159 mFakeListener->notify(args);
160 }
161 mReader->loopOnce();
162 return out;
163}
164
165std::shared_ptr<InputDevice> InputMapperTest::newDevice(int32_t deviceId, const std::string& name,
166 const std::string& location,
167 int32_t eventHubId,
168 ftl::Flags<InputDeviceClass> classes,
169 int bus) {
170 InputDeviceIdentifier identifier;
171 identifier.name = name;
172 identifier.location = location;
173 identifier.bus = bus;
174 std::shared_ptr<InputDevice> device =
175 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
176 identifier);
177 mReader->pushNextDevice(device);
178 mFakeEventHub->addDevice(eventHubId, name, classes, bus);
179 mReader->loopOnce();
180 return device;
181}
182
Linnan Li13bf76a2024-05-05 19:18:02 +0800183void InputMapperTest::setDisplayInfoAndReconfigure(ui::LogicalDisplayId displayId, int32_t width,
184 int32_t height, ui::Rotation orientation,
Harry Cuttse6512e12022-11-28 18:44:01 +0000185 const std::string& uniqueId,
186 std::optional<uint8_t> physicalPort,
187 ViewportType viewportType) {
188 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, /* isActive= */ true,
189 uniqueId, physicalPort, viewportType);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000190 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Harry Cuttse6512e12022-11-28 18:44:01 +0000191}
192
193void InputMapperTest::clearViewports() {
194 mFakePolicy->clearViewports();
195}
196
197std::list<NotifyArgs> InputMapperTest::process(InputMapper& mapper, nsecs_t when, nsecs_t readTime,
198 int32_t type, int32_t code, int32_t value) {
199 RawEvent event;
200 event.when = when;
201 event.readTime = readTime;
202 event.deviceId = mapper.getDeviceContext().getEventHubId();
203 event.type = type;
204 event.code = code;
205 event.value = value;
Harry Cuttsa32a1192024-06-04 15:10:31 +0000206 std::list<NotifyArgs> processArgList = mapper.process(event);
Harry Cuttse6512e12022-11-28 18:44:01 +0000207 for (const NotifyArgs& args : processArgList) {
208 mFakeListener->notify(args);
209 }
210 // Loop the reader to flush the input listener queue.
211 mReader->loopOnce();
212 return processArgList;
213}
214
215void InputMapperTest::resetMapper(InputMapper& mapper, nsecs_t when) {
216 const auto resetArgs = mapper.reset(when);
217 for (const auto args : resetArgs) {
218 mFakeListener->notify(args);
219 }
220 // Loop the reader to flush the input listener queue.
221 mReader->loopOnce();
222}
223
224std::list<NotifyArgs> InputMapperTest::handleTimeout(InputMapper& mapper, nsecs_t when) {
225 std::list<NotifyArgs> generatedArgs = mapper.timeoutExpired(when);
226 for (const NotifyArgs& args : generatedArgs) {
227 mFakeListener->notify(args);
228 }
229 // Loop the reader to flush the input listener queue.
230 mReader->loopOnce();
231 return generatedArgs;
232}
233
Harry Cutts7ecbb992023-12-18 14:45:09 +0000234void assertMotionRange(const InputDeviceInfo& info, int32_t axis, uint32_t source, float min,
235 float max, float flat, float fuzz) {
Harry Cuttse6512e12022-11-28 18:44:01 +0000236 const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
237 ASSERT_TRUE(range != nullptr) << "Axis: " << axis << " Source: " << source;
238 ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
239 ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
240 ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
241 ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
242 ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
243 ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
244}
245
Harry Cutts7ecbb992023-12-18 14:45:09 +0000246void assertPointerCoords(const PointerCoords& coords, float x, float y, float pressure, float size,
247 float touchMajor, float touchMinor, float toolMajor, float toolMinor,
248 float orientation, float distance, float scaledAxisEpsilon) {
Harry Cuttse6512e12022-11-28 18:44:01 +0000249 ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), scaledAxisEpsilon);
250 ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), scaledAxisEpsilon);
251 ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
252 ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
253 ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), scaledAxisEpsilon);
254 ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), scaledAxisEpsilon);
255 ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), scaledAxisEpsilon);
256 ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), scaledAxisEpsilon);
257 ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
258 ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
259}
260
Harry Cuttse6512e12022-11-28 18:44:01 +0000261} // namespace android