File: MapperHelpers.h

package info (click to toggle)
android-platform-tools 35.0.2-1~exp6
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 211,716 kB
  • sloc: cpp: 995,749; java: 290,495; ansic: 145,647; xml: 58,531; python: 39,608; sh: 14,500; javascript: 5,198; asm: 4,866; makefile: 3,115; yacc: 769; awk: 368; ruby: 183; sql: 140; perl: 88; lex: 67
file content (418 lines) | stat: -rw-r--r-- 18,495 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#include <map>
#include <memory>

#include <EventHub.h>
#include <InputDevice.h>
#include <InputMapper.h>
#include <InputReader.h>
#include <ThreadSafeFuzzedDataProvider.h>

constexpr size_t kValidTypes[] = {EV_SW,
                                  EV_SYN,
                                  EV_ABS,
                                  EV_KEY,
                                  EV_MSC,
                                  EV_REL,
                                  android::EventHubInterface::DEVICE_ADDED,
                                  android::EventHubInterface::DEVICE_REMOVED,
                                  android::EventHubInterface::FINISHED_DEVICE_SCAN};

constexpr size_t kValidCodes[] = {
        SYN_REPORT,
        ABS_MT_SLOT,
        SYN_MT_REPORT,
        ABS_MT_POSITION_X,
        ABS_MT_POSITION_Y,
        ABS_MT_TOUCH_MAJOR,
        ABS_MT_TOUCH_MINOR,
        ABS_MT_WIDTH_MAJOR,
        ABS_MT_WIDTH_MINOR,
        ABS_MT_ORIENTATION,
        ABS_MT_TRACKING_ID,
        ABS_MT_PRESSURE,
        ABS_MT_DISTANCE,
        ABS_MT_TOOL_TYPE,
        MSC_SCAN,
        REL_X,
        REL_Y,
        REL_WHEEL,
        REL_HWHEEL,
        BTN_LEFT,
        BTN_RIGHT,
        BTN_MIDDLE,
        BTN_BACK,
        BTN_SIDE,
        BTN_FORWARD,
        BTN_EXTRA,
        BTN_TASK,
};

constexpr size_t kMaxSize = 256;

namespace android {

template<class Fdp>
ToolType getFuzzedToolType(Fdp& fdp) {
    const int32_t toolType = fdp.template ConsumeIntegralInRange<int32_t>(
                            static_cast<int32_t>(ToolType::ftl_first),
                            static_cast<int32_t>(ToolType::ftl_last));
    return static_cast<ToolType>(toolType);
}

template <class Fdp>
RawEvent getFuzzedRawEvent(Fdp& fdp) {
    const int32_t type = fdp.ConsumeBool() ? fdp.PickValueInArray(kValidTypes)
                                           : fdp.template ConsumeIntegral<int32_t>();
    const int32_t code = fdp.ConsumeBool() ? fdp.PickValueInArray(kValidCodes)
                                           : fdp.template ConsumeIntegral<int32_t>();
    return RawEvent{
            .when = fdp.template ConsumeIntegral<nsecs_t>(),
            .readTime = fdp.template ConsumeIntegral<nsecs_t>(),
            .deviceId = fdp.template ConsumeIntegral<int32_t>(),
            .type = type,
            .code = code,
            .value = fdp.template ConsumeIntegral<int32_t>(),
    };
}

class FuzzEventHub : public EventHubInterface {
    InputDeviceIdentifier mIdentifier;
    std::vector<TouchVideoFrame> mVideoFrames;
    PropertyMap mFuzzConfig;
    std::map<int32_t /* deviceId */, std::map<int /* axis */, RawAbsoluteAxisInfo>> mAxes;
    std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;

public:
    FuzzEventHub(std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) : mFdp(std::move(fdp)) {}
    ~FuzzEventHub() {}
    void addProperty(std::string key, std::string value) { mFuzzConfig.addProperty(key, value); }

