Refactor use of services in InputMappers.

Create InputDeviceContext class to hide direct EventHub and
InputDevice accesses from InputMappers.

Test: atest inputflinger_tests libinput_tests
Change-Id: I05f9c808fc1a6f4c9207bd29fde50b76ec5655bb
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 1c08ab1..ae82cd4 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -43,12 +43,14 @@
         mSources(0),
         mIsExternal(false),
         mHasMic(false),
-        mDropUntilNextSync(false) {}
+        mDropUntilNextSync(false) {
+    mDeviceContext = std::make_unique<InputDeviceContext>(*this);
+}
 
 InputDevice::~InputDevice() {}
 
 bool InputDevice::isEnabled() {
-    return getEventHub()->isDeviceEnabled(mId);
+    return mDeviceContext->isDeviceEnabled();
 }
 
 void InputDevice::setEnabled(bool enabled, nsecs_t when) {
@@ -64,11 +66,11 @@
     }
 
     if (enabled) {
-        getEventHub()->enableDevice(mId);
+        mDeviceContext->enableDevice();
         reset(when);
     } else {
         reset(when);
-        getEventHub()->disableDevice(mId);
+        mDeviceContext->disableDevice();
     }
     // Must change generation to flag this device as changed
     bumpGeneration();
@@ -119,6 +121,7 @@
 void InputDevice::populateMappers() {
     uint32_t classes = mClasses;
     std::vector<std::unique_ptr<InputMapper>>& mappers = mMappers;
+    std::unique_ptr<InputDeviceContext>& contextPtr = mDeviceContext;
 
     // External devices.
     if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
@@ -132,17 +135,17 @@
 
     // Switch-like devices.
     if (classes & INPUT_DEVICE_CLASS_SWITCH) {
-        mappers.push_back(std::make_unique<SwitchInputMapper>(this));
+        mappers.push_back(std::make_unique<SwitchInputMapper>(*contextPtr));
     }
 
     // Scroll wheel-like devices.
     if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
-        mappers.push_back(std::make_unique<RotaryEncoderInputMapper>(this));
+        mappers.push_back(std::make_unique<RotaryEncoderInputMapper>(*contextPtr));
     }
 
     // Vibrator-like devices.
     if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
-        mappers.push_back(std::make_unique<VibratorInputMapper>(this));
+        mappers.push_back(std::make_unique<VibratorInputMapper>(*contextPtr));
     }
 
     // Keyboard-like devices.
@@ -163,29 +166,29 @@
 
     if (keyboardSource != 0) {
         mappers.push_back(
-                std::make_unique<KeyboardInputMapper>(this, keyboardSource, keyboardType));
+                std::make_unique<KeyboardInputMapper>(*contextPtr, keyboardSource, keyboardType));
     }
 
     // Cursor-like devices.
     if (classes & INPUT_DEVICE_CLASS_CURSOR) {
-        mappers.push_back(std::make_unique<CursorInputMapper>(this));
+        mappers.push_back(std::make_unique<CursorInputMapper>(*contextPtr));
     }
 
     // Touchscreens and touchpad devices.
     if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
-        mappers.push_back(std::make_unique<MultiTouchInputMapper>(this));
+        mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
     } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
-        mappers.push_back(std::make_unique<SingleTouchInputMapper>(this));
+        mappers.push_back(std::make_unique<SingleTouchInputMapper>(*contextPtr));
     }
 
     // Joystick-like devices.
     if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
-        mappers.push_back(std::make_unique<JoystickInputMapper>(this));
+        mappers.push_back(std::make_unique<JoystickInputMapper>(*contextPtr));
     }
 
     // External stylus-like devices.
     if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
-        mappers.push_back(std::make_unique<ExternalStylusInputMapper>(this));
+        mappers.push_back(std::make_unique<ExternalStylusInputMapper>(*contextPtr));
     }
 }
 
@@ -195,14 +198,14 @@
 
     if (!isIgnored()) {
         if (!changes) { // first time only
-            mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
+            mDeviceContext->getConfiguration(&mConfiguration);
         }
 
         if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
             if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
                 sp<KeyCharacterMap> keyboardLayout =
                         mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
-                if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
+                if (mDeviceContext->setKeyboardLayoutOverlay(keyboardLayout)) {
                     bumpGeneration();
                 }
             }
@@ -421,4 +424,12 @@
             [](InputMapper& mapper) { return mapper.getAssociatedDisplayId(); });
 }
 
+InputDeviceContext::InputDeviceContext(InputDevice& device)
+      : mDevice(device),
+        mContext(device.getContext()),
+        mEventHub(device.getContext()->getEventHub()),
+        mId(device.getId()) {}
+
+InputDeviceContext::~InputDeviceContext() {}
+
 } // namespace android
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 010729a..3e23fa6 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -348,13 +348,11 @@
     mDisableVirtualKeysTimeout = time;
 }
 
-bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, InputDevice* device, int32_t keyCode,
-                                             int32_t scanCode) {
+bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32_t scanCode) {
     if (now < mDisableVirtualKeysTimeout) {
-        ALOGI("Dropping virtual key from device %s because virtual keys are "
+        ALOGI("Dropping virtual key from device because virtual keys are "
               "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
-              device->getName().c_str(), (mDisableVirtualKeysTimeout - now) * 0.000001, keyCode,
-              scanCode);
+              (mDisableVirtualKeysTimeout - now) * 0.000001, keyCode, scanCode);
         return true;
     } else {
         return false;
@@ -662,10 +660,10 @@
     mReader->disableVirtualKeysUntilLocked(time);
 }
 
-bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now, InputDevice* device,
-                                                    int32_t keyCode, int32_t scanCode) {
+bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now, int32_t keyCode,
+                                                    int32_t scanCode) {
     // lock is already held by the input loop
-    return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
+    return mReader->shouldDropVirtualKeyLocked(now, keyCode, scanCode);
 }
 
 void InputReader::ContextImpl::fadePointer() {
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index d06cc20..0814d1f 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -31,6 +31,7 @@
 
 namespace android {
 
+class InputDeviceContext;
 class InputMapper;
 
 /* Represents the state of a single input device. */
@@ -96,30 +97,12 @@
     inline const PropertyMap& getConfiguration() { return mConfiguration; }
     inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
 
-    bool hasKey(int32_t code) { return getEventHub()->hasScanCode(mId, code); }
-
-    bool hasAbsoluteAxis(int32_t code) {
-        RawAbsoluteAxisInfo info;
-        getEventHub()->getAbsoluteAxisInfo(mId, code, &info);
-        return info.valid;
-    }
-
-    bool isKeyPressed(int32_t code) {
-        return getEventHub()->getScanCodeState(mId, code) == AKEY_STATE_DOWN;
-    }
-
-    int32_t getAbsoluteAxisValue(int32_t code) {
-        int32_t value;
-        getEventHub()->getAbsoluteAxisValue(mId, code, &value);
-        return value;
-    }
-
     std::optional<int32_t> getAssociatedDisplayId();
 
     // construct and add a mapper to the input device
     template <class T, typename... Args>
     T& addMapper(Args... args) {
-        T* mapper = new T(this, args...);
+        T* mapper = new T(*mDeviceContext, args...);
         mMappers.emplace_back(mapper);
         return *mapper;
     }
@@ -133,6 +116,7 @@
     std::string mAlias;
     uint32_t mClasses;
 
+    std::unique_ptr<InputDeviceContext> mDeviceContext;
     std::vector<std::unique_ptr<InputMapper>> mMappers;
 
     uint32_t mSources;
@@ -168,6 +152,115 @@
     }
 };
 
