Merge "Clean up BBQ#abandon dead code"
diff --git a/libs/fakeservicemanager/Android.bp b/libs/fakeservicemanager/Android.bp
index 47c0657..29924ff 100644
--- a/libs/fakeservicemanager/Android.bp
+++ b/libs/fakeservicemanager/Android.bp
@@ -28,6 +28,7 @@
 cc_library {
     name: "libfakeservicemanager",
     defaults: ["fakeservicemanager_defaults"],
+    export_include_dirs: ["include/fakeservicemanager"],
 }
 
 cc_test_host {
@@ -37,4 +38,5 @@
         "test_sm.cpp",
     ],
     static_libs: ["libgmock"],
+    local_include_dirs: ["include/fakeservicemanager"],
 }
diff --git a/libs/fakeservicemanager/ServiceManager.h b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
similarity index 100%
rename from libs/fakeservicemanager/ServiceManager.h
rename to libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
diff --git a/libs/input/PropertyMap.cpp b/libs/input/PropertyMap.cpp
index 662e568..16ffa10 100644
--- a/libs/input/PropertyMap.cpp
+++ b/libs/input/PropertyMap.cpp
@@ -75,7 +75,7 @@
     }
 
     char* end;
-    int value = strtol(stringValue.c_str(), &end, 10);
+    int32_t value = static_cast<int32_t>(strtol(stringValue.c_str(), &end, 10));
     if (*end != '\0') {
         ALOGW("Property key '%s' has invalid value '%s'.  Expected an integer.", key.c_str(),
               stringValue.c_str());
diff --git a/services/inputflinger/tests/fuzzers/Android.bp b/services/inputflinger/tests/fuzzers/Android.bp
index 455a1e2..f4ecba2 100644
--- a/services/inputflinger/tests/fuzzers/Android.bp
+++ b/services/inputflinger/tests/fuzzers/Android.bp
@@ -46,3 +46,105 @@
        cc: ["android-framework-input@google.com"],
     },
 }