    ftl::Flags<InputDeviceClass> getDeviceClasses(int32_t deviceId) const override {
        return ftl::Flags<InputDeviceClass>(mFdp->ConsumeIntegral<uint32_t>());
    }
    InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override {
        return mIdentifier;
    }
    int32_t getDeviceControllerNumber(int32_t deviceId) const override {
        return mFdp->ConsumeIntegral<int32_t>();
    }
    std::optional<PropertyMap> getConfiguration(int32_t deviceId) const override {
        return mFuzzConfig;
    }
    void setAbsoluteAxisInfo(int32_t deviceId, int axis, const RawAbsoluteAxisInfo& axisInfo) {
        mAxes[deviceId][axis] = axisInfo;
    }
    status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
                                 RawAbsoluteAxisInfo* outAxisInfo) const override {
        if (auto deviceAxesIt = mAxes.find(deviceId); deviceAxesIt != mAxes.end()) {
            const std::map<int, RawAbsoluteAxisInfo>& deviceAxes = deviceAxesIt->second;
            if (auto axisInfoIt = deviceAxes.find(axis); axisInfoIt != deviceAxes.end()) {
                *outAxisInfo = axisInfoIt->second;
                return OK;
            }
        }
        return mFdp->ConsumeIntegral<status_t>();
    }
    bool hasRelativeAxis(int32_t deviceId, int axis) const override { return mFdp->ConsumeBool(); }
    bool hasInputProperty(int32_t deviceId, int property) const override {
        return mFdp->ConsumeBool();
    }
    bool hasMscEvent(int32_t deviceId, int mscEvent) const override { return mFdp->ConsumeBool(); }
    status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState,
                    int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const override {
        return mFdp->ConsumeIntegral<status_t>();
    }
    status_t mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const override {
        return mFdp->ConsumeIntegral<status_t>();
    }
    void setExcludedDevices(const std::vector<std::string>& devices) override {}
    std::vector<RawEvent> getEvents(int timeoutMillis) override {
        std::vector<RawEvent> events;
        const size_t count = mFdp->ConsumeIntegralInRange<size_t>(0, kMaxSize);
        for (size_t i = 0; i < count; ++i) {
            events.push_back(getFuzzedRawEvent(*mFdp));
        }
        return events;
    }
    std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override { return mVideoFrames; }

    base::Result<std::pair<InputDeviceSensorType, int32_t>> mapSensor(
            int32_t deviceId, int32_t absCode) const override {
        return base::ResultError("Fuzzer", UNKNOWN_ERROR);
    };
    // Raw batteries are sysfs power_supply nodes we found from the EventHub device sysfs node,
    // containing the raw info of the sysfs node structure.
    std::vector<int32_t> getRawBatteryIds(int32_t deviceId) const override { return {}; }
    std::optional<RawBatteryInfo> getRawBatteryInfo(int32_t deviceId,
                                                    int32_t BatteryId) const override {
        return std::nullopt;
    };

    std::vector<int32_t> getRawLightIds(int32_t deviceId) const override { return {}; };
    std::optional<RawLightInfo> getRawLightInfo(int32_t deviceId, int32_t lightId) const override {
        return std::nullopt;
    };
    std::optional<int32_t> getLightBrightness(int32_t deviceId, int32_t lightId) const override {
        return std::nullopt;
    };
    void setLightBrightness(int32_t deviceId, int32_t lightId, int32_t brightness) override{};
    std::optional<std::unordered_map<LightColor, int32_t>> getLightIntensities(
            int32_t deviceId, int32_t lightId) const override {
        return std::nullopt;
    };
    void setLightIntensities(int32_t deviceId, int32_t lightId,
                             std::unordered_map<LightColor, int32_t> intensities) override{};

    std::optional<RawLayoutInfo> getRawLayoutInfo(int32_t deviceId) const override {
        return std::nullopt;
    };

