blob: 36be684f96aa91d4458bcd945fe186ac935a57d8 [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>
22
23namespace android {
24
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070025using testing::Return;
26
27void InputMapperUnitTest::SetUp() {
28 mFakePointerController = std::make_shared<FakePointerController>();
29 mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
Siarhei Vishniakou5197ce62023-09-19 08:27:05 -070030 mFakePointerController->setPosition(INITIAL_CURSOR_X, INITIAL_CURSOR_Y);
Byoungho Jungee6268f2023-10-30 17:27:26 +090031 mFakePolicy = sp<FakeInputReaderPolicy>::make();
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070032
33 EXPECT_CALL(mMockInputReaderContext, getPointerController(DEVICE_ID))
34 .WillRepeatedly(Return(mFakePointerController));
35
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));
39 InputDeviceIdentifier identifier;
40 identifier.name = "device";
41 identifier.location = "USB1";
42 identifier.bus = 0;
43
44 EXPECT_CALL(mMockEventHub, getDeviceIdentifier(EVENTHUB_ID)).WillRepeatedly(Return(identifier));
45 mDevice = std::make_unique<InputDevice>(&mMockInputReaderContext, DEVICE_ID,
46 /*generation=*/2, identifier);
47 mDeviceContext = std::make_unique<InputDeviceContext>(*mDevice, EVENTHUB_ID);
48}
49
50void InputMapperUnitTest::setupAxis(int axis, bool valid, int32_t min, int32_t max,
51 int32_t resolution) {
52 EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis, testing::_))
53 .WillRepeatedly([=](int32_t, int32_t, RawAbsoluteAxisInfo* outAxisInfo) {
54 outAxisInfo->valid = valid;
55 outAxisInfo->minValue = min;
56 outAxisInfo->maxValue = max;
57 outAxisInfo->flat = 0;
58 outAxisInfo->fuzz = 0;
59 outAxisInfo->resolution = resolution;
60 return valid ? OK : -1;
61 });
62}
63
64void InputMapperUnitTest::expectScanCodes(bool present, std::set<int> scanCodes) {
65 for (const auto& scanCode : scanCodes) {
66 EXPECT_CALL(mMockEventHub, hasScanCode(EVENTHUB_ID, scanCode))
67 .WillRepeatedly(testing::Return(present));
68 }
69}
70
71void InputMapperUnitTest::setScanCodeState(KeyState state, std::set<int> scanCodes) {
72 for (const auto& scanCode : scanCodes) {
73 EXPECT_CALL(mMockEventHub, getScanCodeState(EVENTHUB_ID, scanCode))
74 .WillRepeatedly(testing::Return(static_cast<int>(state)));
75 }
76}
77
78void InputMapperUnitTest::setKeyCodeState(KeyState state, std::set<int> keyCodes) {
79 for (const auto& keyCode : keyCodes) {
80 EXPECT_CALL(mMockEventHub, getKeyCodeState(EVENTHUB_ID, keyCode))
81 .WillRepeatedly(testing::Return(static_cast<int>(state)));
82 }
83}
84
85std::list<NotifyArgs> InputMapperUnitTest::process(int32_t type, int32_t code, int32_t value) {
Arpit Singh82e413e2023-10-10 19:30:58 +000086 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
87 return process(when, type, code, value);
88}
89
90std::list<NotifyArgs> InputMapperUnitTest::process(nsecs_t when, int32_t type, int32_t code,
91 int32_t value) {
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070092 RawEvent event;
Arpit Singh82e413e2023-10-10 19:30:58 +000093 event.when = when;
94 event.readTime = when;
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070095 event.deviceId = mMapper->getDeviceContext().getEventHubId();
96 event.type = type;
97 event.code = code;
98 event.value = value;
99 return mMapper->process(&event);
100}
101
Harry Cuttse6512e12022-11-28 18:44:01 +0000102const char* InputMapperTest::DEVICE_NAME = "device";
103const char* InputMapperTest::DEVICE_LOCATION = "USB1";
104const ftl::Flags<InputDeviceClass> InputMapperTest::DEVICE_CLASSES =
105 ftl::Flags<InputDeviceClass>(0); // not needed for current tests
106
107void InputMapperTest::SetUp(ftl::Flags<InputDeviceClass> classes, int bus) {
108 mFakeEventHub = std::make_unique<FakeEventHub>();
109 mFakePolicy = sp<FakeInputReaderPolicy>::make();
110 mFakeListener = std::make_unique<TestInputListener>();
111 mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy, *mFakeListener);
112 mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes, bus);
113 // Consume the device reset notification generated when adding a new device.
114 mFakeListener->assertNotifyDeviceResetWasCalled();
115}
116
117void InputMapperTest::SetUp() {
118 SetUp(DEVICE_CLASSES);
119}
120
121void InputMapperTest::TearDown() {
122 mFakeListener.reset();
123 mFakePolicy.clear();
124}
125
126void InputMapperTest::addConfigurationProperty(const char* key, const char* value) {
127 mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, key, value);
128}
129
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000130std::list<NotifyArgs> InputMapperTest::configureDevice(ConfigurationChanges changes) {
131 using namespace ftl::flag_operators;
132 if (!changes.any() ||
133 (changes.any(InputReaderConfiguration::Change::DISPLAY_INFO |
134 InputReaderConfiguration::Change::POINTER_CAPTURE |
135 InputReaderConfiguration::Change::DEVICE_TYPE))) {
Harry Cuttse6512e12022-11-28 18:44:01 +0000136 mReader->requestRefreshConfiguration(changes);
137 mReader->loopOnce();
138 }
139 std::list<NotifyArgs> out =
140 mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes);
141 // Loop the reader to flush the input listener queue.
142 for (const NotifyArgs& args : out) {
143 mFakeListener->notify(args);
144 }
145 mReader->loopOnce();
146 return out;
147}
148
149std::shared_ptr<InputDevice> InputMapperTest::newDevice(int32_t deviceId, const std::string& name,
150 const std::string& location,
151 int32_t eventHubId,
152 ftl::Flags<InputDeviceClass> classes,
153 int bus) {
154 InputDeviceIdentifier identifier;
155 identifier.name = name;
156 identifier.location = location;
157 identifier.bus = bus;
158 std::shared_ptr<InputDevice> device =
159 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
160 identifier);
161 mReader->pushNextDevice(device);
162 mFakeEventHub->addDevice(eventHubId, name, classes, bus);
163 mReader->loopOnce();
164 return device;
165}
166
167void InputMapperTest::setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
168 ui::Rotation orientation,
169 const std::string& uniqueId,
170 std::optional<uint8_t> physicalPort,
171 ViewportType viewportType) {
172 mFakePolicy->addDisplayViewport(displayId, width, height, orientation, /* isActive= */ true,
173 uniqueId, physicalPort, viewportType);
Prabir Pradhan4bf6d452023-04-18 21:26:56 +0000174 configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
Harry Cuttse6512e12022-11-28 18:44:01 +0000175}
176
177void InputMapperTest::clearViewports() {
178 mFakePolicy->clearViewports();
179}
180
181std::list<NotifyArgs> InputMapperTest::process(InputMapper& mapper, nsecs_t when, nsecs_t readTime,
182 int32_t type, int32_t code, int32_t value) {
183 RawEvent event;
184 event.when = when;
185 event.readTime = readTime;
186 event.deviceId = mapper.getDeviceContext().getEventHubId();
187 event.type = type;
188 event.code = code;
189 event.value = value;
190 std::list<NotifyArgs> processArgList = mapper.process(&event);
191 for (const NotifyArgs& args : processArgList) {
192 mFakeListener->notify(args);
193 }
194 // Loop the reader to flush the input listener queue.
195 mReader->loopOnce();
196 return processArgList;
197}
198
199void InputMapperTest::resetMapper(InputMapper& mapper, nsecs_t when) {
200 const auto resetArgs = mapper.reset(when);
201 for (const auto args : resetArgs) {
202 mFakeListener->notify(args);
203 }
204 // Loop the reader to flush the input listener queue.
205 mReader->loopOnce();
206}
207
208std::list<NotifyArgs> InputMapperTest::handleTimeout(InputMapper& mapper, nsecs_t when) {
209 std::list<NotifyArgs> generatedArgs = mapper.timeoutExpired(when);
210 for (const NotifyArgs& args : generatedArgs) {
211 mFakeListener->notify(args);
212 }
213 // Loop the reader to flush the input listener queue.
214 mReader->loopOnce();
215 return generatedArgs;
216}
217
218void InputMapperTest::assertMotionRange(const InputDeviceInfo& info, int32_t axis, uint32_t source,
219 float min, float max, float flat, float fuzz) {
220 const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
221 ASSERT_TRUE(range != nullptr) << "Axis: " << axis << " Source: " << source;
222 ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
223 ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
224 ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
225 ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
226 ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
227 ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
228}
229
230void InputMapperTest::assertPointerCoords(const PointerCoords& coords, float x, float y,
231 float pressure, float size, float touchMajor,
232 float touchMinor, float toolMajor, float toolMinor,
233 float orientation, float distance,
234 float scaledAxisEpsilon) {
235 ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), scaledAxisEpsilon);
236 ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), scaledAxisEpsilon);
237 ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
238 ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
239 ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), scaledAxisEpsilon);
240 ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), scaledAxisEpsilon);
241 ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), scaledAxisEpsilon);
242 ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), scaledAxisEpsilon);
243 ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
244 ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
245}
246
Harry Cuttse6512e12022-11-28 18:44:01 +0000247} // namespace android