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