blob: 50fbf4b9953173e8ce14b389118c22c2dddfe73a [file] [log] [blame]
Michael Ensingb8d93262020-05-12 00:41:30 -07001/*
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 */
Michael Ensingb8d93262020-05-12 00:41:30 -070016#pragma once
17
Harry Cuttsccb75e82023-06-23 14:08:06 +000018#include <map>
Harry Cuttsf61c0472023-07-10 14:45:15 +000019#include <memory>
Harry Cutts207674d2024-06-06 18:53:41 +000020#include <optional>
Harry Cuttsccb75e82023-06-23 14:08:06 +000021
22#include <EventHub.h>
Michael Ensingb8d93262020-05-12 00:41:30 -070023#include <InputDevice.h>
24#include <InputMapper.h>
25#include <InputReader.h>
Aditya Wazireea5be02022-10-31 12:40:10 +053026#include <ThreadSafeFuzzedDataProvider.h>
Michael Ensingb8d93262020-05-12 00:41:30 -070027
28constexpr size_t kValidTypes[] = {EV_SW,
29 EV_SYN,
Michael Ensingb8d93262020-05-12 00:41:30 -070030 EV_ABS,
31 EV_KEY,
32 EV_MSC,
33 EV_REL,
34 android::EventHubInterface::DEVICE_ADDED,
35 android::EventHubInterface::DEVICE_REMOVED,
36 android::EventHubInterface::FINISHED_DEVICE_SCAN};
37
38constexpr size_t kValidCodes[] = {
39 SYN_REPORT,
40 ABS_MT_SLOT,
41 SYN_MT_REPORT,
42 ABS_MT_POSITION_X,
43 ABS_MT_POSITION_Y,
44 ABS_MT_TOUCH_MAJOR,
45 ABS_MT_TOUCH_MINOR,
46 ABS_MT_WIDTH_MAJOR,
47 ABS_MT_WIDTH_MINOR,
48 ABS_MT_ORIENTATION,
49 ABS_MT_TRACKING_ID,
50 ABS_MT_PRESSURE,
51 ABS_MT_DISTANCE,
52 ABS_MT_TOOL_TYPE,
Michael Ensingb8d93262020-05-12 00:41:30 -070053 MSC_SCAN,
54 REL_X,
55 REL_Y,
56 REL_WHEEL,
57 REL_HWHEEL,
58 BTN_LEFT,
59 BTN_RIGHT,
60 BTN_MIDDLE,
61 BTN_BACK,
62 BTN_SIDE,
63 BTN_FORWARD,
64 BTN_EXTRA,
65 BTN_TASK,
66};
67
Michael Ensingb8d93262020-05-12 00:41:30 -070068constexpr size_t kMaxSize = 256;
69
70namespace android {
71
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -070072template<class Fdp>
73ToolType getFuzzedToolType(Fdp& fdp) {
74 const int32_t toolType = fdp.template ConsumeIntegralInRange<int32_t>(
75 static_cast<int32_t>(ToolType::ftl_first),
76 static_cast<int32_t>(ToolType::ftl_last));
77 return static_cast<ToolType>(toolType);
78}
79
Harry Cutts656e0ad2023-06-16 16:39:55 +000080template <class Fdp>
81RawEvent getFuzzedRawEvent(Fdp& fdp) {
82 const int32_t type = fdp.ConsumeBool() ? fdp.PickValueInArray(kValidTypes)
83 : fdp.template ConsumeIntegral<int32_t>();
84 const int32_t code = fdp.ConsumeBool() ? fdp.PickValueInArray(kValidCodes)
85 : fdp.template ConsumeIntegral<int32_t>();
86 return RawEvent{
87 .when = fdp.template ConsumeIntegral<nsecs_t>(),
88 .readTime = fdp.template ConsumeIntegral<nsecs_t>(),
89 .deviceId = fdp.template ConsumeIntegral<int32_t>(),
90 .type = type,
91 .code = code,
92 .value = fdp.template ConsumeIntegral<int32_t>(),
93 };
94}
95
Michael Ensingb8d93262020-05-12 00:41:30 -070096class FuzzEventHub : public EventHubInterface {
97 InputDeviceIdentifier mIdentifier;
98 std::vector<TouchVideoFrame> mVideoFrames;
99 PropertyMap mFuzzConfig;
Harry Cuttsccb75e82023-06-23 14:08:06 +0000100 std::map<int32_t /* deviceId */, std::map<int /* axis */, RawAbsoluteAxisInfo>> mAxes;
Aditya Wazireea5be02022-10-31 12:40:10 +0530101 std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;
Michael Ensingb8d93262020-05-12 00:41:30 -0700102
103public:
Aditya Wazireea5be02022-10-31 12:40:10 +0530104 FuzzEventHub(std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) : mFdp(std::move(fdp)) {}
Michael Ensingb8d93262020-05-12 00:41:30 -0700105 ~FuzzEventHub() {}
106 void addProperty(std::string key, std::string value) { mFuzzConfig.addProperty(key, value); }
Michael Ensingb8d93262020-05-12 00:41:30 -0700107
108 ftl::Flags<InputDeviceClass> getDeviceClasses(int32_t deviceId) const override {
109 return ftl::Flags<InputDeviceClass>(mFdp->ConsumeIntegral<uint32_t>());
110 }
111 InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override {
112 return mIdentifier;
113 }
114 int32_t getDeviceControllerNumber(int32_t deviceId) const override {
115 return mFdp->ConsumeIntegral<int32_t>();
116 }
Harry Cuttsc34f7582023-03-07 16:23:30 +0000117 std::optional<PropertyMap> getConfiguration(int32_t deviceId) const override {
118 return mFuzzConfig;
Michael Ensingb8d93262020-05-12 00:41:30 -0700119 }
Harry Cuttsccb75e82023-06-23 14:08:06 +0000120 void setAbsoluteAxisInfo(int32_t deviceId, int axis, const RawAbsoluteAxisInfo& axisInfo) {
121 mAxes[deviceId][axis] = axisInfo;
122 }
Harry Cutts207674d2024-06-06 18:53:41 +0000123 std::optional<RawAbsoluteAxisInfo> getAbsoluteAxisInfo(int32_t deviceId,
124 int axis) const override {
Harry Cuttsccb75e82023-06-23 14:08:06 +0000125 if (auto deviceAxesIt = mAxes.find(deviceId); deviceAxesIt != mAxes.end()) {
126 const std::map<int, RawAbsoluteAxisInfo>& deviceAxes = deviceAxesIt->second;
127 if (auto axisInfoIt = deviceAxes.find(axis); axisInfoIt != deviceAxes.end()) {
Harry Cutts207674d2024-06-06 18:53:41 +0000128 return axisInfoIt->second;
Harry Cuttsccb75e82023-06-23 14:08:06 +0000129 }
130 }
Harry Cutts207674d2024-06-06 18:53:41 +0000131 if (mFdp->ConsumeBool()) {
132 return std::optional<RawAbsoluteAxisInfo>({
133 .valid = mFdp->ConsumeBool(),
134 .minValue = mFdp->ConsumeIntegral<int32_t>(),
135 .maxValue = mFdp->ConsumeIntegral<int32_t>(),
136 .flat = mFdp->ConsumeIntegral<int32_t>(),
137 .fuzz = mFdp->ConsumeIntegral<int32_t>(),
138 .resolution = mFdp->ConsumeIntegral<int32_t>(),
139 });
140 } else {
141 return std::nullopt;
142 }
Michael Ensingb8d93262020-05-12 00:41:30 -0700143 }
144 bool hasRelativeAxis(int32_t deviceId, int axis) const override { return mFdp->ConsumeBool(); }
145 bool hasInputProperty(int32_t deviceId, int property) const override {
146 return mFdp->ConsumeBool();
147 }
148 bool hasMscEvent(int32_t deviceId, int mscEvent) const override { return mFdp->ConsumeBool(); }
149 status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState,
150 int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const override {
151 return mFdp->ConsumeIntegral<status_t>();
152 }
153 status_t mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const override {
154 return mFdp->ConsumeIntegral<status_t>();
155 }
156 void setExcludedDevices(const std::vector<std::string>& devices) override {}
Siarhei Vishniakou7b3ea0b2022-09-16 14:23:20 -0700157 std::vector<RawEvent> getEvents(int timeoutMillis) override {
158 std::vector<RawEvent> events;
159 const size_t count = mFdp->ConsumeIntegralInRange<size_t>(0, kMaxSize);
160 for (size_t i = 0; i < count; ++i) {
Harry Cutts656e0ad2023-06-16 16:39:55 +0000161 events.push_back(getFuzzedRawEvent(*mFdp));
Siarhei Vishniakou7b3ea0b2022-09-16 14:23:20 -0700162 }
163 return events;
Michael Ensingb8d93262020-05-12 00:41:30 -0700164 }
165 std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override { return mVideoFrames; }
166
167 base::Result<std::pair<InputDeviceSensorType, int32_t>> mapSensor(
168 int32_t deviceId, int32_t absCode) const override {
169 return base::ResultError("Fuzzer", UNKNOWN_ERROR);
170 };
171 // Raw batteries are sysfs power_supply nodes we found from the EventHub device sysfs node,
172 // containing the raw info of the sysfs node structure.
173 std::vector<int32_t> getRawBatteryIds(int32_t deviceId) const override { return {}; }
174 std::optional<RawBatteryInfo> getRawBatteryInfo(int32_t deviceId,
175 int32_t BatteryId) const override {
176 return std::nullopt;
177 };
178
179 std::vector<int32_t> getRawLightIds(int32_t deviceId) const override { return {}; };
180 std::optional<RawLightInfo> getRawLightInfo(int32_t deviceId, int32_t lightId) const override {
181 return std::nullopt;
182 };
183 std::optional<int32_t> getLightBrightness(int32_t deviceId, int32_t lightId) const override {
184 return std::nullopt;
185 };
186 void setLightBrightness(int32_t deviceId, int32_t lightId, int32_t brightness) override{};
187 std::optional<std::unordered_map<LightColor, int32_t>> getLightIntensities(
188 int32_t deviceId, int32_t lightId) const override {
189 return std::nullopt;
190 };
191 void setLightIntensities(int32_t deviceId, int32_t lightId,
192 std::unordered_map<LightColor, int32_t> intensities) override{};
193
Vaibhav Devmurari7fb41132023-01-02 13:30:26 +0000194 std::optional<RawLayoutInfo> getRawLayoutInfo(int32_t deviceId) const override {
195 return std::nullopt;
Michael Ensingb8d93262020-05-12 00:41:30 -0700196 };
197
198 int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override {
199 return mFdp->ConsumeIntegral<int32_t>();
200 }
201 int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override {
202 return mFdp->ConsumeIntegral<int32_t>();
203 }
204 int32_t getSwitchState(int32_t deviceId, int32_t sw) const override {
205 return mFdp->ConsumeIntegral<int32_t>();
206 }
Vaibhav Devmuraricbba14c2022-10-10 16:54:49 +0000207 void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const override {}
Michael Ensingb8d93262020-05-12 00:41:30 -0700208 int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override {
209 return mFdp->ConsumeIntegral<int32_t>();
210 }
211 status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
212 int32_t* outValue) const override {
213 return mFdp->ConsumeIntegral<status_t>();
214 }
Arpit Singh4b4a4572023-11-24 18:19:56 +0000215 base::Result<std::vector<int32_t>> getMtSlotValues(int32_t deviceId, int32_t axis,
216 size_t slotCount) const override {
217 if (mFdp->ConsumeBool()) {
218 std::vector<int32_t> outValues(slotCount + 1);
219 for (size_t i = 0; i < outValues.size(); i++) {
220 outValues.push_back(mFdp->ConsumeIntegral<int32_t>());
221 }
222 return std::move(outValues);
223 } else {
224 return base::ResultError("Fuzzer", UNKNOWN_ERROR);
225 }
226 }
Michael Ensingb8d93262020-05-12 00:41:30 -0700227 bool markSupportedKeyCodes(int32_t deviceId, const std::vector<int32_t>& keyCodes,
228 uint8_t* outFlags) const override {
229 return mFdp->ConsumeBool();
230 }
231 bool hasScanCode(int32_t deviceId, int32_t scanCode) const override {
232 return mFdp->ConsumeBool();
233 }
234 bool hasKeyCode(int32_t deviceId, int32_t keyCode) const override {
235 return mFdp->ConsumeBool();
236 }
237 bool hasLed(int32_t deviceId, int32_t led) const override { return mFdp->ConsumeBool(); }
238 void setLedState(int32_t deviceId, int32_t led, bool on) override {}
239 void getVirtualKeyDefinitions(
240 int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const override {}
241 const std::shared_ptr<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const override {
242 return nullptr;
243 }
244 bool setKeyboardLayoutOverlay(int32_t deviceId, std::shared_ptr<KeyCharacterMap> map) override {
245 return mFdp->ConsumeBool();
246 }
247 void vibrate(int32_t deviceId, const VibrationElement& effect) override {}
248 void cancelVibrate(int32_t deviceId) override {}
249
250 std::vector<int32_t> getVibratorIds(int32_t deviceId) const override { return {}; };
251
252 /* Query battery level. */
253 std::optional<int32_t> getBatteryCapacity(int32_t deviceId, int32_t batteryId) const override {
254 return std::nullopt;
255 };
256
257 /* Query battery status. */
258 std::optional<int32_t> getBatteryStatus(int32_t deviceId, int32_t batteryId) const override {
259 return std::nullopt;
260 };
261
262 void requestReopenDevices() override {}
263 void wake() override {}
264 void dump(std::string& dump) const override {}
265 void monitor() const override {}
266 bool isDeviceEnabled(int32_t deviceId) const override { return mFdp->ConsumeBool(); }
267 status_t enableDevice(int32_t deviceId) override { return mFdp->ConsumeIntegral<status_t>(); }
268 status_t disableDevice(int32_t deviceId) override { return mFdp->ConsumeIntegral<status_t>(); }
Vaibhav Devmurari5fc7d852023-03-17 18:43:33 +0000269 void sysfsNodeChanged(const std::string& sysfsNodePath) override {}
Michael Ensingb8d93262020-05-12 00:41:30 -0700270};
271
Michael Ensingb8d93262020-05-12 00:41:30 -0700272class FuzzInputReaderPolicy : public InputReaderPolicyInterface {
273 TouchAffineTransformation mTransform;
Aditya Wazireea5be02022-10-31 12:40:10 +0530274 std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;
Michael Ensingb8d93262020-05-12 00:41:30 -0700275
276protected:
277 ~FuzzInputReaderPolicy() {}
278
279public:
Prabir Pradhan2120b9e2024-05-04 00:06:37 +0000280 FuzzInputReaderPolicy(std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp) : mFdp(mFdp) {}
Michael Ensingb8d93262020-05-12 00:41:30 -0700281 void getReaderConfiguration(InputReaderConfiguration* outConfig) override {}
Michael Ensingb8d93262020-05-12 00:41:30 -0700282 void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override {}
283 std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
Vaibhav Devmuraridec30802023-07-11 15:02:03 +0000284 const InputDeviceIdentifier& identifier,
285 const std::optional<KeyboardLayoutInfo> layoutInfo) override {
Michael Ensingb8d93262020-05-12 00:41:30 -0700286 return nullptr;
287 }
288 std::string getDeviceAlias(const InputDeviceIdentifier& identifier) {
289 return mFdp->ConsumeRandomLengthString(32);
290 }
291 TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
Michael Wrighta9cf4192022-12-01 23:46:39 +0000292 ui::Rotation surfaceRotation) override {
Michael Ensingb8d93262020-05-12 00:41:30 -0700293 return mTransform;
294 }
295 void setTouchAffineTransformation(const TouchAffineTransformation t) { mTransform = t; }
Prabir Pradhanda20b172022-09-26 17:01:18 +0000296 void notifyStylusGestureStarted(int32_t, nsecs_t) {}
Arpit Singhb3b3f732023-07-04 14:30:05 +0000297 bool isInputMethodConnectionActive() override { return mFdp->ConsumeBool(); }
Prabir Pradhan19767602023-11-03 16:53:31 +0000298 std::optional<DisplayViewport> getPointerViewportForAssociatedDisplay(
Linnan Li13bf76a2024-05-05 19:18:02 +0800299 ui::LogicalDisplayId associatedDisplayId) override {
Byoungho Jungda10dd32023-10-06 17:03:45 +0900300 return {};
301 }
Michael Ensingb8d93262020-05-12 00:41:30 -0700302};
303
304class FuzzInputListener : public virtual InputListenerInterface {
305public:
Prabir Pradhane3da4bb2023-04-05 23:51:23 +0000306 void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override {}
Prabir Pradhanc392d8f2023-04-13 19:32:51 +0000307 void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override {}
308 void notifyKey(const NotifyKeyArgs& args) override {}
309 void notifyMotion(const NotifyMotionArgs& args) override {}
310 void notifySwitch(const NotifySwitchArgs& args) override {}
311 void notifySensor(const NotifySensorArgs& args) override{};
312 void notifyVibratorState(const NotifyVibratorStateArgs& args) override{};
313 void notifyDeviceReset(const NotifyDeviceResetArgs& args) override {}
314 void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override{};
Michael Ensingb8d93262020-05-12 00:41:30 -0700315};
316
317class FuzzInputReaderContext : public InputReaderContext {
318 std::shared_ptr<EventHubInterface> mEventHub;
319 sp<InputReaderPolicyInterface> mPolicy;
Aditya Wazireea5be02022-10-31 12:40:10 +0530320 std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;
Michael Ensingb8d93262020-05-12 00:41:30 -0700321
322public:
323 FuzzInputReaderContext(std::shared_ptr<EventHubInterface> eventHub,
Harry Cuttsf61c0472023-07-10 14:45:15 +0000324 std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp)
325 : mEventHub(eventHub), mPolicy(sp<FuzzInputReaderPolicy>::make(fdp)), mFdp(fdp) {}
Michael Ensingb8d93262020-05-12 00:41:30 -0700326 ~FuzzInputReaderContext() {}
327 void updateGlobalMetaState() override {}
328 int32_t getGlobalMetaState() { return mFdp->ConsumeIntegral<int32_t>(); }
329 void disableVirtualKeysUntil(nsecs_t time) override {}
330 bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) override {
331 return mFdp->ConsumeBool();
332 }
Michael Ensingb8d93262020-05-12 00:41:30 -0700333 void requestTimeoutAtTime(nsecs_t when) override {}
334 int32_t bumpGeneration() override { return mFdp->ConsumeIntegral<int32_t>(); }
335 void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) override {}
Siarhei Vishniakou2935db72022-09-22 13:35:22 -0700336 std::list<NotifyArgs> dispatchExternalStylusState(const StylusState& outState) override {
337 return {};
338 }
Michael Ensingb8d93262020-05-12 00:41:30 -0700339 InputReaderPolicyInterface* getPolicy() override { return mPolicy.get(); }
Michael Ensingb8d93262020-05-12 00:41:30 -0700340 EventHubInterface* getEventHub() override { return mEventHub.get(); }
341 int32_t getNextId() override { return mFdp->ConsumeIntegral<int32_t>(); }
342
343 void updateLedMetaState(int32_t metaState) override{};
344 int32_t getLedMetaState() override { return mFdp->ConsumeIntegral<int32_t>(); };
Prabir Pradhanda20b172022-09-26 17:01:18 +0000345 void notifyStylusGestureStarted(int32_t, nsecs_t) {}
Arpit Singha5ea7c12023-07-05 15:39:25 +0000346
347 void setPreventingTouchpadTaps(bool prevent) {}
348 bool isPreventingTouchpadTaps() { return mFdp->ConsumeBool(); };
Arpit Singh82e413e2023-10-10 19:30:58 +0000349
350 void setLastKeyDownTimestamp(nsecs_t when) { mLastKeyDownTimestamp = when; };
351 nsecs_t getLastKeyDownTimestamp() { return mLastKeyDownTimestamp; };
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000352 KeyboardClassifier& getKeyboardClassifier() override { return *mClassifier; }
Arpit Singh82e413e2023-10-10 19:30:58 +0000353
354private:
355 nsecs_t mLastKeyDownTimestamp;
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000356 std::unique_ptr<KeyboardClassifier> mClassifier = std::make_unique<KeyboardClassifier>();
Michael Ensingb8d93262020-05-12 00:41:30 -0700357};
358
Harry Cuttsf61c0472023-07-10 14:45:15 +0000359template <class Fdp>
360InputDevice getFuzzedInputDevice(Fdp& fdp, FuzzInputReaderContext* context) {
361 InputDeviceIdentifier identifier;
362 identifier.name = fdp.ConsumeRandomLengthString(16);
363 identifier.location = fdp.ConsumeRandomLengthString(12);
364 int32_t deviceID = fdp.ConsumeIntegralInRange(0, 5);
365 int32_t deviceGeneration = fdp.ConsumeIntegralInRange(0, 5);
366 return InputDevice(context, deviceID, deviceGeneration, identifier);
367}
368
369template <class Fdp>
370void configureAndResetDevice(Fdp& fdp, InputDevice& device) {
371 nsecs_t arbitraryTime = fdp.template ConsumeIntegral<nsecs_t>();
372 std::list<NotifyArgs> out;
373 out += device.configure(arbitraryTime, /*readerConfig=*/{}, /*changes=*/{});
374 out += device.reset(arbitraryTime);
375}
376
377template <class Fdp, class T, typename... Args>
378T& getMapperForDevice(Fdp& fdp, InputDevice& device, Args... args) {
379 int32_t eventhubId = fdp.template ConsumeIntegral<int32_t>();
380 // ensure a device entry exists for this eventHubId
381 device.addEmptyEventHubDevice(eventhubId);
382 configureAndResetDevice(fdp, device);
383
384 return device.template constructAndAddMapper<T>(eventhubId, args...);
385}
386
Michael Ensingb8d93262020-05-12 00:41:30 -0700387} // namespace android