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 #pragma once
17
18 #include <map>
19 #include <memory>
20 #include <optional>
21
22 #include <EventHub.h>
23 #include <InputDevice.h>
24 #include <InputMapper.h>
25 #include <InputReader.h>
26 #include <ThreadSafeFuzzedDataProvider.h>
27
28 constexpr size_t kValidTypes[] = {EV_SW,
29 EV_SYN,
30 EV_ABS,
31 EV_KEY,
32 EV_MSC,
33 EV_REL,
34 android::EventHubInterface::DEVICE_ADDED,
35 android::EventHubInterface::DEVICE_REMOVED};
36
37 constexpr size_t kValidCodes[] = {
38 SYN_REPORT,
39 ABS_MT_SLOT,
40 SYN_MT_REPORT,
41 ABS_MT_POSITION_X,
42 ABS_MT_POSITION_Y,
43 ABS_MT_TOUCH_MAJOR,
44 ABS_MT_TOUCH_MINOR,
45 ABS_MT_WIDTH_MAJOR,
46 ABS_MT_WIDTH_MINOR,
47 ABS_MT_ORIENTATION,
48 ABS_MT_TRACKING_ID,
49 ABS_MT_PRESSURE,
50 ABS_MT_DISTANCE,
51 ABS_MT_TOOL_TYPE,
52 MSC_SCAN,
53 REL_X,
54 REL_Y,
55 REL_WHEEL,
56 REL_HWHEEL,
57 BTN_LEFT,
58 BTN_RIGHT,
59 BTN_MIDDLE,
60 BTN_BACK,
61 BTN_SIDE,
62 BTN_FORWARD,
63 BTN_EXTRA,
64 BTN_TASK,
65 };
66
67 constexpr size_t kMaxSize = 256;
68
69 namespace android {
70
71 template<class Fdp>
getFuzzedToolType(Fdp & fdp)72 ToolType getFuzzedToolType(Fdp& fdp) {
73 const int32_t toolType = fdp.template ConsumeIntegralInRange<int32_t>(
74 static_cast<int32_t>(ToolType::ftl_first),
75 static_cast<int32_t>(ToolType::ftl_last));
76 return static_cast<ToolType>(toolType);
77 }
78
79 template <class Fdp>
getFuzzedRawEvent(Fdp & fdp)80 RawEvent getFuzzedRawEvent(Fdp& fdp) {
81 const int32_t type = fdp.ConsumeBool() ? fdp.PickValueInArray(kValidTypes)
82 : fdp.template ConsumeIntegral<int32_t>();
83 const int32_t code = fdp.ConsumeBool() ? fdp.PickValueInArray(kValidCodes)
84 : fdp.template ConsumeIntegral<int32_t>();
85 return RawEvent{
86 .when = fdp.template ConsumeIntegral<nsecs_t>(),
87 .readTime = fdp.template ConsumeIntegral<nsecs_t>(),
88 .deviceId = fdp.template ConsumeIntegral<int32_t>(),
89 .type = type,
90 .code = code,
91 .value = fdp.template ConsumeIntegral<int32_t>(),
92 };
93 }
94
95 class FuzzEventHub : public EventHubInterface {
96 InputDeviceIdentifier mIdentifier;
97 std::vector<TouchVideoFrame> mVideoFrames;
98 PropertyMap mFuzzConfig;
99 std::map<int32_t /* deviceId */, std::map<int /* axis */, RawAbsoluteAxisInfo>> mAxes;
100 std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;
101
102 public:
FuzzEventHub(std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp)103 FuzzEventHub(std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp) : mFdp(std::move(fdp)) {}
~FuzzEventHub()104 ~FuzzEventHub() {}
addProperty(std::string key,std::string value)105 void addProperty(std::string key, std::string value) { mFuzzConfig.addProperty(key, value); }
106
getDeviceClasses(int32_t deviceId)107 ftl::Flags<InputDeviceClass> getDeviceClasses(int32_t deviceId) const override {
108 return ftl::Flags<InputDeviceClass>(mFdp->ConsumeIntegral<uint32_t>());
109 }
getDeviceIdentifier(int32_t deviceId)110 InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override {
111 return mIdentifier;
112 }
getDeviceControllerNumber(int32_t deviceId)113 int32_t getDeviceControllerNumber(int32_t deviceId) const override {
114 return mFdp->ConsumeIntegral<int32_t>();
115 }
getConfiguration(int32_t deviceId)116 std::optional<PropertyMap> getConfiguration(int32_t deviceId) const override {
117 return mFuzzConfig;
118 }
setAbsoluteAxisInfo(int32_t deviceId,int axis,const RawAbsoluteAxisInfo & axisInfo)119 void setAbsoluteAxisInfo(int32_t deviceId, int axis, const RawAbsoluteAxisInfo& axisInfo) {
120 mAxes[deviceId][axis] = axisInfo;
121 }
getAbsoluteAxisInfo(int32_t deviceId,int axis)122 std::optional<RawAbsoluteAxisInfo> getAbsoluteAxisInfo(int32_t deviceId,
123 int axis) const override {
124 if (auto deviceAxesIt = mAxes.find(deviceId); deviceAxesIt != mAxes.end()) {
125 const std::map<int, RawAbsoluteAxisInfo>& deviceAxes = deviceAxesIt->second;
126 if (auto axisInfoIt = deviceAxes.find(axis); axisInfoIt != deviceAxes.end()) {
127 return axisInfoIt->second;
128 }
129 }
130 if (mFdp->ConsumeBool()) {
131 return std::optional<RawAbsoluteAxisInfo>({
132 .minValue = mFdp->ConsumeIntegral<int32_t>(),
133 .maxValue = mFdp->ConsumeIntegral<int32_t>(),
134 .flat = mFdp->ConsumeIntegral<int32_t>(),
135 .fuzz = mFdp->ConsumeIntegral<int32_t>(),
136 .resolution = mFdp->ConsumeIntegral<int32_t>(),
137 });
138 } else {
139 return std::nullopt;
140 }
141 }
hasRelativeAxis(int32_t deviceId,int axis)142 bool hasRelativeAxis(int32_t deviceId, int axis) const override { return mFdp->ConsumeBool(); }
hasInputProperty(int32_t deviceId,int property)143 bool hasInputProperty(int32_t deviceId, int property) const override {
144 return mFdp->ConsumeBool();
145 }
hasMscEvent(int32_t deviceId,int mscEvent)146 bool hasMscEvent(int32_t deviceId, int mscEvent) const override { return mFdp->ConsumeBool(); }
mapKey(int32_t deviceId,int32_t scanCode,int32_t usageCode,int32_t metaState,int32_t * outKeycode,int32_t * outMetaState,uint32_t * outFlags)147 status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState,
148 int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const override {
149 return mFdp->ConsumeIntegral<status_t>();
150 }
mapAxis(int32_t deviceId,int32_t scanCode,AxisInfo * outAxisInfo)151 status_t mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const override {
152 return mFdp->ConsumeIntegral<status_t>();
153 }
setExcludedDevices(const std::vector<std::string> & devices)154 void setExcludedDevices(const std::vector<std::string>& devices) override {}
getEvents(int timeoutMillis)155 std::vector<RawEvent> getEvents(int timeoutMillis) override {
156 std::vector<RawEvent> events;
157 const size_t count = mFdp->ConsumeIntegralInRange<size_t>(0, kMaxSize);
158 for (size_t i = 0; i < count; ++i) {
159 events.push_back(getFuzzedRawEvent(*mFdp));
160 }
161 return events;
162 }
getVideoFrames(int32_t deviceId)163 std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override { return mVideoFrames; }
164
mapSensor(int32_t deviceId,int32_t absCode)165 base::Result<std::pair<InputDeviceSensorType, int32_t>> mapSensor(
166 int32_t deviceId, int32_t absCode) const override {
167 return base::ResultError("Fuzzer", UNKNOWN_ERROR);
168 };
169 // Raw batteries are sysfs power_supply nodes we found from the EventHub device sysfs node,
170 // containing the raw info of the sysfs node structure.
getRawBatteryIds(int32_t deviceId)171 std::vector<int32_t> getRawBatteryIds(int32_t deviceId) const override { return {}; }
getRawBatteryInfo(int32_t deviceId,int32_t BatteryId)172 std::optional<RawBatteryInfo> getRawBatteryInfo(int32_t deviceId,
173 int32_t BatteryId) const override {
174 return std::nullopt;
175 };
176
getRawLightIds(int32_t deviceId)177 std::vector<int32_t> getRawLightIds(int32_t deviceId) const override { return {}; };
getRawLightInfo(int32_t deviceId,int32_t lightId)178 std::optional<RawLightInfo> getRawLightInfo(int32_t deviceId, int32_t lightId) const override {
179 return std::nullopt;
180 };
getLightBrightness(int32_t deviceId,int32_t lightId)181 std::optional<int32_t> getLightBrightness(int32_t deviceId, int32_t lightId) const override {
182 return std::nullopt;
183 };
setLightBrightness(int32_t deviceId,int32_t lightId,int32_t brightness)184 void setLightBrightness(int32_t deviceId, int32_t lightId, int32_t brightness) override{};
getLightIntensities(int32_t deviceId,int32_t lightId)185 std::optional<std::unordered_map<LightColor, int32_t>> getLightIntensities(
186 int32_t deviceId, int32_t lightId) const override {
187 return std::nullopt;
188 };
setLightIntensities(int32_t deviceId,int32_t lightId,std::unordered_map<LightColor,int32_t> intensities)189 void setLightIntensities(int32_t deviceId, int32_t lightId,
190 std::unordered_map<LightColor, int32_t> intensities) override{};
191
getRawLayoutInfo(int32_t deviceId)192 std::optional<RawLayoutInfo> getRawLayoutInfo(int32_t deviceId) const override {
193 return std::nullopt;
194 };
195
getScanCodeState(int32_t deviceId,int32_t scanCode)196 int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override {
197 return mFdp->ConsumeIntegral<int32_t>();
198 }
getKeyCodeState(int32_t deviceId,int32_t keyCode)199 int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override {
200 return mFdp->ConsumeIntegral<int32_t>();
201 }
getSwitchState(int32_t deviceId,int32_t sw)202 int32_t getSwitchState(int32_t deviceId, int32_t sw) const override {
203 return mFdp->ConsumeIntegral<int32_t>();
204 }
setKeyRemapping(int32_t deviceId,const std::map<int32_t,int32_t> & keyRemapping)205 void setKeyRemapping(int32_t deviceId,
206 const std::map<int32_t, int32_t>& keyRemapping) const override {}
getKeyCodeForKeyLocation(int32_t deviceId,int32_t locationKeyCode)207 int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override {
208 return mFdp->ConsumeIntegral<int32_t>();
209 }
getAbsoluteAxisValue(int32_t deviceId,int32_t axis)210 std::optional<int32_t> getAbsoluteAxisValue(int32_t deviceId, int32_t axis) const override {
211 if (mFdp->ConsumeBool()) {
212 return mFdp->ConsumeIntegral<int32_t>();
213 } else {
214 return std::nullopt;
215 }
216 }
getMtSlotValues(int32_t deviceId,int32_t axis,size_t slotCount)217 base::Result<std::vector<int32_t>> getMtSlotValues(int32_t deviceId, int32_t axis,
218 size_t slotCount) const override {
219 if (mFdp->ConsumeBool()) {
220 std::vector<int32_t> outValues(slotCount + 1);
221 for (size_t i = 0; i < outValues.size(); i++) {
222 outValues.push_back(mFdp->ConsumeIntegral<int32_t>());
223 }
224 return std::move(outValues);
225 } else {
226 return base::ResultError("Fuzzer", UNKNOWN_ERROR);
227 }
228 }
markSupportedKeyCodes(int32_t deviceId,const std::vector<int32_t> & keyCodes,uint8_t * outFlags)229 bool markSupportedKeyCodes(int32_t deviceId, const std::vector<int32_t>& keyCodes,
230 uint8_t* outFlags) const override {
231 return mFdp->ConsumeBool();
232 }
hasScanCode(int32_t deviceId,int32_t scanCode)233 bool hasScanCode(int32_t deviceId, int32_t scanCode) const override {
234 return mFdp->ConsumeBool();
235 }
hasKeyCode(int32_t deviceId,int32_t keyCode)236 bool hasKeyCode(int32_t deviceId, int32_t keyCode) const override {
237 return mFdp->ConsumeBool();
238 }
hasLed(int32_t deviceId,int32_t led)239 bool hasLed(int32_t deviceId, int32_t led) const override { return mFdp->ConsumeBool(); }
setLedState(int32_t deviceId,int32_t led,bool on)240 void setLedState(int32_t deviceId, int32_t led, bool on) override {}
getVirtualKeyDefinitions(int32_t deviceId,std::vector<VirtualKeyDefinition> & outVirtualKeys)241 void getVirtualKeyDefinitions(
242 int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const override {}
getKeyCharacterMap(int32_t deviceId)243 const std::shared_ptr<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const override {
244 return nullptr;
245 }
setKeyboardLayoutOverlay(int32_t deviceId,std::shared_ptr<KeyCharacterMap> map)246 bool setKeyboardLayoutOverlay(int32_t deviceId, std::shared_ptr<KeyCharacterMap> map) override {
247 return mFdp->ConsumeBool();
248 }
vibrate(int32_t deviceId,const VibrationElement & effect)249 void vibrate(int32_t deviceId, const VibrationElement& effect) override {}
cancelVibrate(int32_t deviceId)250 void cancelVibrate(int32_t deviceId) override {}
251
getVibratorIds(int32_t deviceId)252 std::vector<int32_t> getVibratorIds(int32_t deviceId) const override { return {}; };
253
254 /* Query battery level. */
getBatteryCapacity(int32_t deviceId,int32_t batteryId)255 std::optional<int32_t> getBatteryCapacity(int32_t deviceId, int32_t batteryId) const override {
256 return std::nullopt;
257 };
258
259 /* Query battery status. */
getBatteryStatus(int32_t deviceId,int32_t batteryId)260 std::optional<int32_t> getBatteryStatus(int32_t deviceId, int32_t batteryId) const override {
261 return std::nullopt;
262 };
263
requestReopenDevices()264 void requestReopenDevices() override {}
wake()265 void wake() override {}
dump(std::string & dump)266 void dump(std::string& dump) const override {}
monitor()267 void monitor() const override {}
isDeviceEnabled(int32_t deviceId)268 bool isDeviceEnabled(int32_t deviceId) const override { return mFdp->ConsumeBool(); }
enableDevice(int32_t deviceId)269 status_t enableDevice(int32_t deviceId) override { return mFdp->ConsumeIntegral<status_t>(); }
disableDevice(int32_t deviceId)270 status_t disableDevice(int32_t deviceId) override { return mFdp->ConsumeIntegral<status_t>(); }
sysfsNodeChanged(const std::string & sysfsNodePath)271 void sysfsNodeChanged(const std::string& sysfsNodePath) override {}
setKernelWakeEnabled(int32_t deviceId,bool enabled)272 bool setKernelWakeEnabled(int32_t deviceId, bool enabled) override {
273 return mFdp->ConsumeBool();
274 }
275 };
276
277 class FuzzInputReaderPolicy : public InputReaderPolicyInterface {
278 TouchAffineTransformation mTransform;
279 std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;
280
281 protected:
~FuzzInputReaderPolicy()282 ~FuzzInputReaderPolicy() {}
283
284 public:
FuzzInputReaderPolicy(std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp)285 FuzzInputReaderPolicy(std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp) : mFdp(mFdp) {}
getReaderConfiguration(InputReaderConfiguration * outConfig)286 void getReaderConfiguration(InputReaderConfiguration* outConfig) override {}
notifyInputDevicesChanged(const std::vector<InputDeviceInfo> & inputDevices)287 void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override {}
notifyTouchpadHardwareState(const SelfContainedHardwareState & schs,int32_t deviceId)288 void notifyTouchpadHardwareState(const SelfContainedHardwareState& schs,
289 int32_t deviceId) override {}
notifyTouchpadGestureInfo(GestureType type,int32_t deviceId)290 void notifyTouchpadGestureInfo(GestureType type, int32_t deviceId) override {}
notifyTouchpadThreeFingerTap()291 void notifyTouchpadThreeFingerTap() override {}
getKeyboardLayoutOverlay(const InputDeviceIdentifier & identifier,const std::optional<KeyboardLayoutInfo> layoutInfo)292 std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
293 const InputDeviceIdentifier& identifier,
294 const std::optional<KeyboardLayoutInfo> layoutInfo) override {
295 return nullptr;
296 }
getDeviceAlias(const InputDeviceIdentifier & identifier)297 std::string getDeviceAlias(const InputDeviceIdentifier& identifier) {
298 return mFdp->ConsumeRandomLengthString(32);
299 }
getTouchAffineTransformation(const std::string & inputDeviceDescriptor,ui::Rotation surfaceRotation)300 TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
301 ui::Rotation surfaceRotation) override {
302 return mTransform;
303 }
setTouchAffineTransformation(const TouchAffineTransformation t)304 void setTouchAffineTransformation(const TouchAffineTransformation t) { mTransform = t; }
notifyStylusGestureStarted(int32_t,nsecs_t)305 void notifyStylusGestureStarted(int32_t, nsecs_t) {}
isInputMethodConnectionActive()306 bool isInputMethodConnectionActive() override { return mFdp->ConsumeBool(); }
getPointerViewportForAssociatedDisplay(ui::LogicalDisplayId associatedDisplayId)307 std::optional<DisplayViewport> getPointerViewportForAssociatedDisplay(
308 ui::LogicalDisplayId associatedDisplayId) override {
309 return {};
310 }
311 };
312
313 class FuzzInputListener : public virtual InputListenerInterface {
314 public:
notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs & args)315 void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override {}
notifyKey(const NotifyKeyArgs & args)316 void notifyKey(const NotifyKeyArgs& args) override {}
notifyMotion(const NotifyMotionArgs & args)317 void notifyMotion(const NotifyMotionArgs& args) override {}
notifySwitch(const NotifySwitchArgs & args)318 void notifySwitch(const NotifySwitchArgs& args) override {}
notifySensor(const NotifySensorArgs & args)319 void notifySensor(const NotifySensorArgs& args) override{};
notifyVibratorState(const NotifyVibratorStateArgs & args)320 void notifyVibratorState(const NotifyVibratorStateArgs& args) override{};
notifyDeviceReset(const NotifyDeviceResetArgs & args)321 void notifyDeviceReset(const NotifyDeviceResetArgs& args) override {}
notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs & args)322 void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override{};
323 };
324
325 class FuzzInputReaderContext : public InputReaderContext {
326 std::shared_ptr<EventHubInterface> mEventHub;
327 sp<InputReaderPolicyInterface> mPolicy;
328 std::shared_ptr<ThreadSafeFuzzedDataProvider> mFdp;
329
330 public:
FuzzInputReaderContext(std::shared_ptr<EventHubInterface> eventHub,std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp)331 FuzzInputReaderContext(std::shared_ptr<EventHubInterface> eventHub,
332 std::shared_ptr<ThreadSafeFuzzedDataProvider> fdp)
333 : mEventHub(eventHub), mPolicy(sp<FuzzInputReaderPolicy>::make(fdp)), mFdp(fdp) {}
~FuzzInputReaderContext()334 ~FuzzInputReaderContext() {}
updateGlobalMetaState()335 void updateGlobalMetaState() override {}
getGlobalMetaState()336 int32_t getGlobalMetaState() { return mFdp->ConsumeIntegral<int32_t>(); }
disableVirtualKeysUntil(nsecs_t time)337 void disableVirtualKeysUntil(nsecs_t time) override {}
shouldDropVirtualKey(nsecs_t now,int32_t keyCode,int32_t scanCode)338 bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) override {
339 return mFdp->ConsumeBool();
340 }
requestTimeoutAtTime(nsecs_t when)341 void requestTimeoutAtTime(nsecs_t when) override {}
bumpGeneration()342 int32_t bumpGeneration() override { return mFdp->ConsumeIntegral<int32_t>(); }
getExternalStylusDevices(std::vector<InputDeviceInfo> & outDevices)343 void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) override {}
dispatchExternalStylusState(const StylusState & outState)344 std::list<NotifyArgs> dispatchExternalStylusState(const StylusState& outState) override {
345 return {};
346 }
getPolicy()347 InputReaderPolicyInterface* getPolicy() override { return mPolicy.get(); }
getEventHub()348 EventHubInterface* getEventHub() override { return mEventHub.get(); }
getNextId()349 int32_t getNextId() override { return mFdp->ConsumeIntegral<int32_t>(); }
350
updateLedMetaState(int32_t metaState)351 void updateLedMetaState(int32_t metaState) override{};
getLedMetaState()352 int32_t getLedMetaState() override { return mFdp->ConsumeIntegral<int32_t>(); };
notifyStylusGestureStarted(int32_t,nsecs_t)353 void notifyStylusGestureStarted(int32_t, nsecs_t) {}
354
setPreventingTouchpadTaps(bool prevent)355 void setPreventingTouchpadTaps(bool prevent) override {}
isPreventingTouchpadTaps()356 bool isPreventingTouchpadTaps() override { return mFdp->ConsumeBool(); };
357
setLastKeyDownTimestamp(nsecs_t when)358 void setLastKeyDownTimestamp(nsecs_t when) { mLastKeyDownTimestamp = when; };
getLastKeyDownTimestamp()359 nsecs_t getLastKeyDownTimestamp() { return mLastKeyDownTimestamp; };
getKeyboardClassifier()360 KeyboardClassifier& getKeyboardClassifier() override { return *mClassifier; }
361
362 private:
363 nsecs_t mLastKeyDownTimestamp;
364 std::unique_ptr<KeyboardClassifier> mClassifier = std::make_unique<KeyboardClassifier>();
365 };
366
367 template <class Fdp>
getFuzzedInputDevice(Fdp & fdp,FuzzInputReaderContext * context)368 InputDevice getFuzzedInputDevice(Fdp& fdp, FuzzInputReaderContext* context) {
369 InputDeviceIdentifier identifier;
370 identifier.name = fdp.ConsumeRandomLengthString(16);
371 identifier.location = fdp.ConsumeRandomLengthString(12);
372 int32_t deviceID = fdp.ConsumeIntegralInRange(0, 5);
373 int32_t deviceGeneration = fdp.ConsumeIntegralInRange(0, 5);
374 return InputDevice(context, deviceID, deviceGeneration, identifier);
375 }
376
377 template <class Fdp>
configureAndResetDevice(Fdp & fdp,InputDevice & device)378 void configureAndResetDevice(Fdp& fdp, InputDevice& device) {
379 nsecs_t arbitraryTime = fdp.template ConsumeIntegral<nsecs_t>();
380 std::list<NotifyArgs> out;
381 out += device.configure(arbitraryTime, /*readerConfig=*/{}, /*changes=*/{});
382 out += device.reset(arbitraryTime);
383 }
384
385 template <class Fdp, class T, typename... Args>
getMapperForDevice(Fdp & fdp,InputDevice & device,Args...args)386 T& getMapperForDevice(Fdp& fdp, InputDevice& device, Args... args) {
387 int32_t eventhubId = fdp.template ConsumeIntegral<int32_t>();
388 // ensure a device entry exists for this eventHubId
389 device.addEmptyEventHubDevice(eventhubId);
390 configureAndResetDevice(fdp, device);
391
392 return device.template constructAndAddMapper<T>(eventhubId, args...);
393 }
394
395 } // namespace android
396