    int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override {
        return mFdp->ConsumeIntegral<int32_t>();
    }
    int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override {
        return mFdp->ConsumeIntegral<int32_t>();
    }
    int32_t getSwitchState(int32_t deviceId, int32_t sw) const override {
        return mFdp->ConsumeIntegral<int32_t>();
    }
    void addKeyRemapping(int32_t deviceId, int32_t fromKeyCode, int32_t toKeyCode) const override {}
    int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override {
        return mFdp->ConsumeIntegral<int32_t>();
    }
    status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
                                  int32_t* outValue) const override {
        return mFdp->ConsumeIntegral<status_t>();
    }
    base::Result<std::vector<int32_t>> getMtSlotValues(int32_t deviceId, int32_t axis,
                                                       size_t slotCount) const override {
        if (mFdp->ConsumeBool()) {
            std::vector<int32_t> outValues(slotCount + 1);
            for (size_t i = 0; i < outValues.size(); i++) {
                outValues.push_back(mFdp->ConsumeIntegral<int32_t>());
            }
            return std::move(outValues);
        } else {
            return base::ResultError("Fuzzer", UNKNOWN_ERROR);
        }
    }
    bool markSupportedKeyCodes(int32_t deviceId, const std::vector<int32_t>& keyCodes,
                               uint8_t* outFlags) const override {
        return mFdp->ConsumeBool();
    }
    bool hasScanCode(int32_t deviceId, int32_t scanCode) const override {
        return mFdp->ConsumeBool();
    }
    bool hasKeyCode(int32_t deviceId, int32_t keyCode) const override {
        return mFdp->ConsumeBool();
    }
    bool hasLed(int32_t deviceId, int32_t led) const override { return mFdp->ConsumeBool(); }
    void setLedState(int32_t deviceId, int32_t led, bool on) override {}
    void getVirtualKeyDefinitions(
            int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const override {}
    const std::shared_ptr<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const override {
        return nullptr;
    }
    bool setKeyboardLayoutOverlay(int32_t deviceId, std::shared_ptr<KeyCharacterMap> map) override {
        return mFdp->ConsumeBool();
    }
    void vibrate(int32_t deviceId, const VibrationElement& effect) override {}
    void cancelVibrate(int32_t deviceId) override {}

    std::vector<int32_t> getVibratorIds(int32_t deviceId) const override { return {}; };

    /* Query battery level. */
    std::optional<int32_t> getBatteryCapacity(int32_t deviceId, int32_t batteryId) const override {
        return std::nullopt;
    };

    /* Query battery status. */
    std::optional<int32_t> getBatteryStatus(int32_t deviceId, int32_t batteryId) const override {
        return std::nullopt;
    };

    void requestReopenDevices() override {}
    void wake() override {}
    void dump(std::string& dump) const override {}
    void monitor() const override {}
    bool isDeviceEnabled(int32_t deviceId) const override { return mFdp->ConsumeBool(); }
    status_t enableDevice(int32_t deviceId) override { return mFdp->ConsumeIntegral<status_t>(); }
    status_t disableDevice(int32_t deviceId) override { return mFdp->ConsumeIntegral<status_t>(); }
    void sysfsNodeChanged(const std::string& sysfsNodePath) override {}
};

class FuzzPointerController : public PointerControllerInterface {
    std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;

public:
    FuzzPointerController(std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp) : mFdp(mFdp) {}
    ~FuzzPointerController() {}
    std::optional<FloatRect> getBounds() const override {
        if (mFdp->ConsumeBool()) {
            return {};
        } else {
            return FloatRect{mFdp->ConsumeFloatingPoint<float>(),
                             mFdp->ConsumeFloatingPoint<float>(),
                             mFdp->ConsumeFloatingPoint<float>(),
                             mFdp->ConsumeFloatingPoint<float>()};
        }
    }
    void move(float deltaX, float deltaY) override {}
    void setPosition(float x, float y) override {}
    FloatPoint getPosition() const override {
        return {mFdp->ConsumeFloatingPoint<float>(), mFdp->ConsumeFloatingPoint<float>()};
    }
    void fade(Transition transition) override {}
    void unfade(Transition transition) override {}
    void setPresentation(Presentation presentation) override {}
    void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
                  BitSet32 spotIdBits, int32_t displayId) override {}
    void clearSpots() override {}
    int32_t getDisplayId() const override { return mFdp->ConsumeIntegral<int32_t>(); }
    void setDisplayViewport(const DisplayViewport& displayViewport) override {}
    void updatePointerIcon(PointerIconStyle iconId) override {}
    void setCustomPointerIcon(const SpriteIcon& icon) override {}
    std::string dump() override { return ""; }
};

class FuzzInputReaderPolicy : public InputReaderPolicyInterface {
    TouchAffineTransformation mTransform;
    std::shared_ptr<FuzzPointerController> mPointerController;
    std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;

protected:
    ~FuzzInputReaderPolicy() {}

public:
    FuzzInputReaderPolicy(std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp) : mFdp(mFdp) {
        mPointerController = std::make_shared<FuzzPointerController>(mFdp);
    }
    void getReaderConfiguration(InputReaderConfiguration* outConfig) override {}
    std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId) override {
        return mPointerController;
    }
    void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override {}
    std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
            const InputDeviceIdentifier& identifier,
            const std::optional<KeyboardLayoutInfo> layoutInfo) override {
        return nullptr;
    }
    std::string getDeviceAlias(const InputDeviceIdentifier& identifier) {
        return mFdp->ConsumeRandomLengthString(32);
    }
    TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
                                                           ui::Rotation surfaceRotation) override {
        return mTransform;
    }
    void setTouchAffineTransformation(const TouchAffineTransformation t) { mTransform = t; }
    void notifyStylusGestureStarted(int32_t, nsecs_t) {}
    bool isInputMethodConnectionActive() override { return mFdp->ConsumeBool(); }
    std::optional<DisplayViewport> getPointerViewportForAssociatedDisplay(
            int32_t associatedDisplayId) override {
        return {};
    }
};

