xref: /aosp_15_r20/frameworks/native/services/inputflinger/tests/FakeInputReaderPolicy.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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 "FakeInputReaderPolicy.h"
18 
19 #include <android-base/properties.h>
20 #include <android-base/thread_annotations.h>
21 #include <gtest/gtest.h>
22 
23 #include "TestConstants.h"
24 #include "ui/Rotation.h"
25 
26 namespace android {
27 
28 namespace {
29 
30 static const int HW_TIMEOUT_MULTIPLIER = base::GetIntProperty("ro.hw_timeout_multiplier", 1);
31 
32 } // namespace
33 
assertInputDevicesChanged()34 void FakeInputReaderPolicy::assertInputDevicesChanged() {
35     waitForInputDevices(
36             [](bool devicesChanged) {
37                 if (!devicesChanged) {
38                     FAIL() << "Timed out waiting for notifyInputDevicesChanged() to be called.";
39                 }
40             },
41             ADD_INPUT_DEVICE_TIMEOUT);
42 }
43 
assertInputDevicesNotChanged()44 void FakeInputReaderPolicy::assertInputDevicesNotChanged() {
45     waitForInputDevices(
46             [](bool devicesChanged) {
47                 if (devicesChanged) {
48                     FAIL() << "Expected notifyInputDevicesChanged() to not be called.";
49                 }
50             },
51             INPUT_DEVICES_DIDNT_CHANGE_TIMEOUT);
52 }
53 
assertStylusGestureNotified(int32_t deviceId)54 void FakeInputReaderPolicy::assertStylusGestureNotified(int32_t deviceId) {
55     std::unique_lock lock(mLock);
56     base::ScopedLockAssertion assumeLocked(mLock);
57 
58     const bool success =
59             mStylusGestureNotifiedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
60                 return mDeviceIdOfNotifiedStylusGesture.has_value();
61             });
62     ASSERT_TRUE(success) << "Timed out waiting for stylus gesture to be notified";
63     ASSERT_EQ(deviceId, *mDeviceIdOfNotifiedStylusGesture);
64     mDeviceIdOfNotifiedStylusGesture.reset();
65 }
66 
assertStylusGestureNotNotified()67 void FakeInputReaderPolicy::assertStylusGestureNotNotified() {
68     std::scoped_lock lock(mLock);
69     ASSERT_FALSE(mDeviceIdOfNotifiedStylusGesture);
70 }
71 
assertTouchpadHardwareStateNotified()72 void FakeInputReaderPolicy::assertTouchpadHardwareStateNotified() {
73     std::unique_lock lock(mLock);
74     base::ScopedLockAssertion assumeLocked(mLock);
75 
76     const bool success =
77             mTouchpadHardwareStateNotified.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
78                 return mTouchpadHardwareState.has_value();
79             });
80     ASSERT_TRUE(success) << "Timed out waiting for hardware state to be notified";
81 }
82 
assertTouchpadThreeFingerTapNotified()83 void FakeInputReaderPolicy::assertTouchpadThreeFingerTapNotified() {
84     std::unique_lock lock(mLock);
85     base::ScopedLockAssertion assumeLocked(mLock);
86 
87     const bool success =
88             mTouchpadThreeFingerTapNotified.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
89                 return mTouchpadThreeFingerTapHasBeenReported;
90             });
91     ASSERT_TRUE(success) << "Timed out waiting for three-finger tap to be notified";
92 }
93 
clearViewports()94 void FakeInputReaderPolicy::clearViewports() {
95     mViewports.clear();
96     mConfig.setDisplayViewports(mViewports);
97 }
98 
getDisplayViewportByUniqueId(const std::string & uniqueId) const99 std::optional<DisplayViewport> FakeInputReaderPolicy::getDisplayViewportByUniqueId(
100         const std::string& uniqueId) const {
101     return mConfig.getDisplayViewportByUniqueId(uniqueId);
102 }
getDisplayViewportByType(ViewportType type) const103 std::optional<DisplayViewport> FakeInputReaderPolicy::getDisplayViewportByType(
104         ViewportType type) const {
105     return mConfig.getDisplayViewportByType(type);
106 }
107 
getDisplayViewportByPort(uint8_t displayPort) const108 std::optional<DisplayViewport> FakeInputReaderPolicy::getDisplayViewportByPort(
109         uint8_t displayPort) const {
110     return mConfig.getDisplayViewportByPort(displayPort);
111 }
112 
addDisplayViewport(DisplayViewport viewport)113 void FakeInputReaderPolicy::addDisplayViewport(DisplayViewport viewport) {
114     mViewports.push_back(std::move(viewport));
115     mConfig.setDisplayViewports(mViewports);
116 }
117 
addDisplayViewport(ui::LogicalDisplayId displayId,int32_t width,int32_t height,ui::Rotation orientation,bool isActive,const std::string & uniqueId,std::optional<uint8_t> physicalPort,ViewportType type)118 void FakeInputReaderPolicy::addDisplayViewport(ui::LogicalDisplayId displayId, int32_t width,
119                                                int32_t height, ui::Rotation orientation,
120                                                bool isActive, const std::string& uniqueId,
121                                                std::optional<uint8_t> physicalPort,
122                                                ViewportType type) {
123     const bool isRotated = orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270;
124     DisplayViewport v;
125     v.displayId = displayId;
126     v.orientation = orientation;
127     v.logicalLeft = 0;
128     v.logicalTop = 0;
129     v.logicalRight = isRotated ? height : width;
130     v.logicalBottom = isRotated ? width : height;
131     v.physicalLeft = 0;
132     v.physicalTop = 0;
133     v.physicalRight = isRotated ? height : width;
134     v.physicalBottom = isRotated ? width : height;
135     v.deviceWidth = isRotated ? height : width;
136     v.deviceHeight = isRotated ? width : height;
137     v.isActive = isActive;
138     v.uniqueId = uniqueId;
139     v.physicalPort = physicalPort;
140     v.type = type;
141 
142     addDisplayViewport(v);
143 }
144 
updateViewport(const DisplayViewport & viewport)145 bool FakeInputReaderPolicy::updateViewport(const DisplayViewport& viewport) {
146     size_t count = mViewports.size();
147     for (size_t i = 0; i < count; i++) {
148         const DisplayViewport& currentViewport = mViewports[i];
149         if (currentViewport.displayId == viewport.displayId) {
150             mViewports[i] = viewport;
151             mConfig.setDisplayViewports(mViewports);
152             return true;
153         }
154     }
155     // no viewport found.
156     return false;
157 }
158 
addExcludedDeviceName(const std::string & deviceName)159 void FakeInputReaderPolicy::addExcludedDeviceName(const std::string& deviceName) {
160     mConfig.excludedDeviceNames.push_back(deviceName);
161 }
162 
addInputPortAssociation(const std::string & inputPort,uint8_t displayPort)163 void FakeInputReaderPolicy::addInputPortAssociation(const std::string& inputPort,
164                                                     uint8_t displayPort) {
165     mConfig.inputPortToDisplayPortAssociations.insert({inputPort, displayPort});
166 }
167 
addDeviceTypeAssociation(const std::string & inputPort,const std::string & type)168 void FakeInputReaderPolicy::addDeviceTypeAssociation(const std::string& inputPort,
169                                                      const std::string& type) {
170     mConfig.deviceTypeAssociations.insert({inputPort, type});
171 }
172 
addInputUniqueIdAssociation(const std::string & inputUniqueId,const std::string & displayUniqueId)173 void FakeInputReaderPolicy::addInputUniqueIdAssociation(const std::string& inputUniqueId,
174                                                         const std::string& displayUniqueId) {
175     mConfig.inputPortToDisplayUniqueIdAssociations.insert({inputUniqueId, displayUniqueId});
176 }
177 
addKeyboardLayoutAssociation(const std::string & inputUniqueId,const KeyboardLayoutInfo & layoutInfo)178 void FakeInputReaderPolicy::addKeyboardLayoutAssociation(const std::string& inputUniqueId,
179                                                          const KeyboardLayoutInfo& layoutInfo) {
180     mConfig.keyboardLayoutAssociations.insert({inputUniqueId, layoutInfo});
181 }
182 
addDisabledDevice(int32_t deviceId)183 void FakeInputReaderPolicy::addDisabledDevice(int32_t deviceId) {
184     mConfig.disabledDevices.insert(deviceId);
185 }
186 
removeDisabledDevice(int32_t deviceId)187 void FakeInputReaderPolicy::removeDisabledDevice(int32_t deviceId) {
188     mConfig.disabledDevices.erase(deviceId);
189 }
190 
getReaderConfiguration() const191 const InputReaderConfiguration& FakeInputReaderPolicy::getReaderConfiguration() const {
192     return mConfig;
193 }
194 
getInputDevices() const195 const std::vector<InputDeviceInfo> FakeInputReaderPolicy::getInputDevices() const {
196     std::scoped_lock lock(mLock);
197     return mInputDevices;
198 }
199 
getTouchAffineTransformation(const std::string & inputDeviceDescriptor,ui::Rotation surfaceRotation)200 TouchAffineTransformation FakeInputReaderPolicy::getTouchAffineTransformation(
201         const std::string& inputDeviceDescriptor, ui::Rotation surfaceRotation) {
202     return transform;
203 }
204 
setTouchAffineTransformation(const TouchAffineTransformation t)205 void FakeInputReaderPolicy::setTouchAffineTransformation(const TouchAffineTransformation t) {
206     transform = t;
207 }
208 
setPointerCapture(const sp<IBinder> & window)209 PointerCaptureRequest FakeInputReaderPolicy::setPointerCapture(const sp<IBinder>& window) {
210     mConfig.pointerCaptureRequest = {window, mNextPointerCaptureSequenceNumber++};
211     return mConfig.pointerCaptureRequest;
212 }
213 
setDefaultPointerDisplayId(ui::LogicalDisplayId pointerDisplayId)214 void FakeInputReaderPolicy::setDefaultPointerDisplayId(ui::LogicalDisplayId pointerDisplayId) {
215     mConfig.defaultPointerDisplayId = pointerDisplayId;
216 }
217 
setPointerGestureEnabled(bool enabled)218 void FakeInputReaderPolicy::setPointerGestureEnabled(bool enabled) {
219     mConfig.pointerGesturesEnabled = enabled;
220 }
221 
getPointerGestureMovementSpeedRatio()222 float FakeInputReaderPolicy::getPointerGestureMovementSpeedRatio() {
223     return mConfig.pointerGestureMovementSpeedRatio;
224 }
225 
getPointerGestureZoomSpeedRatio()226 float FakeInputReaderPolicy::getPointerGestureZoomSpeedRatio() {
227     return mConfig.pointerGestureZoomSpeedRatio;
228 }
229 
setVelocityControlParams(const VelocityControlParameters & params)230 void FakeInputReaderPolicy::setVelocityControlParams(const VelocityControlParameters& params) {
231     mConfig.wheelVelocityControlParameters = params;
232 }
233 
setStylusButtonMotionEventsEnabled(bool enabled)234 void FakeInputReaderPolicy::setStylusButtonMotionEventsEnabled(bool enabled) {
235     mConfig.stylusButtonMotionEventsEnabled = enabled;
236 }
237 
setStylusPointerIconEnabled(bool enabled)238 void FakeInputReaderPolicy::setStylusPointerIconEnabled(bool enabled) {
239     mConfig.stylusPointerIconEnabled = enabled;
240 }
241 
setIsInputMethodConnectionActive(bool active)242 void FakeInputReaderPolicy::setIsInputMethodConnectionActive(bool active) {
243     mIsInputMethodConnectionActive = active;
244 }
245 
isInputMethodConnectionActive()246 bool FakeInputReaderPolicy::isInputMethodConnectionActive() {
247     return mIsInputMethodConnectionActive;
248 }
249 
getReaderConfiguration(InputReaderConfiguration * outConfig)250 void FakeInputReaderPolicy::getReaderConfiguration(InputReaderConfiguration* outConfig) {
251     *outConfig = mConfig;
252 }
253 
notifyInputDevicesChanged(const std::vector<InputDeviceInfo> & inputDevices)254 void FakeInputReaderPolicy::notifyInputDevicesChanged(
255         const std::vector<InputDeviceInfo>& inputDevices) {
256     std::scoped_lock lock(mLock);
257     mInputDevices = inputDevices;
258     mInputDevicesChanged = true;
259     mDevicesChangedCondition.notify_all();
260 }
261 
notifyTouchpadHardwareState(const SelfContainedHardwareState & schs,int32_t deviceId)262 void FakeInputReaderPolicy::notifyTouchpadHardwareState(const SelfContainedHardwareState& schs,
263                                                         int32_t deviceId) {
264     std::scoped_lock lock(mLock);
265     mTouchpadHardwareState = schs;
266     mTouchpadHardwareStateNotified.notify_all();
267 }
268 
notifyTouchpadGestureInfo(GestureType type,int32_t deviceId)269 void FakeInputReaderPolicy::notifyTouchpadGestureInfo(GestureType type, int32_t deviceId) {
270     std::scoped_lock lock(mLock);
271 }
272 
notifyTouchpadThreeFingerTap()273 void FakeInputReaderPolicy::notifyTouchpadThreeFingerTap() {
274     std::scoped_lock lock(mLock);
275     mTouchpadThreeFingerTapHasBeenReported = true;
276     mTouchpadThreeFingerTapNotified.notify_all();
277 }
278 
getKeyboardLayoutOverlay(const InputDeviceIdentifier &,const std::optional<KeyboardLayoutInfo>)279 std::shared_ptr<KeyCharacterMap> FakeInputReaderPolicy::getKeyboardLayoutOverlay(
280         const InputDeviceIdentifier&, const std::optional<KeyboardLayoutInfo>) {
281     return nullptr;
282 }
283 
getDeviceAlias(const InputDeviceIdentifier &)284 std::string FakeInputReaderPolicy::getDeviceAlias(const InputDeviceIdentifier&) {
285     return "";
286 }
287 
waitForInputDevices(std::function<void (bool)> processDevicesChanged,std::chrono::milliseconds timeout)288 void FakeInputReaderPolicy::waitForInputDevices(std::function<void(bool)> processDevicesChanged,
289                                                 std::chrono::milliseconds timeout) {
290     std::unique_lock<std::mutex> lock(mLock);
291     base::ScopedLockAssertion assumeLocked(mLock);
292 
293     const bool devicesChanged =
294             mDevicesChangedCondition.wait_for(lock, timeout * HW_TIMEOUT_MULTIPLIER,
295                                               [this]() REQUIRES(mLock) {
296                                                   return mInputDevicesChanged;
297                                               });
298     ASSERT_NO_FATAL_FAILURE(processDevicesChanged(devicesChanged));
299     mInputDevicesChanged = false;
300 }
301 
notifyStylusGestureStarted(int32_t deviceId,nsecs_t eventTime)302 void FakeInputReaderPolicy::notifyStylusGestureStarted(int32_t deviceId, nsecs_t eventTime) {
303     std::scoped_lock lock(mLock);
304     mDeviceIdOfNotifiedStylusGesture = deviceId;
305     mStylusGestureNotifiedCondition.notify_all();
306 }
307 
getPointerViewportForAssociatedDisplay(ui::LogicalDisplayId associatedDisplayId)308 std::optional<DisplayViewport> FakeInputReaderPolicy::getPointerViewportForAssociatedDisplay(
309         ui::LogicalDisplayId associatedDisplayId) {
310     if (!associatedDisplayId.isValid()) {
311         associatedDisplayId = mConfig.defaultPointerDisplayId;
312     }
313     for (auto& viewport : mViewports) {
314         if (viewport.displayId == associatedDisplayId) {
315             return std::make_optional(viewport);
316         }
317     }
318     return std::nullopt;
319 }
320 
321 } // namespace android
322