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