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