+
+cc_defaults {
+    name: "inputflinger_fuzz_defaults",
+    defaults: [
+        "inputflinger_defaults",
+    ],
+    include_dirs: [
+        "frameworks/native/services/inputflinger",
+    ],
+    shared_libs: [
+        "android.hardware.input.classifier@1.0",
+        "android.hardware.input.processor-V1-ndk",
+        "libbase",
+        "libbinder",
+        "libcutils",
+        "liblog",
+        "libutils",
+        "libui",
+        "libinput",
+        "libinputflinger",
+        "libinputreader",
+        "libinputflinger_base",
+        "libstatslog",
+    ],
+    header_libs: [
+        "libbatteryservice_headers",
+        "libinputreader_headers",
+    ],
+    fuzz_config: {
+       cc: ["android-framework-input@google.com"],
+    },
+}
+
+cc_fuzz {
+    name: "inputflinger_cursor_input_fuzzer",
+    defaults: [
+        "inputflinger_fuzz_defaults",
+    ],
+    srcs: [
+        "CursorInputFuzzer.cpp",
+    ],
+}
+
+cc_fuzz {
+    name: "inputflinger_keyboard_input_fuzzer",
+    defaults: [
+        "inputflinger_fuzz_defaults",
+    ],
+    srcs: [
+        "KeyboardInputFuzzer.cpp",
+    ],
+}
+
+cc_fuzz {
+    name: "inputflinger_multitouch_input_fuzzer",
+    defaults: [
+        "inputflinger_fuzz_defaults",
+    ],
+    srcs: [
+        "MultiTouchInputFuzzer.cpp",
+    ],
+}
+
+cc_fuzz {
+    name: "inputflinger_switch_input_fuzzer",
+    defaults: [
+        "inputflinger_fuzz_defaults",
+    ],
+    srcs: [
+        "SwitchInputFuzzer.cpp",
+    ],
+}
+
+cc_fuzz {
+    name: "inputflinger_input_reader_fuzzer",
+    defaults: [
+        "inputflinger_fuzz_defaults",
+    ],
+    srcs: [
+        "InputReaderFuzzer.cpp",
+    ],
+}
+
+cc_fuzz {
+    name: "inputflinger_blocking_queue_fuzzer",
+    defaults: [
+        "inputflinger_fuzz_defaults",
+    ],
+    srcs: [
+        "BlockingQueueFuzzer.cpp",
+    ],
+}
+
+cc_fuzz {
+    name: "inputflinger_input_classifier_fuzzer",
+    defaults: [
+        "inputflinger_fuzz_defaults",
+    ],
+    srcs: [
+        "InputClassifierFuzzer.cpp",
+    ],
+}
diff --git a/services/inputflinger/tests/fuzzers/BlockingQueueFuzzer.cpp b/services/inputflinger/tests/fuzzers/BlockingQueueFuzzer.cpp
new file mode 100644
index 0000000..d2595bf
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/BlockingQueueFuzzer.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <thread>
+#include "BlockingQueue.h"
+
+// Chosen to be a number large enough for variation in fuzzer runs, but not consume too much memory.
+static constexpr size_t MAX_CAPACITY = 1024;
+
+namespace android {
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp(data, size);
+    size_t capacity = fdp.ConsumeIntegralInRange<size_t>(1, MAX_CAPACITY);
+    size_t filled = 0;
+    BlockingQueue<int32_t> queue(capacity);
+
+    while (fdp.remaining_bytes() > 0) {
+        fdp.PickValueInArray<std::function<void()>>({
+                [&]() -> void {
+                    size_t numPushes = fdp.ConsumeIntegralInRange<size_t>(0, capacity + 1);
+                    for (size_t i = 0; i < numPushes; i++) {
+                        queue.push(fdp.ConsumeIntegral<int32_t>());
+                    }
+                    filled = std::min(capacity, filled + numPushes);
+                },
+                [&]() -> void {
+                    // Pops blocks if it is empty, so only pop up to num elements inserted.
+                    size_t numPops = fdp.ConsumeIntegralInRange<size_t>(0, filled);
+                    for (size_t i = 0; i < numPops; i++) {
+                        queue.pop();
+                    }
+                    filled > numPops ? filled -= numPops : filled = 0;
+                },
+                [&]() -> void {
+                    queue.clear();
+                    filled = 0;
+                },
+                [&]() -> void {
+                    int32_t eraseElement = fdp.ConsumeIntegral<int32_t>();
+                    queue.erase([&](int32_t element) {
+                        if (element == eraseElement) {
+                            filled--;
+                            return true;
+                        }
+                        return false;
+                    });
+                },
+        })();
+    }
+
+    return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
new file mode 100644
index 0000000..4b542aa
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+#include <CursorInputMapper.h>
+#include <FuzzContainer.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+static void addProperty(FuzzContainer& fuzzer, std::shared_ptr<FuzzedDataProvider> fdp) {
+    // Pick a random property to set for the mapper to have set.
+    fdp->PickValueInArray<std::function<void()>>(
+            {[&]() -> void { fuzzer.addProperty("cursor.mode", "pointer"); },
+             [&]() -> void { fuzzer.addProperty("cursor.mode", "navigation"); },
+             [&]() -> void {
+                 fuzzer.addProperty("cursor.mode", fdp->ConsumeRandomLengthString(100).data());
+             },
+             [&]() -> void {
+                 fuzzer.addProperty("cursor.orientationAware",
+                                    fdp->ConsumeRandomLengthString(100).data());
+             }})();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+    std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+    FuzzContainer fuzzer(fdp);
+
+    CursorInputMapper& mapper = fuzzer.getMapper<CursorInputMapper>();
+    auto policyConfig = fuzzer.getPolicyConfig();
+
+    // Loop through mapper operations until randomness is exhausted.
+    while (fdp->remaining_bytes() > 0) {
+        fdp->PickValueInArray<std::function<void()>>({
+                [&]() -> void { addProperty(fuzzer, fdp); },
+                [&]() -> void {
+                    std::string dump;
+                    mapper.dump(dump);
+                },
+                [&]() -> void { mapper.getSources(); },
+                [&]() -> void {
+                    mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+                                     fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    // Need to reconfigure with 0 or you risk a NPE.
+                    mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+                    InputDeviceInfo info;
+                    mapper.populateDeviceInfo(&info);
+                },
+                [&]() -> void {
+                    int32_t type, code;
+                    type = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidTypes)
+                                              : fdp->ConsumeIntegral<int32_t>();
+                    code = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidCodes)
+                                              : fdp->ConsumeIntegral<int32_t>();
+
+                    // Need to reconfigure with 0 or you risk a NPE.
+                    mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+                    RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+                                      fdp->ConsumeIntegral<nsecs_t>(),
+                                      fdp->ConsumeIntegral<int32_t>(),
+                                      type,
+                                      code,
+                                      fdp->ConsumeIntegral<int32_t>()};
+                    mapper.process(&rawEvent);
+                },
+                [&]() -> void { mapper.reset(fdp->ConsumeIntegral<nsecs_t>()); },
+                [&]() -> void {
+                    mapper.getScanCodeState(fdp->ConsumeIntegral<uint32_t>(),
+                                            fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    // Need to reconfigure with 0 or you risk a NPE.
+                    mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+                    mapper.getAssociatedDisplayId();
+                },
+        })();
+    }
+
+    return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/FuzzContainer.h b/services/inputflinger/tests/fuzzers/FuzzContainer.h
new file mode 100644
index 0000000..62615d0
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/FuzzContainer.h
@@ -0,0 +1,82 @@
+/*
+ * 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 <InputDevice.h>
+#include <InputMapper.h>
+#include <InputReader.h>
+#include <MapperHelpers.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+class FuzzContainer {
+    std::shared_ptr<FuzzEventHub> mFuzzEventHub;
+    sp<FuzzInputReaderPolicy> mFuzzPolicy;
+    std::unique_ptr<FuzzInputListener> mFuzzListener;
+    std::unique_ptr<FuzzInputReaderContext> mFuzzContext;
+    std::unique_ptr<InputDevice> mFuzzDevice;
+    InputReaderConfiguration mPolicyConfig;
+    std::shared_ptr<FuzzedDataProvider> mFdp;
+
+public:
+    FuzzContainer(std::shared_ptr<FuzzedDataProvider> fdp) : mFdp(fdp) {
+        // Setup parameters.
+        std::string deviceName = mFdp->ConsumeRandomLengthString(16);
+        std::string deviceLocation = mFdp->ConsumeRandomLengthString(12);
+        int32_t deviceID = mFdp->ConsumeIntegralInRange<int32_t>(0, 5);
+        int32_t deviceGeneration = mFdp->ConsumeIntegralInRange<int32_t>(/*from*/ 0, /*to*/ 5);
+
+        // Create mocked objects.
+        mFuzzEventHub = std::make_shared<FuzzEventHub>(mFdp);
+        mFuzzPolicy = sp<FuzzInputReaderPolicy>::make(mFdp);
+        mFuzzListener = std::make_unique<FuzzInputListener>();
+        mFuzzContext = std::make_unique<FuzzInputReaderContext>(mFuzzEventHub, mFuzzPolicy,
+                                                                *mFuzzListener, mFdp);
+
+        InputDeviceIdentifier identifier;
+        identifier.name = deviceName;
+        identifier.location = deviceLocation;
+        mFuzzDevice = std::make_unique<InputDevice>(mFuzzContext.get(), deviceID, deviceGeneration,
+                                                    identifier);
+        mFuzzPolicy->getReaderConfiguration(&mPolicyConfig);
+    }
+
+    ~FuzzContainer() {}
+
+    void configureDevice() {
+        nsecs_t arbitraryTime = mFdp->ConsumeIntegral<nsecs_t>();
+        mFuzzDevice->configure(arbitraryTime, &mPolicyConfig, 0);
+        mFuzzDevice->reset(arbitraryTime);
+    }
+
+    void addProperty(std::string key, std::string value) {
+        mFuzzEventHub->addProperty(key, value);
+        configureDevice();
+    }
+
+    InputReaderConfiguration& getPolicyConfig() { return mPolicyConfig; }
+
+    template <class T, typename... Args>
+    T& getMapper(Args... args) {
+        T& mapper = mFuzzDevice->addMapper<T>(mFdp->ConsumeIntegral<int32_t>(), args...);
+        configureDevice();
+        return mapper;
+    }
+};
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
new file mode 100644
index 0000000..c407cff
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+#include <MapperHelpers.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include "InputCommonConverter.h"
+#include "InputProcessor.h"
+
+namespace android {
+
+static constexpr int32_t MAX_AXES = 64;
+
+// Used by two fuzz operations and a bit lengthy, so pulled out into a function.
+NotifyMotionArgs generateFuzzedMotionArgs(FuzzedDataProvider &fdp) {
+    // Create a basic motion event for testing
+    PointerProperties properties;
+    properties.id = 0;
+    properties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+    PointerCoords coords;
+    coords.clear();
+    for (int32_t i = 0; i < fdp.ConsumeIntegralInRange<int32_t>(0, MAX_AXES); i++) {
+        coords.setAxisValue(fdp.ConsumeIntegral<int32_t>(), fdp.ConsumeFloatingPoint<float>());
+    }
+
+    const nsecs_t downTime = 2;
+    const nsecs_t readTime = downTime + fdp.ConsumeIntegralInRange<nsecs_t>(0, 1E8);
+    NotifyMotionArgs motionArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/,
+                                downTime /*eventTime*/, readTime,
+                                fdp.ConsumeIntegral<int32_t>() /*deviceId*/, AINPUT_SOURCE_ANY,
+                                ADISPLAY_ID_DEFAULT,
+                                fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/,
+                                AMOTION_EVENT_ACTION_DOWN,
+                                fdp.ConsumeIntegral<int32_t>() /*actionButton*/,
+                                fdp.ConsumeIntegral<int32_t>() /*flags*/, AMETA_NONE,
+                                fdp.ConsumeIntegral<int32_t>() /*buttonState*/,
+                                MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
+                                1 /*pointerCount*/, &properties, &coords,
+                                fdp.ConsumeFloatingPoint<float>() /*xPrecision*/,
+                                fdp.ConsumeFloatingPoint<float>() /*yPrecision*/,
+                                AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                                AMOTION_EVENT_INVALID_CURSOR_POSITION, downTime,
+                                {} /*videoFrames*/);
+    return motionArgs;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
+    FuzzedDataProvider fdp(data, size);
+
+    std::unique_ptr<FuzzInputListener> mFuzzListener = std::make_unique<FuzzInputListener>();
+    std::unique_ptr<InputProcessorInterface> mClassifier =
+            std::make_unique<InputProcessor>(*mFuzzListener);
+
+    while (fdp.remaining_bytes() > 0) {
+        fdp.PickValueInArray<std::function<void()>>({
+                [&]() -> void {
+                    // SendToNextStage_NotifyConfigurationChangedArgs
+                    NotifyConfigurationChangedArgs
+                            args(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/,
+                                 fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/);
+                    mClassifier->notifyConfigurationChanged(&args);
+                },
+                [&]() -> void {
+                    // SendToNextStage_NotifyKeyArgs
+                    const nsecs_t eventTime = fdp.ConsumeIntegral<nsecs_t>();
+                    const nsecs_t readTime =
+                            eventTime + fdp.ConsumeIntegralInRange<nsecs_t>(0, 1E8);
+                    NotifyKeyArgs keyArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/,
+                                          eventTime, readTime,
+                                          fdp.ConsumeIntegral<int32_t>() /*deviceId*/,
+                                          AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_DEFAULT,
+                                          fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/,
+                                          AKEY_EVENT_ACTION_DOWN,
+                                          fdp.ConsumeIntegral<int32_t>() /*flags*/, AKEYCODE_HOME,
+                                          fdp.ConsumeIntegral<int32_t>() /*scanCode*/, AMETA_NONE,
+                                          fdp.ConsumeIntegral<nsecs_t>() /*downTime*/);
+
+                    mClassifier->notifyKey(&keyArgs);
+                },
+                [&]() -> void {
+                    // SendToNextStage_NotifyMotionArgs
+                    NotifyMotionArgs motionArgs = generateFuzzedMotionArgs(fdp);
+                    mClassifier->notifyMotion(&motionArgs);
+                },
+                [&]() -> void {
+                    // SendToNextStage_NotifySwitchArgs
+                    NotifySwitchArgs switchArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/,
+                                                fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/,
+                                                fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/,
+                                                fdp.ConsumeIntegral<uint32_t>() /*switchValues*/,
+                                                fdp.ConsumeIntegral<uint32_t>() /*switchMask*/);
+
+                    mClassifier->notifySwitch(&switchArgs);
+                },
+                [&]() -> void {
+                    // SendToNextStage_NotifyDeviceResetArgs
+                    NotifyDeviceResetArgs resetArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/,
+                                                    fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/,
+                                                    fdp.ConsumeIntegral<int32_t>() /*deviceId*/);
+
+                    mClassifier->notifyDeviceReset(&resetArgs);
+                },
+                [&]() -> void {
+                    // InputClassifierConverterTest
+                    const NotifyMotionArgs motionArgs = generateFuzzedMotionArgs(fdp);
+                    aidl::android::hardware::input::common::MotionEvent motionEvent =
+                            notifyMotionArgsToHalMotionEvent(motionArgs);
+                },
+        })();
+    }
+    return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
new file mode 100644
index 0000000..f15d871
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
@@ -0,0 +1,279 @@
+/*
+ * 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.
+ */
+
+#include <InputReader.h>
+#include <MapperHelpers.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <input/InputDevice.h>
+#include <chrono>
+#include <thread>
+
+namespace android {
+
+constexpr InputDeviceSensorType kInputDeviceSensorType[] = {
+        InputDeviceSensorType::ACCELEROMETER,
+        InputDeviceSensorType::MAGNETIC_FIELD,
+        InputDeviceSensorType::ORIENTATION,
+        InputDeviceSensorType::GYROSCOPE,
+        InputDeviceSensorType::LIGHT,
+        InputDeviceSensorType::PRESSURE,
+        InputDeviceSensorType::TEMPERATURE,
+        InputDeviceSensorType::PROXIMITY,
+        InputDeviceSensorType::GRAVITY,
+        InputDeviceSensorType::LINEAR_ACCELERATION,
+        InputDeviceSensorType::ROTATION_VECTOR,
+        InputDeviceSensorType::RELATIVE_HUMIDITY,
+        InputDeviceSensorType::AMBIENT_TEMPERATURE,
+        InputDeviceSensorType::MAGNETIC_FIELD_UNCALIBRATED,
+        InputDeviceSensorType::GAME_ROTATION_VECTOR,
+        InputDeviceSensorType::GYROSCOPE_UNCALIBRATED,
+        InputDeviceSensorType::SIGNIFICANT_MOTION,
+};
+
+class FuzzInputReader : public InputReaderInterface {
+public:
+    FuzzInputReader(std::shared_ptr<EventHubInterface> fuzzEventHub,
+                    const sp<InputReaderPolicyInterface>& fuzzPolicy,
+                    InputListenerInterface& fuzzListener) {
+        reader = std::make_unique<InputReader>(fuzzEventHub, fuzzPolicy, fuzzListener);
+    }
+
+    void dump(std::string& dump) { reader->dump(dump); }
+
+    void monitor() { reader->monitor(); }
+
+    bool isInputDeviceEnabled(int32_t deviceId) { return reader->isInputDeviceEnabled(deviceId); }
+
+    status_t start() { return reader->start(); }
+
+    status_t stop() { return reader->stop(); }
+
+    std::vector<InputDeviceInfo> getInputDevices() const { return reader->getInputDevices(); }
+
+    int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask, int32_t scanCode) {
+        return reader->getScanCodeState(deviceId, sourceMask, scanCode);
+    }
+
+    int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) {
+        return reader->getKeyCodeState(deviceId, sourceMask, keyCode);
+    }
+
+    int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) {
+        return reader->getSwitchState(deviceId, sourceMask, sw);
+    }
+
+    void toggleCapsLockState(int32_t deviceId) { reader->toggleCapsLockState(deviceId); }
+
+    bool hasKeys(int32_t deviceId, uint32_t sourceMask, const std::vector<int32_t>& keyCodes,
+                 uint8_t* outFlags) {
+        return reader->hasKeys(deviceId, sourceMask, keyCodes, outFlags);
+    }
+
+    void requestRefreshConfiguration(uint32_t changes) {
+        reader->requestRefreshConfiguration(changes);
+    }
+
+    void vibrate(int32_t deviceId, const VibrationSequence& sequence, ssize_t repeat,
+                 int32_t token) {
+        reader->vibrate(deviceId, sequence, repeat, token);
+    }
+
+    void cancelVibrate(int32_t deviceId, int32_t token) { reader->cancelVibrate(deviceId, token); }
+
+    bool isVibrating(int32_t deviceId) { return reader->isVibrating(deviceId); }
+
+    std::vector<int32_t> getVibratorIds(int32_t deviceId) {
+        return reader->getVibratorIds(deviceId);
+    }
+
+    std::optional<int32_t> getBatteryCapacity(int32_t deviceId) {
+        return reader->getBatteryCapacity(deviceId);
+    }
+
+    std::optional<int32_t> getBatteryStatus(int32_t deviceId) {
+        return reader->getBatteryStatus(deviceId);
+    }
+
+    std::vector<InputDeviceLightInfo> getLights(int32_t deviceId) {
+        return reader->getLights(deviceId);
+    }
+
+    std::vector<InputDeviceSensorInfo> getSensors(int32_t deviceId) {
+        return reader->getSensors(deviceId);
+    }
+
+    bool canDispatchToDisplay(int32_t deviceId, int32_t displayId) {
+        return reader->canDispatchToDisplay(deviceId, displayId);
+    }
+
+    bool enableSensor(int32_t deviceId, InputDeviceSensorType sensorType,
+                      std::chrono::microseconds samplingPeriod,
+                      std::chrono::microseconds maxBatchReportLatency) {
+        return reader->enableSensor(deviceId, sensorType, samplingPeriod, maxBatchReportLatency);
+    }
+
+    void disableSensor(int32_t deviceId, InputDeviceSensorType sensorType) {
+        return reader->disableSensor(deviceId, sensorType);
+    }
+
+    void flushSensor(int32_t deviceId, InputDeviceSensorType sensorType) {
+        return reader->flushSensor(deviceId, sensorType);
+    }
+
+    bool setLightColor(int32_t deviceId, int32_t lightId, int32_t color) {
+        return reader->setLightColor(deviceId, lightId, color);
+    }
+
+    bool setLightPlayerId(int32_t deviceId, int32_t lightId, int32_t playerId) {
+        return reader->setLightPlayerId(deviceId, lightId, playerId);
+    }
+
+    std::optional<int32_t> getLightColor(int32_t deviceId, int32_t lightId) {
+        return reader->getLightColor(deviceId, lightId);
+    }
+
+    std::optional<int32_t> getLightPlayerId(int32_t deviceId, int32_t lightId) {
+        return reader->getLightPlayerId(deviceId, lightId);
+    }
+
+    int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const {
+        return reader->getKeyCodeForKeyLocation(deviceId, locationKeyCode);
+    }
+
+private:
+    std::unique_ptr<InputReaderInterface> reader;
+};
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+    std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+
+    FuzzInputListener fuzzListener;
+    sp<FuzzInputReaderPolicy> fuzzPolicy = sp<FuzzInputReaderPolicy>::make(fdp);
+    std::shared_ptr<FuzzEventHub> fuzzEventHub = std::make_shared<FuzzEventHub>(fdp);
+    std::unique_ptr<FuzzInputReader> reader =
+            std::make_unique<FuzzInputReader>(fuzzEventHub, fuzzPolicy, fuzzListener);
+    fuzzEventHub->addEvents(fdp);
+    size_t patternCount = fdp->ConsumeIntegralInRange<size_t>(1, 260);
+    VibrationSequence pattern(patternCount);
+    for (size_t i = 0; i < patternCount; ++i) {
+        VibrationElement element(i);
+        element.addChannel(fdp->ConsumeIntegral<int32_t>() /* vibratorId */,
+                           fdp->ConsumeIntegral<uint8_t>() /* amplitude */);
+        pattern.addElement(element);
+    }
+    reader->vibrate(fdp->ConsumeIntegral<int32_t>(), pattern,
+                    fdp->ConsumeIntegral<ssize_t>() /*repeat*/,
+                    fdp->ConsumeIntegral<int32_t>() /*token*/);
+    reader->start();
+
+    // Loop through mapper operations until randomness is exhausted.
+    while (fdp->remaining_bytes() > 0) {
+        fdp->PickValueInArray<std::function<void()>>({
+                [&]() -> void {
+                    std::string dump;
+                    reader->dump(dump);
+                },
+                [&]() -> void { reader->monitor(); },
+                [&]() -> void { reader->getInputDevices(); },
+                [&]() -> void { reader->isInputDeviceEnabled(fdp->ConsumeIntegral<int32_t>()); },
+                [&]() -> void {
+                    reader->getScanCodeState(fdp->ConsumeIntegral<int32_t>(),
+                                             fdp->ConsumeIntegral<uint32_t>(),
+                                             fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    reader->getKeyCodeState(fdp->ConsumeIntegral<int32_t>(),
+                                            fdp->ConsumeIntegral<uint32_t>(),
+                                            fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    reader->getSwitchState(fdp->ConsumeIntegral<int32_t>(),
+                                           fdp->ConsumeIntegral<uint32_t>(),
+                                           fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void { reader->toggleCapsLockState(fdp->ConsumeIntegral<int32_t>()); },
+                [&]() -> void {
+                    size_t count = fdp->ConsumeIntegralInRange<size_t>(1, 1024);
+                    std::vector<uint8_t> outFlags(count);
+                    std::vector<int32_t> keyCodes;
+                    for (size_t i = 0; i < count; ++i) {
+                        keyCodes.push_back(fdp->ConsumeIntegral<int32_t>());
+                    }
+                    reader->hasKeys(fdp->ConsumeIntegral<int32_t>(),
+                                    fdp->ConsumeIntegral<uint32_t>(), keyCodes, outFlags.data());
+                },
+                [&]() -> void {
+                    reader->requestRefreshConfiguration(fdp->ConsumeIntegral<uint32_t>());
+                },
+                [&]() -> void {
+                    reader->cancelVibrate(fdp->ConsumeIntegral<int32_t>(),
+                                          fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    reader->canDispatchToDisplay(fdp->ConsumeIntegral<int32_t>(),
+                                                 fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    reader->getKeyCodeForKeyLocation(fdp->ConsumeIntegral<int32_t>(),
+                                                     fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void { reader->getBatteryCapacity(fdp->ConsumeIntegral<int32_t>()); },
+                [&]() -> void { reader->getBatteryStatus(fdp->ConsumeIntegral<int32_t>()); },
+                [&]() -> void { reader->getLights(fdp->ConsumeIntegral<int32_t>()); },
+                [&]() -> void { reader->getSensors(fdp->ConsumeIntegral<int32_t>()); },
+                [&]() -> void {
+                    reader->getLightPlayerId(fdp->ConsumeIntegral<int32_t>(),
+                                             fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    reader->getLightColor(fdp->ConsumeIntegral<int32_t>(),
+                                          fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    reader->setLightPlayerId(fdp->ConsumeIntegral<int32_t>(),
+                                             fdp->ConsumeIntegral<int32_t>(),
+                                             fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    reader->setLightColor(fdp->ConsumeIntegral<int32_t>(),
+                                          fdp->ConsumeIntegral<int32_t>(),
+                                          fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    reader->flushSensor(fdp->ConsumeIntegral<int32_t>(),
+                                        fdp->PickValueInArray<InputDeviceSensorType>(
+                                                kInputDeviceSensorType));
+                },
+                [&]() -> void {
+                    reader->disableSensor(fdp->ConsumeIntegral<int32_t>(),
+                                          fdp->PickValueInArray<InputDeviceSensorType>(
+                                                  kInputDeviceSensorType));
+                },
+                [&]() -> void {
+                    reader->enableSensor(fdp->ConsumeIntegral<int32_t>(),
+                                         fdp->PickValueInArray<InputDeviceSensorType>(
+                                                 kInputDeviceSensorType),
+                                         std::chrono::microseconds(fdp->ConsumeIntegral<size_t>()),
+                                         std::chrono::microseconds(fdp->ConsumeIntegral<size_t>()));
+                },
+        })();
+    }
+
+    reader->stop();
+    return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
new file mode 100644
index 0000000..c48a099
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+#include <FuzzContainer.h>
+#include <KeyboardInputMapper.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+const int32_t kMaxKeycodes = 100;
+
+static void addProperty(FuzzContainer& fuzzer, std::shared_ptr<FuzzedDataProvider> fdp) {
+    // Pick a random property to set for the mapper to have set.
+    fdp->PickValueInArray<std::function<void()>>(
+            {[&]() -> void { fuzzer.addProperty("keyboard.orientationAware", "1"); },
+             [&]() -> void {
+                 fuzzer.addProperty("keyboard.orientationAware",
+                                    fdp->ConsumeRandomLengthString(100).data());
+             },
+             [&]() -> void {
+                 fuzzer.addProperty("keyboard.doNotWakeByDefault",
+                                    fdp->ConsumeRandomLengthString(100).data());
+             },
+             [&]() -> void {
+                 fuzzer.addProperty("keyboard.handlesKeyRepeat",
+                                    fdp->ConsumeRandomLengthString(100).data());
+             }})();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+    std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+    FuzzContainer fuzzer(fdp);
+
+    KeyboardInputMapper& mapper =
+            fuzzer.getMapper<KeyboardInputMapper>(fdp->ConsumeIntegral<uint32_t>(),
+                                                  fdp->ConsumeIntegral<int32_t>());
+    auto policyConfig = fuzzer.getPolicyConfig();
+
+    // Loop through mapper operations until randomness is exhausted.
+    while (fdp->remaining_bytes() > 0) {
+        fdp->PickValueInArray<std::function<void()>>({
+                [&]() -> void { addProperty(fuzzer, fdp); },
+                [&]() -> void {
+                    std::string dump;
+                    mapper.dump(dump);
+                },
+                [&]() -> void {
+                    InputDeviceInfo info;
+                    mapper.populateDeviceInfo(&info);
+                },
+                [&]() -> void { mapper.getSources(); },
+                [&]() -> void {
+                    mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+                                     fdp->ConsumeIntegral<uint32_t>());
+                },
+                [&]() -> void { mapper.reset(fdp->ConsumeIntegral<nsecs_t>()); },
+                [&]() -> void {
+                    int32_t type, code;
+                    type = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidTypes)
+                                              : fdp->ConsumeIntegral<int32_t>();
+                    code = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidCodes)
+                                              : fdp->ConsumeIntegral<int32_t>();
+                    RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+                                      fdp->ConsumeIntegral<nsecs_t>(),
+                                      fdp->ConsumeIntegral<int32_t>(),
+                                      type,
+                                      code,
+                                      fdp->ConsumeIntegral<int32_t>()};
+                    mapper.process(&rawEvent);
+                },
+                [&]() -> void {
+                    mapper.getKeyCodeState(fdp->ConsumeIntegral<uint32_t>(),
+                                           fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    mapper.getScanCodeState(fdp->ConsumeIntegral<uint32_t>(),
+                                            fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    std::vector<int32_t> keyCodes;
+                    int32_t numBytes = fdp->ConsumeIntegralInRange<int32_t>(0, kMaxKeycodes);
+                    for (int32_t i = 0; i < numBytes; ++i) {
+                        keyCodes.push_back(fdp->ConsumeIntegral<int32_t>());
+                    }
+                    mapper.markSupportedKeyCodes(fdp->ConsumeIntegral<uint32_t>(), keyCodes,
+                                                 nullptr);
+                },
+                [&]() -> void { mapper.getMetaState(); },
+                [&]() -> void { mapper.updateMetaState(fdp->ConsumeIntegral<int32_t>()); },
+                [&]() -> void { mapper.getAssociatedDisplayId(); },
+        })();
+    }
+
+    return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h
new file mode 100644
index 0000000..53a7b16
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h
@@ -0,0 +1,372 @@
+/*
+ * 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 <InputDevice.h>
+#include <InputMapper.h>
+#include <InputReader.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include "android/hardware/input/InputDeviceCountryCode.h"
+
+using android::hardware::input::InputDeviceCountryCode;
+
+constexpr size_t kValidTypes[] = {EV_SW,
+                                  EV_SYN,
+                                  SYN_REPORT,
+                                  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,
+        SYN_MT_REPORT,
+        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 InputDeviceCountryCode kCountryCodes[] = {
+        InputDeviceCountryCode::INVALID,
+        InputDeviceCountryCode::NOT_SUPPORTED,
+        InputDeviceCountryCode::ARABIC,
+        InputDeviceCountryCode::BELGIAN,
+        InputDeviceCountryCode::CANADIAN_BILINGUAL,
+        InputDeviceCountryCode::CANADIAN_FRENCH,
+        InputDeviceCountryCode::CZECH_REPUBLIC,
+        InputDeviceCountryCode::DANISH,
+        InputDeviceCountryCode::FINNISH,
+        InputDeviceCountryCode::FRENCH,
+        InputDeviceCountryCode::GERMAN,
+        InputDeviceCountryCode::GREEK,
+        InputDeviceCountryCode::HEBREW,
+        InputDeviceCountryCode::HUNGARY,
+        InputDeviceCountryCode::INTERNATIONAL,
+        InputDeviceCountryCode::ITALIAN,
+        InputDeviceCountryCode::JAPAN,
+        InputDeviceCountryCode::KOREAN,
+        InputDeviceCountryCode::LATIN_AMERICAN,
+        InputDeviceCountryCode::DUTCH,
+        InputDeviceCountryCode::NORWEGIAN,
+        InputDeviceCountryCode::PERSIAN,
+        InputDeviceCountryCode::POLAND,
+        InputDeviceCountryCode::PORTUGUESE,
+        InputDeviceCountryCode::RUSSIA,
+        InputDeviceCountryCode::SLOVAKIA,
+        InputDeviceCountryCode::SPANISH,
+        InputDeviceCountryCode::SWEDISH,
+        InputDeviceCountryCode::SWISS_FRENCH,
+        InputDeviceCountryCode::SWISS_GERMAN,
+        InputDeviceCountryCode::SWITZERLAND,
+        InputDeviceCountryCode::TAIWAN,
+        InputDeviceCountryCode::TURKISH_Q,
+        InputDeviceCountryCode::UK,
+        InputDeviceCountryCode::US,
+        InputDeviceCountryCode::YUGOSLAVIA,
+        InputDeviceCountryCode::TURKISH_F,
+};
+
+constexpr size_t kMaxSize = 256;
+
+namespace android {
+
+class FuzzEventHub : public EventHubInterface {
+    InputDeviceIdentifier mIdentifier;
+    std::vector<TouchVideoFrame> mVideoFrames;
+    PropertyMap mFuzzConfig;
+    size_t mCount = 0;
+    std::array<RawEvent, kMaxSize> mBuf;
+    std::shared_ptr<FuzzedDataProvider> mFdp;
+
+public:
+    FuzzEventHub(std::shared_ptr<FuzzedDataProvider> fdp) : mFdp(std::move(fdp)) {}
+    ~FuzzEventHub() {}
+    void addProperty(std::string key, std::string value) { mFuzzConfig.addProperty(key, value); }
+    void addEvents(std::shared_ptr<FuzzedDataProvider> fdp) {
+        mCount = fdp->ConsumeIntegralInRange<size_t>(0, kMaxSize);
+
+        for (size_t i = 0; i < mCount; ++i) {
+            int32_t type = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidTypes)
+                                              : fdp->ConsumeIntegral<int32_t>();
+            int32_t code = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidCodes)
+                                              : fdp->ConsumeIntegral<int32_t>();
+            mBuf[i] = {fdp->ConsumeIntegral<nsecs_t>(),
+                       fdp->ConsumeIntegral<nsecs_t>(),
+                       fdp->ConsumeIntegral<int32_t>(),
+                       type,
+                       code,
+                       fdp->ConsumeIntegral<int32_t>()};
+        }
+    }
+
+    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>();
+    }
+    void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const override {
+        *outConfiguration = mFuzzConfig;
+    }
+    status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+                                 RawAbsoluteAxisInfo* outAxisInfo) const override {
+        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 {}
+    size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) override {
+        for (size_t i = 0; i < mCount; ++i) buffer[i] = mBuf[i];
+
+        return mCount;
+    }
+    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{};
+
+    InputDeviceCountryCode getCountryCode(int32_t deviceId) const override {
+        return mFdp->PickValueInArray<InputDeviceCountryCode>(kCountryCodes);
+    };
+
+    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>();
+    }
+    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>();
+    }
+    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>(); }
+};
+
+class FuzzPointerController : public PointerControllerInterface {
+    std::shared_ptr<FuzzedDataProvider> mFdp;
+
+public:
+    FuzzPointerController(std::shared_ptr<FuzzedDataProvider> mFdp) : mFdp(mFdp) {}
+    ~FuzzPointerController() {}
+    bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const override {
+        return mFdp->ConsumeBool();
+    }
+    void move(float deltaX, float deltaY) override {}
+    void setButtonState(int32_t buttonState) override {}
+    int32_t getButtonState() const override { return mFdp->ConsumeIntegral<int32_t>(); }
+    void setPosition(float x, float y) override {}
+    void getPosition(float* outX, float* outY) const override {}
+    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 {}
+};
+
+class FuzzInputReaderPolicy : public InputReaderPolicyInterface {
+    TouchAffineTransformation mTransform;
+    std::shared_ptr<FuzzPointerController> mPointerController;
+    std::shared_ptr<FuzzedDataProvider> mFdp;
+
+protected:
+    ~FuzzInputReaderPolicy() {}
+
+public:
+    FuzzInputReaderPolicy(std::shared_ptr<FuzzedDataProvider> 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) override {
+        return nullptr;
+    }
+    std::string getDeviceAlias(const InputDeviceIdentifier& identifier) {
+        return mFdp->ConsumeRandomLengthString(32);
+    }
+    TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
+                                                           int32_t surfaceRotation) override {
+        return mTransform;
+    }
+    void setTouchAffineTransformation(const TouchAffineTransformation t) { mTransform = t; }
+};
+
+class FuzzInputListener : public virtual InputListenerInterface {
+public:
+    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;
+    InputListenerInterface& mListener;
+    std::shared_ptr<FuzzedDataProvider> mFdp;
+
+public:
+    FuzzInputReaderContext(std::shared_ptr<EventHubInterface> eventHub,
+                           const sp<InputReaderPolicyInterface>& policy,
+                           InputListenerInterface& listener,
+                           std::shared_ptr<FuzzedDataProvider> mFdp)
+          : mEventHub(eventHub), mPolicy(policy), mListener(listener), mFdp(mFdp) {}
+    ~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 {}
+    void dispatchExternalStylusState(const StylusState& outState) override {}
+    InputReaderPolicyInterface* getPolicy() override { return mPolicy.get(); }
+    InputListenerInterface& getListener() override { return mListener; }
+    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>(); };
+};
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
new file mode 100644
index 0000000..59b0642
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+#include <FuzzContainer.h>
+#include <MultiTouchInputMapper.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+const int32_t kMaxKeycodes = 100;
+
+static void addProperty(FuzzContainer& fuzzer, std::shared_ptr<FuzzedDataProvider> fdp) {
+    // Pick a random property to set for the mapper to have set.
+    fdp->PickValueInArray<std::function<void()>>(
+            {[&]() -> void { fuzzer.addProperty("touch.deviceType", "touchScreen"); },
+             [&]() -> void {
+                 fuzzer.addProperty("touch.deviceType", fdp->ConsumeRandomLengthString(8).data());
+             },
+             [&]() -> void {
+                 fuzzer.addProperty("touch.size.scale", fdp->ConsumeRandomLengthString(8).data());
+             },
+             [&]() -> void {
+                 fuzzer.addProperty("touch.size.bias", fdp->ConsumeRandomLengthString(8).data());
+             },
+             [&]() -> void {
+                 fuzzer.addProperty("touch.size.isSummed",
+                                    fdp->ConsumeRandomLengthString(8).data());
+             },
+             [&]() -> void {
+                 fuzzer.addProperty("touch.size.calibration",
+                                    fdp->ConsumeRandomLengthString(8).data());
+             },
+             [&]() -> void {
+                 fuzzer.addProperty("touch.pressure.scale",
+                                    fdp->ConsumeRandomLengthString(8).data());
+             },
+             [&]() -> void {
+                 fuzzer.addProperty("touch.size.calibration",
+                                    fdp->ConsumeBool() ? "diameter" : "area");
+             },
+             [&]() -> void {
+                 fuzzer.addProperty("touch.pressure.calibration",
+                                    fdp->ConsumeRandomLengthString(8).data());
+             }})();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+    std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+    FuzzContainer fuzzer(fdp);
+
+    MultiTouchInputMapper& mapper = fuzzer.getMapper<MultiTouchInputMapper>();
+    auto policyConfig = fuzzer.getPolicyConfig();
+
+    // Loop through mapper operations until randomness is exhausted.
+    while (fdp->remaining_bytes() > 0) {
+        fdp->PickValueInArray<std::function<void()>>({
+                [&]() -> void { addProperty(fuzzer, fdp); },
+                [&]() -> void {
+                    std::string dump;
+                    mapper.dump(dump);
+                },
+                [&]() -> void {
+                    InputDeviceInfo info;
+                    mapper.populateDeviceInfo(&info);
+                },
+                [&]() -> void { mapper.getSources(); },
+                [&]() -> void {
+                    mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+                                     fdp->ConsumeIntegral<uint32_t>());
+                },
+                [&]() -> void { mapper.reset(fdp->ConsumeIntegral<nsecs_t>()); },
+                [&]() -> void {
+                    int32_t type = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidTypes)
+                                                      : fdp->ConsumeIntegral<int32_t>();
+                    int32_t code = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidCodes)
+                                                      : fdp->ConsumeIntegral<int32_t>();
+                    RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+                                      fdp->ConsumeIntegral<nsecs_t>(),
+                                      fdp->ConsumeIntegral<int32_t>(),
+                                      type,
+                                      code,
+                                      fdp->ConsumeIntegral<int32_t>()};
+                    mapper.process(&rawEvent);
+                },
+                [&]() -> void {
+                    mapper.getKeyCodeState(fdp->ConsumeIntegral<uint32_t>(),
+                                           fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    mapper.getScanCodeState(fdp->ConsumeIntegral<uint32_t>(),
+                                            fdp->ConsumeIntegral<int32_t>());
+                },
+                [&]() -> void {
+                    std::vector<int32_t> keyCodes;
+                    int32_t numBytes = fdp->ConsumeIntegralInRange<int32_t>(0, kMaxKeycodes);
+                    for (int32_t i = 0; i < numBytes; ++i) {
+                        keyCodes.push_back(fdp->ConsumeIntegral<int32_t>());
+                    }
+                    mapper.markSupportedKeyCodes(fdp->ConsumeIntegral<uint32_t>(), keyCodes,
+                                                 nullptr);
+                },
+                [&]() -> void {
+                    mapper.cancelTouch(fdp->ConsumeIntegral<nsecs_t>(),
+                                       fdp->ConsumeIntegral<nsecs_t>());
+                },
+                [&]() -> void { mapper.timeoutExpired(fdp->ConsumeIntegral<nsecs_t>()); },
+                [&]() -> void {
+                    StylusState state{fdp->ConsumeIntegral<nsecs_t>(),
+                                      fdp->ConsumeFloatingPoint<float>(),
+                                      fdp->ConsumeIntegral<uint32_t>(),
+                                      fdp->ConsumeIntegral<int32_t>()};
+                    mapper.updateExternalStylusState(state);
+                },
+                [&]() -> void { mapper.getAssociatedDisplayId(); },
+        })();
+    }
+
+    return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/SwitchInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/SwitchInputFuzzer.cpp
new file mode 100644
index 0000000..e76bd72
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/SwitchInputFuzzer.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#include <FuzzContainer.h>
+#include <SwitchInputMapper.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+    std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+    FuzzContainer fuzzer(fdp);
+
+    SwitchInputMapper& mapper = fuzzer.getMapper<SwitchInputMapper>();
+    auto policyConfig = fuzzer.getPolicyConfig();
+
+    // Loop through mapper operations until randomness is exhausted.
+    while (fdp->remaining_bytes() > 0) {
+        fdp->PickValueInArray<std::function<void()>>({
+                [&]() -> void {
+                    std::string dump;
+                    mapper.dump(dump);
+                },
+                [&]() -> void { mapper.getSources(); },
+                [&]() -> void {
+                    int32_t type = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidTypes)
+                                                      : fdp->ConsumeIntegral<int32_t>();
+                    int32_t code = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidCodes)
+                                                      : fdp->ConsumeIntegral<int32_t>();
+                    RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+                                      fdp->ConsumeIntegral<nsecs_t>(),
+                                      fdp->ConsumeIntegral<int32_t>(),
+                                      type,
+                                      code,
+                                      fdp->ConsumeIntegral<int32_t>()};
+                    mapper.process(&rawEvent);
+                },
+                [&]() -> void {
+                    mapper.getSwitchState(fdp->ConsumeIntegral<uint32_t>(),
+                                          fdp->ConsumeIntegral<int32_t>());
+                },
+        })();
+    }
+
+    return 0;
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/LayerTransaction_test.cpp b/services/surfaceflinger/tests/LayerTransaction_test.cpp
index 513fdc3..c206e1f 100644
--- a/services/surfaceflinger/tests/LayerTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTransaction_test.cpp
@@ -154,6 +154,36 @@
 
     ASSERT_EQ(OK, producer->disconnect(NATIVE_WINDOW_API_CPU));
 }
+
+// b/245052266 - we possible could support blur and a buffer at the same layer but
+// might break existing assumptions at higher level. This test captures the current
+// expectations. A layer drawing a buffer will not support blur.
+TEST_F(LayerTransactionTest, BufferTakesPriorityOverBlur) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
+    ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+    Transaction().setBackgroundBlurRadius(layer, 5).apply();
+    {
+        SCOPED_TRACE("BufferTakesPriorityOverBlur");
+        const Rect rect(0, 0, 32, 32);
+        auto shot = screenshot();
+        shot->expectColor(rect, Color::RED);
+    }
+}
+
+TEST_F(LayerTransactionTest, BufferTakesPriorityOverColor) {
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
+    ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+    Transaction().setColor(layer, {Color::GREEN.r, Color::GREEN.g, Color::GREEN.b}).apply();
+    {
+        SCOPED_TRACE("BufferTakesPriorityOverColor");
+        const Rect rect(0, 0, 32, 32);
+        auto shot = screenshot();
+        shot->expectColor(rect, Color::RED);
+    }
+}
+
 } // namespace android
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues