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