class FuzzInputListener : public virtual InputListenerInterface {
public:
    void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override {}
    void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override {}
    void notifyKey(const NotifyKeyArgs& args) override {}
    void notifyMotion(const NotifyMotionArgs& args) override {}
    void notifySwitch(const NotifySwitchArgs& args) override {}
    void notifySensor(const NotifySensorArgs& args) override{};
    void notifyVibratorState(const NotifyVibratorStateArgs& args) override{};
    void notifyDeviceReset(const NotifyDeviceResetArgs& args) override {}
    void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override{};
};

class FuzzInputReaderContext : public InputReaderContext {
    std::shared_ptr<EventHubInterface> mEventHub;
    sp<InputReaderPolicyInterface> mPolicy;
    std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;

public:
    FuzzInputReaderContext(std::shared_ptr<EventHubInterface> eventHub,
                           std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp)
          : mEventHub(eventHub), mPolicy(sp<FuzzInputReaderPolicy>::make(fdp)), mFdp(fdp) {}
    ~FuzzInputReaderContext() {}
    void updateGlobalMetaState() override {}
    int32_t getGlobalMetaState() { return mFdp->ConsumeIntegral<int32_t>(); }
    void disableVirtualKeysUntil(nsecs_t time) override {}
    bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) override {
        return mFdp->ConsumeBool();
    }
    void fadePointer() override {}
    std::shared_ptr<PointerControllerInterface> getPointerController(int32_t deviceId) override {
        return mPolicy->obtainPointerController(0);
    }
    void requestTimeoutAtTime(nsecs_t when) override {}
    int32_t bumpGeneration() override { return mFdp->ConsumeIntegral<int32_t>(); }
    void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) override {}
    std::list<NotifyArgs> dispatchExternalStylusState(const StylusState& outState) override {
        return {};
    }
    InputReaderPolicyInterface* getPolicy() override { return mPolicy.get(); }
    EventHubInterface* getEventHub() override { return mEventHub.get(); }
    int32_t getNextId() override { return mFdp->ConsumeIntegral<int32_t>(); }

    void updateLedMetaState(int32_t metaState) override{};
    int32_t getLedMetaState() override { return mFdp->ConsumeIntegral<int32_t>(); };
    void notifyStylusGestureStarted(int32_t, nsecs_t) {}

    void setPreventingTouchpadTaps(bool prevent) {}
    bool isPreventingTouchpadTaps() { return mFdp->ConsumeBool(); };

    void setLastKeyDownTimestamp(nsecs_t when) { mLastKeyDownTimestamp = when; };
    nsecs_t getLastKeyDownTimestamp() { return mLastKeyDownTimestamp; };

private:
    nsecs_t mLastKeyDownTimestamp;
};

template <class Fdp>
InputDevice getFuzzedInputDevice(Fdp& fdp, FuzzInputReaderContext* context) {
    InputDeviceIdentifier identifier;
    identifier.name = fdp.ConsumeRandomLengthString(16);
    identifier.location = fdp.ConsumeRandomLengthString(12);
    int32_t deviceID = fdp.ConsumeIntegralInRange(0, 5);
    int32_t deviceGeneration = fdp.ConsumeIntegralInRange(0, 5);
    return InputDevice(context, deviceID, deviceGeneration, identifier);
}

template <class Fdp>
void configureAndResetDevice(Fdp& fdp, InputDevice& device) {
    nsecs_t arbitraryTime = fdp.template ConsumeIntegral<nsecs_t>();
    std::list<NotifyArgs> out;
    out += device.configure(arbitraryTime, /*readerConfig=*/{}, /*changes=*/{});
    out += device.reset(arbitraryTime);
}

template <class Fdp, class T, typename... Args>
T& getMapperForDevice(Fdp& fdp, InputDevice& device, Args... args) {
    int32_t eventhubId = fdp.template ConsumeIntegral<int32_t>();
    // ensure a device entry exists for this eventHubId
    device.addEmptyEventHubDevice(eventhubId);
    configureAndResetDevice(fdp, device);

    return device.template constructAndAddMapper<T>(eventhubId, args...);
}

} // namespace android