+/* Provides access to EventHub methods, but limits access to the current InputDevice.
+ * Essentially an implementation of EventHubInterface, but for a specific device id.
+ * Helps hide implementation details of InputDevice and EventHub. Used by mappers to
+ * check the status of the associated hardware device
+ */
+class InputDeviceContext {
+public:
+    InputDeviceContext(InputDevice& device);
+    ~InputDeviceContext();
+
+    inline InputReaderContext* getContext() { return mContext; }
+    inline int32_t getId() { return mId; }
+
+    inline uint32_t getDeviceClasses() const { return mEventHub->getDeviceClasses(mId); }
+    inline InputDeviceIdentifier getDeviceIdentifier() const {
+        return mEventHub->getDeviceIdentifier(mId);
+    }
+    inline int32_t getDeviceControllerNumber() const {
+        return mEventHub->getDeviceControllerNumber(mId);
+    }
+    inline void getConfiguration(PropertyMap* outConfiguration) const {
+        return mEventHub->getConfiguration(mId, outConfiguration);
+    }
+    inline status_t getAbsoluteAxisInfo(int32_t code, RawAbsoluteAxisInfo* axisInfo) const {
+        return mEventHub->getAbsoluteAxisInfo(mId, code, axisInfo);
+    }
+    inline bool hasRelativeAxis(int32_t code) const {
+        return mEventHub->hasRelativeAxis(mId, code);
+    }
+    inline bool hasInputProperty(int property) const {
+        return mEventHub->hasInputProperty(mId, property);
+    }
+    inline status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t metaState,
+                           int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const {
+        return mEventHub->mapKey(mId, scanCode, usageCode, metaState, outKeycode, outMetaState,
+                                 outFlags);
+    }
+    inline status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
+        return mEventHub->mapAxis(mId, scanCode, outAxisInfo);
+    }
+    inline std::vector<TouchVideoFrame> getVideoFrames() { return mEventHub->getVideoFrames(mId); }
+    inline int32_t getScanCodeState(int32_t scanCode) const {
+        return mEventHub->getScanCodeState(mId, scanCode);
+    }
+    inline int32_t getKeyCodeState(int32_t keyCode) const {
+        return mEventHub->getKeyCodeState(mId, keyCode);
+    }
+    inline int32_t getSwitchState(int32_t sw) const { return mEventHub->getSwitchState(mId, sw); }
+    inline status_t getAbsoluteAxisValue(int32_t code, int32_t* outValue) const {
+        return mEventHub->getAbsoluteAxisValue(mId, code, outValue);
+    }
+    inline bool markSupportedKeyCodes(size_t numCodes, const int32_t* keyCodes,
+                                      uint8_t* outFlags) const {
+        return mEventHub->markSupportedKeyCodes(mId, numCodes, keyCodes, outFlags);
+    }
+    inline bool hasScanCode(int32_t scanCode) const {
+        return mEventHub->hasScanCode(mId, scanCode);
+    }
+    inline bool hasLed(int32_t led) const { return mEventHub->hasLed(mId, led); }
+    inline void setLedState(int32_t led, bool on) { return mEventHub->setLedState(mId, led, on); }
+    inline void getVirtualKeyDefinitions(std::vector<VirtualKeyDefinition>& outVirtualKeys) const {
+        return mEventHub->getVirtualKeyDefinitions(mId, outVirtualKeys);
+    }
+    inline sp<KeyCharacterMap> getKeyCharacterMap() const {
+        return mEventHub->getKeyCharacterMap(mId);
+    }
+    inline bool setKeyboardLayoutOverlay(const sp<KeyCharacterMap>& map) {
+        return mEventHub->setKeyboardLayoutOverlay(mId, map);
+    }
+    inline void vibrate(nsecs_t duration) { return mEventHub->vibrate(mId, duration); }
+    inline void cancelVibrate() { return mEventHub->cancelVibrate(mId); }
+
+    inline bool hasAbsoluteAxis(int32_t code) const {
+        RawAbsoluteAxisInfo info;
+        mEventHub->getAbsoluteAxisInfo(mId, code, &info);
+        return info.valid;
+    }
+    inline bool isKeyPressed(int32_t code) const {
+        return mEventHub->getScanCodeState(mId, code) == AKEY_STATE_DOWN;
+    }
+    inline int32_t getAbsoluteAxisValue(int32_t code) const {
+        int32_t value;
+        mEventHub->getAbsoluteAxisValue(mId, code, &value);
+        return value;
+    }
+    inline bool isDeviceEnabled() { return mEventHub->isDeviceEnabled(mId); }
+    inline status_t enableDevice() { return mEventHub->enableDevice(mId); }
+    inline status_t disableDevice() { return mEventHub->disableDevice(mId); }
+
+    inline const std::string getName() { return mDevice.getName(); }
+    inline const std::string getDescriptor() { return mDevice.getDescriptor(); }
+    inline bool isExternal() { return mDevice.isExternal(); }
+    inline std::optional<uint8_t> getAssociatedDisplayPort() const {
+        return mDevice.getAssociatedDisplayPort();
+    }
+    inline std::optional<DisplayViewport> getAssociatedViewport() const {
+        return mDevice.getAssociatedViewport();
+    }
+    inline void cancelTouch(nsecs_t when) { mDevice.cancelTouch(when); }
+    inline void bumpGeneration() { mDevice.bumpGeneration(); }
+    inline const PropertyMap& getConfiguration() { return mDevice.getConfiguration(); }
+
+private:
+    InputDevice& mDevice;
+    InputReaderContext* mContext;
+    EventHubInterface* mEventHub;
+    int32_t mId;
+};
+
 } // namespace android
 
 #endif //_UI_INPUTREADER_INPUT_DEVICE_H
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index 02957cd..cf1af04 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -101,8 +101,7 @@
         virtual void updateGlobalMetaState() override;
         virtual int32_t getGlobalMetaState() override;
         virtual void disableVirtualKeysUntil(nsecs_t time) override;
-        virtual bool shouldDropVirtualKey(nsecs_t now, InputDevice* device, int32_t keyCode,
-                                          int32_t scanCode) override;
+        virtual bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) override;
         virtual void fadePointer() override;
         virtual void requestTimeoutAtTime(nsecs_t when) override;
         virtual int32_t bumpGeneration() override;
@@ -168,8 +167,7 @@
 
     nsecs_t mDisableVirtualKeysTimeout;
     void disableVirtualKeysUntilLocked(nsecs_t time);
-    bool shouldDropVirtualKeyLocked(nsecs_t now, InputDevice* device, int32_t keyCode,
-                                    int32_t scanCode);
+    bool shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32_t scanCode);
 
     nsecs_t mNextTimeout;
     void requestTimeoutAtTimeLocked(nsecs_t when);
diff --git a/services/inputflinger/reader/include/InputReaderContext.h b/services/inputflinger/reader/include/InputReaderContext.h
index 3472346..e14fbbe 100644
--- a/services/inputflinger/reader/include/InputReaderContext.h
+++ b/services/inputflinger/reader/include/InputReaderContext.h
@@ -42,8 +42,7 @@
     virtual int32_t getGlobalMetaState() = 0;
 
     virtual void disableVirtualKeysUntil(nsecs_t time) = 0;
-    virtual bool shouldDropVirtualKey(nsecs_t now, InputDevice* device, int32_t keyCode,
-                                      int32_t scanCode) = 0;
+    virtual bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) = 0;
 
     virtual void fadePointer() = 0;
 
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index 69a75ba..78f3382 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -30,7 +30,7 @@
     clearRelativeAxes();
 }
 
-void CursorMotionAccumulator::reset(InputDevice* device) {
+void CursorMotionAccumulator::reset(InputDeviceContext& deviceContext) {
     clearRelativeAxes();
 }
 
@@ -58,7 +58,8 @@
 
 // --- CursorInputMapper ---
 
-CursorInputMapper::CursorInputMapper(InputDevice* device) : InputMapper(device) {}
+CursorInputMapper::CursorInputMapper(InputDeviceContext& deviceContext)
+      : InputMapper(deviceContext) {}
 
 CursorInputMapper::~CursorInputMapper() {}
 
@@ -113,7 +114,7 @@
     InputMapper::configure(when, config, changes);
 
     if (!changes) { // first time only
-        mCursorScrollAccumulator.configure(getDevice());
+        mCursorScrollAccumulator.configure(getDeviceContext());
 
         // Configure basic parameters.
         configureParameters();
@@ -167,7 +168,8 @@
         }
         bumpGeneration();
         if (changes) {
-            getDevice()->notifyReset(when);
+            NotifyDeviceResetArgs args(getContext()->getNextSequenceNum(), when, getDeviceId());
+            getListener()->notifyDeviceReset(&args);
         }
     }
 
@@ -218,7 +220,8 @@
 void CursorInputMapper::configureParameters() {
     mParameters.mode = Parameters::MODE_POINTER;
     String8 cursorModeString;
-    if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
+    if (getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.mode"),
+                                                             cursorModeString)) {
         if (cursorModeString == "navigation") {
             mParameters.mode = Parameters::MODE_NAVIGATION;
         } else if (cursorModeString != "pointer" && cursorModeString != "default") {
@@ -227,8 +230,8 @@
     }
 
     mParameters.orientationAware = false;
-    getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
-                                                   mParameters.orientationAware);
+    getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
+                                                         mParameters.orientationAware);
 
     mParameters.hasAssociatedDisplay = false;
     if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
@@ -266,9 +269,9 @@
     mWheelXVelocityControl.reset();
     mWheelYVelocityControl.reset();
 
-    mCursorButtonAccumulator.reset(getDevice());
-    mCursorMotionAccumulator.reset(getDevice());
-    mCursorScrollAccumulator.reset(getDevice());
+    mCursorButtonAccumulator.reset(getDeviceContext());
+    mCursorMotionAccumulator.reset(getDeviceContext());
+    mCursorScrollAccumulator.reset(getDeviceContext());
 
     InputMapper::reset(when);
 }
@@ -369,7 +372,7 @@
     // the device in your pocket.
     // TODO: Use the input device configuration to control this behavior more finely.
     uint32_t policyFlags = 0;
-    if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
+    if ((buttonsPressed || moved || scrolled) && getDeviceContext().isExternal()) {
         policyFlags |= POLICY_FLAG_WAKE;
     }
 
@@ -379,7 +382,7 @@
 
     // Send motion event.
     if (downChanged || moved || scrolled || buttonsChanged) {
-        int32_t metaState = mContext->getGlobalMetaState();
+        int32_t metaState = getContext()->getGlobalMetaState();
         int32_t buttonState = lastButtonState;
         int32_t motionEventAction;
         if (downChanged) {
@@ -395,8 +398,8 @@
             while (!released.isEmpty()) {
                 int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());
                 buttonState &= ~actionButton;
-                NotifyMotionArgs releaseArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
-                                             mSource, displayId, policyFlags,
+                NotifyMotionArgs releaseArgs(getContext()->getNextSequenceNum(), when,
+                                             getDeviceId(), mSource, displayId, policyFlags,
                                              AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
                                              metaState, buttonState, MotionClassification::NONE,
                                              AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
@@ -407,7 +410,7 @@
             }
         }
 
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+        NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
                               displayId, policyFlags, motionEventAction, 0, 0, metaState,
                               currentButtonState, MotionClassification::NONE,
                               AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties, &pointerCoords,
@@ -420,7 +423,7 @@
             while (!pressed.isEmpty()) {
                 int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());
                 buttonState |= actionButton;
-                NotifyMotionArgs pressArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
+                NotifyMotionArgs pressArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
                                            mSource, displayId, policyFlags,
                                            AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
                                            metaState, buttonState, MotionClassification::NONE,
@@ -436,9 +439,10 @@
 
         // Send hover move after UP to tell the application that the mouse is hovering now.
         if (motionEventAction == AMOTION_EVENT_ACTION_UP && (mSource == AINPUT_SOURCE_MOUSE)) {
-            NotifyMotionArgs hoverArgs(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
-                                       displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
-                                       0, metaState, currentButtonState, MotionClassification::NONE,
+            NotifyMotionArgs hoverArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
+                                       mSource, displayId, policyFlags,
+                                       AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
+                                       currentButtonState, MotionClassification::NONE,
                                        AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
                                        &pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
                                        yCursorPosition, downTime, /* videoFrames */ {});
@@ -450,7 +454,7 @@
             pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
             pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
 
-            NotifyMotionArgs scrollArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
+            NotifyMotionArgs scrollArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
                                         mSource, displayId, policyFlags,
                                         AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState,
                                         currentButtonState, MotionClassification::NONE,
@@ -471,7 +475,7 @@
 
 int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
     if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
-        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
+        return getDeviceContext().getScanCodeState(scanCode);
     } else {
         return AKEY_STATE_UNKNOWN;
     }
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h
index d56f9be..94ab306 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.h
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.h
@@ -36,7 +36,7 @@
 class CursorMotionAccumulator {
 public:
     CursorMotionAccumulator();
-    void reset(InputDevice* device);
+    void reset(InputDeviceContext& deviceContext);
 
     void process(const RawEvent* rawEvent);
     void finishSync();
@@ -53,7 +53,7 @@
 
 class CursorInputMapper : public InputMapper {
 public:
-    explicit CursorInputMapper(InputDevice* device);
+    explicit CursorInputMapper(InputDeviceContext& deviceContext);
     virtual ~CursorInputMapper();
 
     virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
index 9aa0770..37e4047 100644
--- a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.cpp
@@ -23,7 +23,8 @@
 
 namespace android {
 
-ExternalStylusInputMapper::ExternalStylusInputMapper(InputDevice* device) : InputMapper(device) {}
+ExternalStylusInputMapper::ExternalStylusInputMapper(InputDeviceContext& deviceContext)
+      : InputMapper(deviceContext) {}
 
 uint32_t ExternalStylusInputMapper::getSources() {
     return AINPUT_SOURCE_STYLUS;
@@ -46,13 +47,12 @@
 void ExternalStylusInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config,
                                           uint32_t changes) {
     getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPressureAxis);
-    mTouchButtonAccumulator.configure(getDevice());
+    mTouchButtonAccumulator.configure(getDeviceContext());
 }
 
 void ExternalStylusInputMapper::reset(nsecs_t when) {
-    InputDevice* device = getDevice();
-    mSingleTouchMotionAccumulator.reset(device);
-    mTouchButtonAccumulator.reset(device);
+    mSingleTouchMotionAccumulator.reset(getDeviceContext());
+    mTouchButtonAccumulator.reset(getDeviceContext());
     InputMapper::reset(when);
 }
 
@@ -86,7 +86,7 @@
 
     mStylusState.buttons = mTouchButtonAccumulator.getButtonState();
 
-    mContext->dispatchExternalStylusState(mStylusState);
+    getContext()->dispatchExternalStylusState(mStylusState);
 }
 
 } // namespace android
diff --git a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
index 34f339a..1d42b30 100644
--- a/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
+++ b/services/inputflinger/reader/mapper/ExternalStylusInputMapper.h
@@ -27,7 +27,7 @@
 
 class ExternalStylusInputMapper : public InputMapper {
 public:
-    explicit ExternalStylusInputMapper(InputDevice* device);
+    explicit ExternalStylusInputMapper(InputDeviceContext& deviceContext);
     virtual ~ExternalStylusInputMapper() = default;
 
     virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/InputMapper.cpp b/services/inputflinger/reader/mapper/InputMapper.cpp
index d941528..92af612 100644
--- a/services/inputflinger/reader/mapper/InputMapper.cpp
+++ b/services/inputflinger/reader/mapper/InputMapper.cpp
@@ -22,7 +22,7 @@
 
 namespace android {
 
-InputMapper::InputMapper(InputDevice* device) : mDevice(device), mContext(device->getContext()) {}
+InputMapper::InputMapper(InputDeviceContext& deviceContext) : mDeviceContext(deviceContext) {}
 
 InputMapper::~InputMapper() {}
 
@@ -74,11 +74,11 @@
 void InputMapper::fadePointer() {}
 
 status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
-    return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
+    return getDeviceContext().getAbsoluteAxisInfo(axis, axisInfo);
 }
 
 void InputMapper::bumpGeneration() {
-    mDevice->bumpGeneration();
+    getDeviceContext().bumpGeneration();
 }
 
 void InputMapper::dumpRawAbsoluteAxisInfo(std::string& dump, const RawAbsoluteAxisInfo& axis,
diff --git a/services/inputflinger/reader/mapper/InputMapper.h b/services/inputflinger/reader/mapper/InputMapper.h
index a559ef8..09888bf 100644
--- a/services/inputflinger/reader/mapper/InputMapper.h
+++ b/services/inputflinger/reader/mapper/InputMapper.h
@@ -39,16 +39,15 @@
  */
 class InputMapper {
 public:
-    explicit InputMapper(InputDevice* device);
+    explicit InputMapper(InputDeviceContext& deviceContext);
     virtual ~InputMapper();
 
-    inline InputDevice* getDevice() { return mDevice; }
-    inline int32_t getDeviceId() { return mDevice->getId(); }
-    inline const std::string getDeviceName() { return mDevice->getName(); }
-    inline InputReaderContext* getContext() { return mContext; }
-    inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
-    inline InputListenerInterface* getListener() { return mContext->getListener(); }
-    inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
+    inline int32_t getDeviceId() { return mDeviceContext.getId(); }
+    inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
+    inline const std::string getDeviceName() { return mDeviceContext.getName(); }
+    inline InputReaderContext* getContext() { return mDeviceContext.getContext(); }
+    inline InputReaderPolicyInterface* getPolicy() { return getContext()->getPolicy(); }
+    inline InputListenerInterface* getListener() { return getContext()->getListener(); }
 
     virtual uint32_t getSources() = 0;
     virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
@@ -76,8 +75,7 @@
     virtual std::optional<int32_t> getAssociatedDisplayId() { return std::nullopt; }
 
 protected:
-    InputDevice* mDevice;
-    InputReaderContext* mContext;
+    InputDeviceContext& mDeviceContext;
 
     status_t getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo);
     void bumpGeneration();
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
index 50adf73..57c85b6 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.cpp
@@ -20,7 +20,8 @@
 
 namespace android {
 
-JoystickInputMapper::JoystickInputMapper(InputDevice* device) : InputMapper(device) {}
+JoystickInputMapper::JoystickInputMapper(InputDeviceContext& deviceContext)
+      : InputMapper(deviceContext) {}
 
 JoystickInputMapper::~JoystickInputMapper() {}
 
@@ -112,7 +113,8 @@
     if (!changes) { // first time only
         // Collect all axes.
         for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
-            if (!(getAbsAxisUsage(abs, getDevice()->getClasses()) & INPUT_DEVICE_CLASS_JOYSTICK)) {
+            if (!(getAbsAxisUsage(abs, getDeviceContext().getDeviceClasses()) &
+                  INPUT_DEVICE_CLASS_JOYSTICK)) {
                 continue; // axis must be claimed by a different device
             }
 
@@ -121,7 +123,7 @@
             if (rawAxisInfo.valid) {
                 // Map axis.
                 AxisInfo axisInfo;
-                bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
+                bool explicitlyMapped = !getDeviceContext().mapAxis(abs, &axisInfo);
                 if (!explicitlyMapped) {
                     // Axis is not explicitly mapped, will choose a generic axis later.
                     axisInfo.mode = AxisInfo::MODE_NORMAL;
@@ -304,7 +306,7 @@
         return;
     }
 
-    int32_t metaState = mContext->getGlobalMetaState();
+    int32_t metaState = getContext()->getGlobalMetaState();
     int32_t buttonState = 0;
 
     PointerProperties pointerProperties;
@@ -331,7 +333,7 @@
     // TODO: Use the input device configuration to control this behavior more finely.
     uint32_t policyFlags = 0;
 
-    NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
+    NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(),
                           AINPUT_SOURCE_JOYSTICK, ADISPLAY_ID_NONE, policyFlags,
                           AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState,
                           MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1,
diff --git a/services/inputflinger/reader/mapper/JoystickInputMapper.h b/services/inputflinger/reader/mapper/JoystickInputMapper.h
index b46d27d..823a096 100644
--- a/services/inputflinger/reader/mapper/JoystickInputMapper.h
+++ b/services/inputflinger/reader/mapper/JoystickInputMapper.h
@@ -23,7 +23,7 @@
 
 class JoystickInputMapper : public InputMapper {
 public:
-    explicit JoystickInputMapper(InputDevice* device);
+    explicit JoystickInputMapper(InputDeviceContext& deviceContext);
     virtual ~JoystickInputMapper();
 
     virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index 348a7ad..9ab707f 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -87,8 +87,9 @@
 
 // --- KeyboardInputMapper ---
 
-KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, uint32_t source, int32_t keyboardType)
-      : InputMapper(device), mSource(source), mKeyboardType(keyboardType) {}
+KeyboardInputMapper::KeyboardInputMapper(InputDeviceContext& deviceContext, uint32_t source,
+                                         int32_t keyboardType)
+      : InputMapper(deviceContext), mSource(source), mKeyboardType(keyboardType) {}
 
 KeyboardInputMapper::~KeyboardInputMapper() {}
 
@@ -114,7 +115,7 @@
     InputMapper::populateDeviceInfo(info);
 
     info->setKeyboardType(mKeyboardType);
-    info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
+    info->setKeyCharacterMap(getDeviceContext().getKeyCharacterMap());
 }
 
 void KeyboardInputMapper::dump(std::string& dump) {
@@ -129,10 +130,10 @@
 
 std::optional<DisplayViewport> KeyboardInputMapper::findViewport(
         nsecs_t when, const InputReaderConfiguration* config) {
-    const std::optional<uint8_t> displayPort = mDevice->getAssociatedDisplayPort();
+    const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
     if (displayPort) {
         // Find the viewport that contains the same port
-        return mDevice->getAssociatedViewport();
+        return getDeviceContext().getAssociatedViewport();
     }
 
     // No associated display defined, try to find default display if orientationAware.
@@ -171,7 +172,7 @@
 
 void KeyboardInputMapper::configureParameters() {
     mParameters.orientationAware = false;
-    const PropertyMap& config = getDevice()->getConfiguration();
+    const PropertyMap& config = getDeviceContext().getConfiguration();
     config.tryGetProperty(String8("keyboard.orientationAware"), mParameters.orientationAware);
 
     if (mParameters.orientationAware) {
@@ -271,8 +272,8 @@
     int32_t keyMetaState;
     uint32_t policyFlags;
 
-    if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, mMetaState, &keyCode,
-                              &keyMetaState, &policyFlags)) {
+    if (getDeviceContext().mapKey(scanCode, usageCode, mMetaState, &keyCode, &keyMetaState,
+                                  &policyFlags)) {
         keyCode = AKEYCODE_UNKNOWN;
         keyMetaState = mMetaState;
         policyFlags = 0;
@@ -292,11 +293,11 @@
         } else {
             // key down
             if ((policyFlags & POLICY_FLAG_VIRTUAL) &&
-                mContext->shouldDropVirtualKey(when, getDevice(), keyCode, scanCode)) {
+                getContext()->shouldDropVirtualKey(when, keyCode, scanCode)) {
                 return;
             }
             if (policyFlags & POLICY_FLAG_GESTURE) {
-                mDevice->cancelTouch(when);
+                getDeviceContext().cancelTouch(when);
             }
 
             KeyDown keyDown;
@@ -338,7 +339,7 @@
     // prevented (e.g. TV remotes), the key layout file should specify the policy flags for each
     // wake key individually.
     // TODO: Use the input device configuration to control this behavior more finely.
-    if (down && getDevice()->isExternal() && !mParameters.doNotWakeByDefault &&
+    if (down && getDeviceContext().isExternal() && !mParameters.doNotWakeByDefault &&
         !isMediaKey(keyCode)) {
         policyFlags |= POLICY_FLAG_WAKE;
     }
@@ -347,8 +348,9 @@
         policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
     }
 
-    NotifyKeyArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource, getDisplayId(),
-                       policyFlags, down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
+    NotifyKeyArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
+                       getDisplayId(), policyFlags,
+                       down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
                        AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);
     getListener()->notifyKey(&args);
 }
@@ -364,16 +366,16 @@
 }
 
 int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-    return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
+    return getDeviceContext().getKeyCodeState(keyCode);
 }
 
 int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
+    return getDeviceContext().getScanCodeState(scanCode);
 }
 
 bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
                                                 const int32_t* keyCodes, uint8_t* outFlags) {
-    return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
+    return getDeviceContext().markSupportedKeyCodes(numCodes, keyCodes, outFlags);
 }
 
 int32_t KeyboardInputMapper::getMetaState() {
@@ -407,7 +409,7 @@
 }
 
 void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
-    ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
+    ledState.avail = getDeviceContext().hasLed(led);
     ledState.on = false;
 }
 
@@ -422,7 +424,7 @@
     if (ledState.avail) {
         bool desiredState = (mMetaState & modifier) != 0;
         if (reset || ledState.on != desiredState) {
-            getEventHub()->setLedState(getDeviceId(), led, desiredState);
+            getDeviceContext().setLedState(led, desiredState);
             ledState.on = desiredState;
         }
     }
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.h b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
index badbcb2..0bdeded 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.h
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
@@ -23,7 +23,7 @@
 
 class KeyboardInputMapper : public InputMapper {
 public:
-    KeyboardInputMapper(InputDevice* device, uint32_t source, int32_t keyboardType);
+    KeyboardInputMapper(InputDeviceContext& deviceContext, uint32_t source, int32_t keyboardType);
     virtual ~KeyboardInputMapper();
 
     virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
index f42ddcf..d195a07 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
@@ -38,17 +38,17 @@
     delete[] mSlots;
 }
 
-void MultiTouchMotionAccumulator::configure(InputDevice* device, size_t slotCount,
+void MultiTouchMotionAccumulator::configure(InputDeviceContext& deviceContext, size_t slotCount,
                                             bool usingSlotsProtocol) {
     mSlotCount = slotCount;
     mUsingSlotsProtocol = usingSlotsProtocol;
-    mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
+    mHaveStylus = deviceContext.hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
 
     delete[] mSlots;
     mSlots = new Slot[slotCount];
 }
 
-void MultiTouchMotionAccumulator::reset(InputDevice* device) {
+void MultiTouchMotionAccumulator::reset(InputDeviceContext& deviceContext) {
     // Unfortunately there is no way to read the initial contents of the slots.
     // So when we reset the accumulator, we must assume they are all zeroes.
     if (mUsingSlotsProtocol) {
@@ -62,8 +62,7 @@
         // This can cause the touch point to "jump", but at least there will be
         // no stuck touches.
         int32_t initialSlot;
-        status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(), ABS_MT_SLOT,
-                                                                      &initialSlot);
+        status_t status = deviceContext.getAbsoluteAxisValue(ABS_MT_SLOT, &initialSlot);
         if (status) {
             ALOGD("Could not retrieve current multitouch slot index.  status=%d", status);
             initialSlot = -1;
@@ -218,12 +217,13 @@
 
 // --- MultiTouchInputMapper ---
 
-MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) : TouchInputMapper(device) {}
+MultiTouchInputMapper::MultiTouchInputMapper(InputDeviceContext& deviceContext)
+      : TouchInputMapper(deviceContext) {}
 
 MultiTouchInputMapper::~MultiTouchInputMapper() {}
 
 void MultiTouchInputMapper::reset(nsecs_t when) {
-    mMultiTouchMotionAccumulator.reset(getDevice());
+    mMultiTouchMotionAccumulator.reset(getDeviceContext());
 
     mPointerIdBits.clear();
 
@@ -353,9 +353,10 @@
                   getDeviceName().c_str(), slotCount, MAX_SLOTS);
             slotCount = MAX_SLOTS;
         }
-        mMultiTouchMotionAccumulator.configure(getDevice(), slotCount, true /*usingSlotsProtocol*/);
+        mMultiTouchMotionAccumulator.configure(getDeviceContext(), slotCount,
+                                               true /*usingSlotsProtocol*/);
     } else {
-        mMultiTouchMotionAccumulator.configure(getDevice(), MAX_POINTERS,
+        mMultiTouchMotionAccumulator.configure(getDeviceContext(), MAX_POINTERS,
                                                false /*usingSlotsProtocol*/);
     }
 }
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.h b/services/inputflinger/reader/mapper/MultiTouchInputMapper.h
index a45c3cb..89ef41d 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.h
@@ -70,8 +70,8 @@
     MultiTouchMotionAccumulator();
     ~MultiTouchMotionAccumulator();
 
-    void configure(InputDevice* device, size_t slotCount, bool usingSlotsProtocol);
-    void reset(InputDevice* device);
+    void configure(InputDeviceContext& deviceContext, size_t slotCount, bool usingSlotsProtocol);
+    void reset(InputDeviceContext& deviceContext);
     void process(const RawEvent* rawEvent);
     void finishSync();
     bool hasStylus() const;
@@ -91,7 +91,7 @@
 
 class MultiTouchInputMapper : public TouchInputMapper {
 public:
-    explicit MultiTouchInputMapper(InputDevice* device);
+    explicit MultiTouchInputMapper(InputDeviceContext& deviceContext);
     virtual ~MultiTouchInputMapper();
 
     virtual void reset(nsecs_t when) override;
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
index e113cca..a1cce56 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
@@ -22,8 +22,8 @@
 
 namespace android {
 
-RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDevice* device)
-      : InputMapper(device), mOrientation(DISPLAY_ORIENTATION_0) {
+RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDeviceContext& deviceContext)
+      : InputMapper(deviceContext), mOrientation(DISPLAY_ORIENTATION_0) {
     mSource = AINPUT_SOURCE_ROTARY_ENCODER;
 }
 
@@ -38,11 +38,11 @@
 
     if (mRotaryEncoderScrollAccumulator.haveRelativeVWheel()) {
         float res = 0.0f;
-        if (!mDevice->getConfiguration().tryGetProperty(String8("device.res"), res)) {
+        if (!getDeviceContext().getConfiguration().tryGetProperty(String8("device.res"), res)) {
             ALOGW("Rotary Encoder device configuration file didn't specify resolution!\n");
         }
-        if (!mDevice->getConfiguration().tryGetProperty(String8("device.scalingFactor"),
-                                                        mScalingFactor)) {
+        if (!getDeviceContext().getConfiguration().tryGetProperty(String8("device.scalingFactor"),
+                                                                  mScalingFactor)) {
             ALOGW("Rotary Encoder device configuration file didn't specify scaling factor,"
                   "default to 1.0!\n");
             mScalingFactor = 1.0f;
@@ -62,7 +62,7 @@
                                          uint32_t changes) {
     InputMapper::configure(when, config, changes);
     if (!changes) {
-        mRotaryEncoderScrollAccumulator.configure(getDevice());
+        mRotaryEncoderScrollAccumulator.configure(getDeviceContext());
     }
     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
         std::optional<DisplayViewport> internalViewport =
@@ -76,7 +76,7 @@
 }
 
 void RotaryEncoderInputMapper::reset(nsecs_t when) {
-    mRotaryEncoderScrollAccumulator.reset(getDevice());
+    mRotaryEncoderScrollAccumulator.reset(getDeviceContext());
 
     InputMapper::reset(when);
 }
@@ -106,7 +106,7 @@
 
     // Moving the rotary encoder should wake the device (if specified).
     uint32_t policyFlags = 0;
-    if (scrolled && getDevice()->isExternal()) {
+    if (scrolled && getDeviceContext().isExternal()) {
         policyFlags |= POLICY_FLAG_WAKE;
     }
 
@@ -116,12 +116,12 @@
 
     // Send motion event.
     if (scrolled) {
-        int32_t metaState = mContext->getGlobalMetaState();
+        int32_t metaState = getContext()->getGlobalMetaState();
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_SCROLL, scroll * mScalingFactor);
 
-        NotifyMotionArgs scrollArgs(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
-                                    displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0,
-                                    metaState, /* buttonState */ 0, MotionClassification::NONE,
+        NotifyMotionArgs scrollArgs(getContext()->getNextSequenceNum(), when, getDeviceId(),
+                                    mSource, displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0,
+                                    0, metaState, /* buttonState */ 0, MotionClassification::NONE,
                                     AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
                                     &pointerCoords, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
                                     AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, /* videoFrames */ {});
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
index 38c7258..7a77b12 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
@@ -24,7 +24,7 @@
 
 class RotaryEncoderInputMapper : public InputMapper {
 public:
-    explicit RotaryEncoderInputMapper(InputDevice* device);
+    explicit RotaryEncoderInputMapper(InputDeviceContext& deviceContext);
     virtual ~RotaryEncoderInputMapper();
 
     virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp b/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
index 440d282..4fff9be 100644
--- a/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
@@ -18,12 +18,13 @@
 
 namespace android {
 
-SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) : TouchInputMapper(device) {}
+SingleTouchInputMapper::SingleTouchInputMapper(InputDeviceContext& deviceContext)
+      : TouchInputMapper(deviceContext) {}
 
 SingleTouchInputMapper::~SingleTouchInputMapper() {}
 
 void SingleTouchInputMapper::reset(nsecs_t when) {
-    mSingleTouchMotionAccumulator.reset(getDevice());
+    mSingleTouchMotionAccumulator.reset(getDeviceContext());
 
     TouchInputMapper::reset(when);
 }
diff --git a/services/inputflinger/reader/mapper/SingleTouchInputMapper.h b/services/inputflinger/reader/mapper/SingleTouchInputMapper.h
index 8438eee..f5befb3 100644
--- a/services/inputflinger/reader/mapper/SingleTouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/SingleTouchInputMapper.h
@@ -24,7 +24,7 @@
 
 class SingleTouchInputMapper : public TouchInputMapper {
 public:
-    explicit SingleTouchInputMapper(InputDevice* device);
+    explicit SingleTouchInputMapper(InputDeviceContext& deviceContext);
     virtual ~SingleTouchInputMapper();
 
     virtual void reset(nsecs_t when) override;
diff --git a/services/inputflinger/reader/mapper/SwitchInputMapper.cpp b/services/inputflinger/reader/mapper/SwitchInputMapper.cpp
index 16095b9..52b2449 100644
--- a/services/inputflinger/reader/mapper/SwitchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SwitchInputMapper.cpp
@@ -20,8 +20,8 @@
 
 namespace android {
 
-SwitchInputMapper::SwitchInputMapper(InputDevice* device)
-      : InputMapper(device), mSwitchValues(0), mUpdatedSwitchMask(0) {}
+SwitchInputMapper::SwitchInputMapper(InputDeviceContext& deviceContext)
+      : InputMapper(deviceContext), mSwitchValues(0), mUpdatedSwitchMask(0) {}
 
 SwitchInputMapper::~SwitchInputMapper() {}
 
@@ -56,7 +56,7 @@
 void SwitchInputMapper::sync(nsecs_t when) {
     if (mUpdatedSwitchMask) {
         uint32_t updatedSwitchValues = mSwitchValues & mUpdatedSwitchMask;
-        NotifySwitchArgs args(mContext->getNextSequenceNum(), when, 0 /*policyFlags*/,
+        NotifySwitchArgs args(getContext()->getNextSequenceNum(), when, 0 /*policyFlags*/,
                               updatedSwitchValues, mUpdatedSwitchMask);
         getListener()->notifySwitch(&args);
 
@@ -65,7 +65,7 @@
 }
 
 int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
-    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
+    return getDeviceContext().getSwitchState(switchCode);
 }
 
 void SwitchInputMapper::dump(std::string& dump) {
diff --git a/services/inputflinger/reader/mapper/SwitchInputMapper.h b/services/inputflinger/reader/mapper/SwitchInputMapper.h
index e65d4e2..4d74163 100644
--- a/services/inputflinger/reader/mapper/SwitchInputMapper.h
+++ b/services/inputflinger/reader/mapper/SwitchInputMapper.h
@@ -23,7 +23,7 @@
 
 class SwitchInputMapper : public InputMapper {
 public:
-    explicit SwitchInputMapper(InputDevice* device);
+    explicit SwitchInputMapper(InputDeviceContext& deviceContext);
     virtual ~SwitchInputMapper();
 
     virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 3b20173..e832804 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -156,8 +156,8 @@
 
 // --- TouchInputMapper ---
 
-TouchInputMapper::TouchInputMapper(InputDevice* device)
-      : InputMapper(device),
+TouchInputMapper::TouchInputMapper(InputDeviceContext& deviceContext)
+      : InputMapper(deviceContext),
         mSource(0),
         mDeviceMode(DEVICE_MODE_DISABLED),
         mSurfaceWidth(-1),
@@ -348,8 +348,8 @@
         configureParameters();
 
         // Configure common accumulators.
-        mCursorScrollAccumulator.configure(getDevice());
-        mTouchButtonAccumulator.configure(getDevice());
+        mCursorScrollAccumulator.configure(getDeviceContext());
+        mTouchButtonAccumulator.configure(getDeviceContext());
 
         // Configure absolute axis information.
         configureRawPointerAxes();
@@ -386,13 +386,14 @@
     if (changes && resetNeeded) {
         // Send reset, unless this is the first time the device has been configured,
         // in which case the reader will call reset itself after all mappers are ready.
-        getDevice()->notifyReset(when);
+        NotifyDeviceResetArgs args(getContext()->getNextSequenceNum(), when, getDeviceId());
+        getListener()->notifyDeviceReset(&args);
     }
 }
 
 void TouchInputMapper::resolveExternalStylusPresence() {
     std::vector<InputDeviceInfo> devices;
-    mContext->getExternalStylusDevices(devices);
+    getContext()->getExternalStylusDevices(devices);
     mExternalStylusConnected = !devices.empty();
 
     if (!mExternalStylusConnected) {
@@ -404,13 +405,13 @@
     // Use the pointer presentation mode for devices that do not support distinct
     // multitouch.  The spot-based presentation relies on being able to accurately
     // locate two or more fingers on the touch pad.
-    mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
+    mParameters.gestureMode = getDeviceContext().hasInputProperty(INPUT_PROP_SEMI_MT)
             ? Parameters::GESTURE_MODE_SINGLE_TOUCH
             : Parameters::GESTURE_MODE_MULTI_TOUCH;
 
     String8 gestureModeString;
-    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
-                                                       gestureModeString)) {
+    if (getDeviceContext().getConfiguration().tryGetProperty(String8("touch.gestureMode"),
+                                                             gestureModeString)) {
         if (gestureModeString == "single-touch") {
             mParameters.gestureMode = Parameters::GESTURE_MODE_SINGLE_TOUCH;
         } else if (gestureModeString == "multi-touch") {
@@ -420,14 +421,14 @@
         }
     }
 
-    if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
+    if (getDeviceContext().hasInputProperty(INPUT_PROP_DIRECT)) {
         // The device is a touch screen.
         mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
-    } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
+    } else if (getDeviceContext().hasInputProperty(INPUT_PROP_POINTER)) {
         // The device is a pointing device like a track pad.
         mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
-    } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X) ||
-               getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
+    } else if (getDeviceContext().hasRelativeAxis(REL_X) ||
+               getDeviceContext().hasRelativeAxis(REL_Y)) {
         // The device is a cursor device with a touch pad attached.
         // By default don't use the touch pad to move the pointer.
         mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
@@ -436,12 +437,11 @@
         mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
     }
 
-    mParameters.hasButtonUnderPad =
-            getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_BUTTONPAD);
+    mParameters.hasButtonUnderPad = getDeviceContext().hasInputProperty(INPUT_PROP_BUTTONPAD);
 
     String8 deviceTypeString;
-    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
-                                                       deviceTypeString)) {
+    if (getDeviceContext().getConfiguration().tryGetProperty(String8("touch.deviceType"),
+                                                             deviceTypeString)) {
         if (deviceTypeString == "touchScreen") {
             mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
         } else if (deviceTypeString == "touchPad") {
@@ -456,8 +456,8 @@
     }
 
     mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
-    getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
-                                                   mParameters.orientationAware);
+    getDeviceContext().getConfiguration().tryGetProperty(String8("touch.orientationAware"),
+                                                         mParameters.orientationAware);
 
     mParameters.hasAssociatedDisplay = false;
     mParameters.associatedDisplayIsExternal = false;
@@ -466,22 +466,22 @@
         mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
         mParameters.hasAssociatedDisplay = true;
         if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
-            mParameters.associatedDisplayIsExternal = getDevice()->isExternal();
+            mParameters.associatedDisplayIsExternal = getDeviceContext().isExternal();
             String8 uniqueDisplayId;
-            getDevice()->getConfiguration().tryGetProperty(String8("touch.displayId"),
-                                                           uniqueDisplayId);
+            getDeviceContext().getConfiguration().tryGetProperty(String8("touch.displayId"),
+                                                                 uniqueDisplayId);
             mParameters.uniqueDisplayId = uniqueDisplayId.c_str();
         }
     }
-    if (getDevice()->getAssociatedDisplayPort()) {
+    if (getDeviceContext().getAssociatedDisplayPort()) {
         mParameters.hasAssociatedDisplay = true;
     }
 
     // Initial downs on external touch devices should wake the device.
     // Normally we don't do this for internal touch screens to prevent them from waking
     // up in your pocket but you can enable it using the input device configuration.
-    mParameters.wake = getDevice()->isExternal();
-    getDevice()->getConfiguration().tryGetProperty(String8("touch.wake"), mParameters.wake);
+    mParameters.wake = getDeviceContext().isExternal();
+    getDeviceContext().getConfiguration().tryGetProperty(String8("touch.wake"), mParameters.wake);
 }
 
 void TouchInputMapper::dumpParameters(std::string& dump) {
@@ -559,10 +559,10 @@
  */
 std::optional<DisplayViewport> TouchInputMapper::findViewport() {
     if (mParameters.hasAssociatedDisplay) {
-        const std::optional<uint8_t> displayPort = mDevice->getAssociatedDisplayPort();
+        const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
         if (displayPort) {
             // Find the viewport that contains the same port
-            return mDevice->getAssociatedViewport();
+            return getDeviceContext().getAssociatedViewport();
         }
 
         if (mDeviceMode == DEVICE_MODE_POINTER) {
@@ -1045,7 +1045,7 @@
 
 void TouchInputMapper::configureVirtualKeys() {
     std::vector<VirtualKeyDefinition> virtualKeyDefinitions;
-    getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
+    getDeviceContext().getVirtualKeyDefinitions(virtualKeyDefinitions);
 
     mVirtualKeys.clear();
 
@@ -1065,8 +1065,8 @@
         int32_t keyCode;
         int32_t dummyKeyMetaState;
         uint32_t flags;
-        if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, 0, &keyCode,
-                                  &dummyKeyMetaState, &flags)) {
+        if (getDeviceContext().mapKey(virtualKey.scanCode, 0, 0, &keyCode, &dummyKeyMetaState,
+                                      &flags)) {
             ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
             continue; // drop the key
         }
@@ -1109,7 +1109,7 @@
 }
 
 void TouchInputMapper::parseCalibration() {
-    const PropertyMap& in = getDevice()->getConfiguration();
+    const PropertyMap& in = getDeviceContext().getConfiguration();
     Calibration& out = mCalibration;
 
     // Size
@@ -1353,14 +1353,14 @@
 }
 
 void TouchInputMapper::updateAffineTransformation() {
-    mAffineTransform = getPolicy()->getTouchAffineTransformation(mDevice->getDescriptor(),
+    mAffineTransform = getPolicy()->getTouchAffineTransformation(getDeviceContext().getDescriptor(),
                                                                  mSurfaceOrientation);
 }
 
 void TouchInputMapper::reset(nsecs_t when) {
-    mCursorButtonAccumulator.reset(getDevice());
-    mCursorScrollAccumulator.reset(getDevice());
-    mTouchButtonAccumulator.reset(getDevice());
+    mCursorButtonAccumulator.reset(getDeviceContext());
+    mCursorScrollAccumulator.reset(getDeviceContext());
+    mTouchButtonAccumulator.reset(getDeviceContext());
 
     mPointerVelocityControl.reset();
     mWheelXVelocityControl.reset();
@@ -1782,8 +1782,8 @@
                     mCurrentVirtualKey.keyCode = virtualKey->keyCode;
                     mCurrentVirtualKey.scanCode = virtualKey->scanCode;
                     mCurrentVirtualKey.ignored =
-                            mContext->shouldDropVirtualKey(when, getDevice(), virtualKey->keyCode,
-                                                           virtualKey->scanCode);
+                            getContext()->shouldDropVirtualKey(when, virtualKey->keyCode,
+                                                               virtualKey->scanCode);
 
                     if (!mCurrentVirtualKey.ignored) {
 #if DEBUG_VIRTUAL_KEYS
@@ -1816,7 +1816,7 @@
     //    is displayed.
     if (mConfig.virtualKeyQuietTime > 0 &&
         !mCurrentRawState.rawPointerData.touchingIdBits.isEmpty()) {
-        mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
+        getContext()->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
     }
     return false;
 }
@@ -1826,12 +1826,12 @@
     int32_t keyCode = mCurrentVirtualKey.keyCode;
     int32_t scanCode = mCurrentVirtualKey.scanCode;
     nsecs_t downTime = mCurrentVirtualKey.downTime;
-    int32_t metaState = mContext->getGlobalMetaState();
+    int32_t metaState = getContext()->getGlobalMetaState();
     policyFlags |= POLICY_FLAG_VIRTUAL;
 
-    NotifyKeyArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), AINPUT_SOURCE_KEYBOARD,
-                       mViewport.displayId, policyFlags, keyEventAction, keyEventFlags, keyCode,
-                       scanCode, metaState, downTime);
+    NotifyKeyArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(),
+                       AINPUT_SOURCE_KEYBOARD, mViewport.displayId, policyFlags, keyEventAction,
+                       keyEventFlags, keyCode, scanCode, metaState, downTime);
     getListener()->notifyKey(&args);
 }
 
@@ -2503,7 +2503,7 @@
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
 
         const int32_t displayId = mPointerController->getDisplayId();
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+        NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
                               displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
                               metaState, buttonState, MotionClassification::NONE,
                               AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties, &pointerCoords,
@@ -3423,7 +3423,7 @@
         mPointerSimple.down = false;
 
         // Send up.
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+        NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
                               displayId, policyFlags, AMOTION_EVENT_ACTION_UP, 0, 0, metaState,
                               mLastRawState.buttonState, MotionClassification::NONE,
                               AMOTION_EVENT_EDGE_FLAG_NONE, 1, &mPointerSimple.lastProperties,
@@ -3437,7 +3437,7 @@
         mPointerSimple.hovering = false;
 
         // Send hover exit.
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+        NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
                               displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0,
                               metaState, mLastRawState.buttonState, MotionClassification::NONE,
                               AMOTION_EVENT_EDGE_FLAG_NONE, 1, &mPointerSimple.lastProperties,
@@ -3453,7 +3453,7 @@
             mPointerSimple.downTime = when;
 
             // Send down.
-            NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+            NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
                                   displayId, policyFlags, AMOTION_EVENT_ACTION_DOWN, 0, 0,
                                   metaState, mCurrentRawState.buttonState,
                                   MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1,
@@ -3464,7 +3464,7 @@
         }
 
         // Send move.
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+        NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
                               displayId, policyFlags, AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState,
                               mCurrentRawState.buttonState, MotionClassification::NONE,
                               AMOTION_EVENT_EDGE_FLAG_NONE, 1, &mPointerSimple.currentProperties,
@@ -3479,7 +3479,7 @@
             mPointerSimple.hovering = true;
 
             // Send hover enter.
-            NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+            NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
                                   displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0,
                                   metaState, mCurrentRawState.buttonState,
                                   MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1,
@@ -3490,7 +3490,7 @@
         }
 
         // Send hover move.
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+        NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
                               displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
                               metaState, mCurrentRawState.buttonState, MotionClassification::NONE,
                               AMOTION_EVENT_EDGE_FLAG_NONE, 1, &mPointerSimple.currentProperties,
@@ -3512,7 +3512,7 @@
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
 
-        NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+        NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, getDeviceId(), mSource,
                               displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState,
                               mCurrentRawState.buttonState, MotionClassification::NONE,
                               AMOTION_EVENT_EDGE_FLAG_NONE, 1, &mPointerSimple.currentProperties,
@@ -3583,10 +3583,10 @@
     }
     const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE);
     const int32_t deviceId = getDeviceId();
-    std::vector<TouchVideoFrame> frames = mDevice->getEventHub()->getVideoFrames(deviceId);
+    std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();
     std::for_each(frames.begin(), frames.end(),
                   [this](TouchVideoFrame& frame) { frame.rotate(this->mSurfaceOrientation); });
-    NotifyMotionArgs args(mContext->getNextSequenceNum(), when, deviceId, source, displayId,
+    NotifyMotionArgs args(getContext()->getNextSequenceNum(), when, deviceId, source, displayId,
                           policyFlags, action, actionButton, flags, metaState, buttonState,
                           MotionClassification::NONE, edgeFlags, pointerCount, pointerProperties,
                           pointerCoords, xPrecision, yPrecision, xCursorPosition, yCursorPosition,
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index 4b1c0cb..3a61206 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -132,7 +132,7 @@
 
 class TouchInputMapper : public InputMapper {
 public:
-    explicit TouchInputMapper(InputDevice* device);
+    explicit TouchInputMapper(InputDeviceContext& deviceContext);
     virtual ~TouchInputMapper();
 
     virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
index a27fab4..1b584ea 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
@@ -20,8 +20,8 @@
 
 namespace android {
 
-VibratorInputMapper::VibratorInputMapper(InputDevice* device)
-      : InputMapper(device), mVibrating(false) {}
+VibratorInputMapper::VibratorInputMapper(InputDeviceContext& deviceContext)
+      : InputMapper(deviceContext), mVibrating(false) {}
 
 VibratorInputMapper::~VibratorInputMapper() {}
 
@@ -100,12 +100,12 @@
 #if DEBUG_VIBRATOR
         ALOGD("nextStep: sending vibrate deviceId=%d, duration=%" PRId64, getDeviceId(), duration);
 #endif
-        getEventHub()->vibrate(getDeviceId(), duration);
+        getDeviceContext().vibrate(duration);
     } else {
 #if DEBUG_VIBRATOR
         ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
 #endif
-        getEventHub()->cancelVibrate(getDeviceId());
+        getDeviceContext().cancelVibrate();
     }
     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
     mNextStepTime = now + duration;
@@ -120,7 +120,7 @@
 #if DEBUG_VIBRATOR
     ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
 #endif
-    getEventHub()->cancelVibrate(getDeviceId());
+    getDeviceContext().cancelVibrate();
 }
 
 void VibratorInputMapper::dump(std::string& dump) {
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.h b/services/inputflinger/reader/mapper/VibratorInputMapper.h
index dc67890..f69fdde 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.h
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.h
@@ -23,7 +23,7 @@
 
 class VibratorInputMapper : public InputMapper {
 public:
-    explicit VibratorInputMapper(InputDevice* device);
+    explicit VibratorInputMapper(InputDeviceContext& deviceContext);
     virtual ~VibratorInputMapper();
 
     virtual uint32_t getSources() override;
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp
index 0337d51..2d7d73b 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.cpp
@@ -25,15 +25,15 @@
     clearButtons();
 }
 
-void CursorButtonAccumulator::reset(InputDevice* device) {
-    mBtnLeft = device->isKeyPressed(BTN_LEFT);
-    mBtnRight = device->isKeyPressed(BTN_RIGHT);
-    mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
-    mBtnBack = device->isKeyPressed(BTN_BACK);
-    mBtnSide = device->isKeyPressed(BTN_SIDE);
-    mBtnForward = device->isKeyPressed(BTN_FORWARD);
-    mBtnExtra = device->isKeyPressed(BTN_EXTRA);
-    mBtnTask = device->isKeyPressed(BTN_TASK);
+void CursorButtonAccumulator::reset(InputDeviceContext& deviceContext) {
+    mBtnLeft = deviceContext.isKeyPressed(BTN_LEFT);
+    mBtnRight = deviceContext.isKeyPressed(BTN_RIGHT);
+    mBtnMiddle = deviceContext.isKeyPressed(BTN_MIDDLE);
+    mBtnBack = deviceContext.isKeyPressed(BTN_BACK);
+    mBtnSide = deviceContext.isKeyPressed(BTN_SIDE);
+    mBtnForward = deviceContext.isKeyPressed(BTN_FORWARD);
+    mBtnExtra = deviceContext.isKeyPressed(BTN_EXTRA);
+    mBtnTask = deviceContext.isKeyPressed(BTN_TASK);
 }
 
 void CursorButtonAccumulator::clearButtons() {
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.h b/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.h
index d912310..9e15906 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/CursorButtonAccumulator.h
@@ -21,14 +21,14 @@
 
 namespace android {
 
-class InputDevice;
+class InputDeviceContext;
 struct RawEvent;
 
 /* Keeps track of the state of mouse or touch pad buttons. */
 class CursorButtonAccumulator {
 public:
     CursorButtonAccumulator();
-    void reset(InputDevice* device);
+    void reset(InputDeviceContext& deviceContext);
 
     void process(const RawEvent* rawEvent);
 
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
index d744096..0714694 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
@@ -25,12 +25,12 @@
     clearRelativeAxes();
 }
 
-void CursorScrollAccumulator::configure(InputDevice* device) {
-    mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
-    mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
+void CursorScrollAccumulator::configure(InputDeviceContext& deviceContext) {
+    mHaveRelWheel = deviceContext.hasRelativeAxis(REL_WHEEL);
+    mHaveRelHWheel = deviceContext.hasRelativeAxis(REL_HWHEEL);
 }
 
-void CursorScrollAccumulator::reset(InputDevice* device) {
+void CursorScrollAccumulator::reset(InputDeviceContext& deviceContext) {
     clearRelativeAxes();
 }
 
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
index 85f331f..1649559 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
@@ -21,7 +21,7 @@
 
 namespace android {
 
-class InputDevice;
+class InputDeviceContext;
 struct RawEvent;
 
 /* Keeps track of cursor scrolling motions. */
@@ -29,8 +29,8 @@
 class CursorScrollAccumulator {
 public:
     CursorScrollAccumulator();
-    void configure(InputDevice* device);
-    void reset(InputDevice* device);
+    void configure(InputDeviceContext& deviceContext);
+    void reset(InputDeviceContext& deviceContext);
 
     void process(const RawEvent* rawEvent);
     void finishSync();
diff --git a/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp
index e9ba727..27b8e40 100644
--- a/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp
@@ -25,14 +25,14 @@
     clearAbsoluteAxes();
 }
 
-void SingleTouchMotionAccumulator::reset(InputDevice* device) {
-    mAbsX = device->getAbsoluteAxisValue(ABS_X);
-    mAbsY = device->getAbsoluteAxisValue(ABS_Y);
-    mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
-    mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
-    mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
-    mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
-    mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
+void SingleTouchMotionAccumulator::reset(InputDeviceContext& deviceContext) {
+    mAbsX = deviceContext.getAbsoluteAxisValue(ABS_X);
+    mAbsY = deviceContext.getAbsoluteAxisValue(ABS_Y);
+    mAbsPressure = deviceContext.getAbsoluteAxisValue(ABS_PRESSURE);
+    mAbsToolWidth = deviceContext.getAbsoluteAxisValue(ABS_TOOL_WIDTH);
+    mAbsDistance = deviceContext.getAbsoluteAxisValue(ABS_DISTANCE);
+    mAbsTiltX = deviceContext.getAbsoluteAxisValue(ABS_TILT_X);
+    mAbsTiltY = deviceContext.getAbsoluteAxisValue(ABS_TILT_Y);
 }
 
 void SingleTouchMotionAccumulator::clearAbsoluteAxes() {
diff --git a/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.h b/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.h
index 75f8a96..4c011f1 100644
--- a/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.h
@@ -21,7 +21,7 @@
 
 namespace android {
 
-class InputDevice;
+class InputDeviceContext;
 struct RawEvent;
 
 /* Keeps track of the state of single-touch protocol. */
@@ -30,7 +30,7 @@
     SingleTouchMotionAccumulator();
 
     void process(const RawEvent* rawEvent);
-    void reset(InputDevice* device);
+    void reset(InputDeviceContext& deviceContext);
 
     inline int32_t getAbsoluteX() const { return mAbsX; }
     inline int32_t getAbsoluteY() const { return mAbsY; }
diff --git a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp
index d2f06c8..86153d3 100644
--- a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.cpp
@@ -25,29 +25,31 @@
     clearButtons();
 }
 
-void TouchButtonAccumulator::configure(InputDevice* device) {
-    mHaveBtnTouch = device->hasKey(BTN_TOUCH);
-    mHaveStylus = device->hasKey(BTN_TOOL_PEN) || device->hasKey(BTN_TOOL_RUBBER) ||
-            device->hasKey(BTN_TOOL_BRUSH) || device->hasKey(BTN_TOOL_PENCIL) ||
-            device->hasKey(BTN_TOOL_AIRBRUSH);
+void TouchButtonAccumulator::configure(InputDeviceContext& deviceContext) {
+    mHaveBtnTouch = deviceContext.hasScanCode(BTN_TOUCH);
+    mHaveStylus = deviceContext.hasScanCode(BTN_TOOL_PEN) ||
+            deviceContext.hasScanCode(BTN_TOOL_RUBBER) ||
+            deviceContext.hasScanCode(BTN_TOOL_BRUSH) ||
+            deviceContext.hasScanCode(BTN_TOOL_PENCIL) ||
+            deviceContext.hasScanCode(BTN_TOOL_AIRBRUSH);
 }
 
-void TouchButtonAccumulator::reset(InputDevice* device) {
-    mBtnTouch = device->isKeyPressed(BTN_TOUCH);
-    mBtnStylus = device->isKeyPressed(BTN_STYLUS);
+void TouchButtonAccumulator::reset(InputDeviceContext& deviceContext) {
+    mBtnTouch = deviceContext.isKeyPressed(BTN_TOUCH);
+    mBtnStylus = deviceContext.isKeyPressed(BTN_STYLUS);
     // BTN_0 is what gets mapped for the HID usage Digitizers.SecondaryBarrelSwitch
-    mBtnStylus2 = device->isKeyPressed(BTN_STYLUS2) || device->isKeyPressed(BTN_0);
-    mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
-    mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
-    mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
-    mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
-    mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
-    mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
-    mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
-    mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
-    mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
-    mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
-    mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
+    mBtnStylus2 = deviceContext.isKeyPressed(BTN_STYLUS2) || deviceContext.isKeyPressed(BTN_0);
+    mBtnToolFinger = deviceContext.isKeyPressed(BTN_TOOL_FINGER);
+    mBtnToolPen = deviceContext.isKeyPressed(BTN_TOOL_PEN);
+    mBtnToolRubber = deviceContext.isKeyPressed(BTN_TOOL_RUBBER);
+    mBtnToolBrush = deviceContext.isKeyPressed(BTN_TOOL_BRUSH);
+    mBtnToolPencil = deviceContext.isKeyPressed(BTN_TOOL_PENCIL);
+    mBtnToolAirbrush = deviceContext.isKeyPressed(BTN_TOOL_AIRBRUSH);
+    mBtnToolMouse = deviceContext.isKeyPressed(BTN_TOOL_MOUSE);
+    mBtnToolLens = deviceContext.isKeyPressed(BTN_TOOL_LENS);
+    mBtnToolDoubleTap = deviceContext.isKeyPressed(BTN_TOOL_DOUBLETAP);
+    mBtnToolTripleTap = deviceContext.isKeyPressed(BTN_TOOL_TRIPLETAP);
+    mBtnToolQuadTap = deviceContext.isKeyPressed(BTN_TOOL_QUADTAP);
 }
 
 void TouchButtonAccumulator::clearButtons() {
diff --git a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h
index 65b6bdc..22ebb72 100644
--- a/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/TouchButtonAccumulator.h
@@ -21,15 +21,15 @@
 
 namespace android {
 
-class InputDevice;
+class InputDeviceContext;
 struct RawEvent;
 
 /* Keeps track of the state of touch, stylus and tool buttons. */
 class TouchButtonAccumulator {
 public:
     TouchButtonAccumulator();
-    void configure(InputDevice* device);
-    void reset(InputDevice* device);
+    void configure(InputDeviceContext& deviceContext);
+    void reset(InputDeviceContext& deviceContext);
 
     void process(const RawEvent* rawEvent);
 
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 7cd8793..01bd9db 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -881,9 +881,7 @@
     virtual void disableVirtualKeysUntil(nsecs_t) {
     }
 
-    virtual bool shouldDropVirtualKey(nsecs_t, InputDevice*, int32_t, int32_t) {
-        return false;
-    }
+    virtual bool shouldDropVirtualKey(nsecs_t, int32_t, int32_t) { return false; }
 
     virtual void fadePointer() {
     }
@@ -929,12 +927,14 @@
 
     std::optional<DisplayViewport> mViewport;
 public:
-    FakeInputMapper(InputDevice* device, uint32_t sources) :
-            InputMapper(device),
-            mSources(sources), mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
+    FakeInputMapper(InputDeviceContext& deviceContext, uint32_t sources)
+          : InputMapper(deviceContext),
+            mSources(sources),
+            mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
             mMetaState(0),
-            mConfigureWasCalled(false), mResetWasCalled(false), mProcessWasCalled(false) {
-    }
+            mConfigureWasCalled(false),
+            mResetWasCalled(false),
+            mProcessWasCalled(false) {}
 
     virtual ~FakeInputMapper() { }
 
@@ -1022,7 +1022,7 @@
         mConfigureWasCalled = true;
 
         // Find the associated viewport if exist.
-        const std::optional<uint8_t> displayPort = mDevice->getAssociatedDisplayPort();
+        const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
         if (displayPort && (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
             mViewport = config->getDisplayViewportByPort(*displayPort);
         }