diff options
author | Sean McCreary <mccreary@mcwest.org> | 2021-06-17 10:39:54 -0600 |
---|---|---|
committer | Jan Altensen <info@stricted.net> | 2021-07-23 18:19:37 +0200 |
commit | 240b8119bc45fc604ff163038d5a3d4ce95cdae1 (patch) | |
tree | 191acdb6873a522c07bff23bc847d4f650892363 | |
parent | ed2228209cffc4c51ac8adf6271d53f0908a0d50 (diff) |
Use the original device ID when the injected event is unchanged
* This is a partial revert of 0d8ed6e8ade20652cea20f579f40b1d698ce8fc0
a.k.a. Change-Id I9a61a99cf5f8ca1a27e4526dd6feedf2c1beec0f
which forced all injected events to appear to be from virtual keyboard
ID.
* Fixes some cases described in
https://issuetracker.google.com/issues/163120692
There may be accessibility apps that modify events in such a way that
they do not appear equivalent to the original event and therefore
continue to have their originated device ID being overridden to the
virtual keyboard ID. Fixing this fully needs API enhancements between
system server and accessibility filters to allow conveying the changes
the filter wishes to make.
* Add native MotionEvent::equals helper that's used by fw/b
InputManagerService to determine whether or not an input filter
modified a MotionEvent. All fields except mDownTime are checked
for precise equality. There are two issues with mDowntime:
- native uses ns, system service uses ms so there is a loss of
precision during inputflinger -> system server -> inputflinger
round trip.
- the magnify accessibility helper modifies this field with
MotionEvent.setDownTime()
Change-Id: Ib980ead9005934ebab65eece1a20cba0e2866b9a
-rw-r--r-- | include/input/Input.h | 6 | ||||
-rw-r--r-- | libs/input/Input.cpp | 42 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 18 |
3 files changed, 61 insertions, 5 deletions
diff --git a/include/input/Input.h b/include/input/Input.h index 54b4e5a737..57a05ada90 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -227,6 +227,10 @@ enum { // Disables automatic key repeating behavior. POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000, + // Indicates whether an injected event is an unmodified copy of what was originally + // a real input event. + POLICY_FLAGS_INJECTED_IS_UNCHANGED = 0x10000000, + /* These flags are set by the input reader policy as it intercepts each event. */ // Indicates that the device was in an interactive state when the @@ -693,6 +697,8 @@ public: void copyFrom(const MotionEvent* other, bool keepHistory); + bool equals(const MotionEvent* other) const; + void addSample( nsecs_t eventTime, const PointerCoords* pointerCoords); diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 31aa685391..36428a3727 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "Input" //#define LOG_NDEBUG 0 +#include <cmath> #include <cutils/compiler.h> #include <limits.h> #include <string.h> @@ -385,6 +386,47 @@ void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) { } } +bool MotionEvent::equals(const MotionEvent* other) const { + /* + * All fields are checked for precise equality except for mDownTime + * which is not checked because: + * 1) magnify accessibility service uses MotionEvent.setDownTime() + * 2) fw/b InputManagerService converts from ns to ms so precision is + * different after inputflinger -> system server -> inputflinger + * round trip. + */ + return mId == other->mId + && mDeviceId == other->mDeviceId + && mSource == other->mSource + && mDisplayId == other->mDisplayId + && mAction == other->mAction + && mActionButton == other->mActionButton + && mFlags == other->mFlags + && mEdgeFlags == other->mEdgeFlags + && mMetaState == other->mMetaState + && mButtonState == other->mButtonState + && mClassification == other->mClassification + && mXScale == other->mXScale + && mYScale == other->mYScale + && mXOffset == other->mXOffset + && mYOffset == other->mYOffset + && mXPrecision == other->mXPrecision + && mYPrecision == other->mYPrecision + && ((std::isnan(mRawXCursorPosition) && std::isnan(other->mRawXCursorPosition)) + || mRawXCursorPosition == other->mRawXCursorPosition) + && ((std::isnan(mRawYCursorPosition) && std::isnan(other->mRawYCursorPosition)) + || mRawYCursorPosition == other->mRawYCursorPosition) + && mPointerProperties.size() == other->mPointerProperties.size() + && std::equal(mPointerProperties.begin(), mPointerProperties.end(), + other->mPointerProperties.begin()) + && mSampleEventTimes.size() == other->mSampleEventTimes.size() + && std::equal(mSampleEventTimes.begin(), mSampleEventTimes.end(), + other->mSampleEventTimes.begin()) + && mSamplePointerCoords.size() == other->mSamplePointerCoords.size() + && std::equal(mSamplePointerCoords.begin(), mSamplePointerCoords.end(), + other->mSamplePointerCoords.begin()); +} + void MotionEvent::addSample( int64_t eventTime, const PointerCoords* pointerCoords) { diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index dd0082c09e..95704f2527 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -3291,6 +3291,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec if (hasInjectionPermission(injectorPid, injectorUid)) { policyFlags |= POLICY_FLAG_TRUSTED; } + // Override device ID if the injected event is not an unmodified real input. + bool forceVirtualKeyboardId = !(policyFlags & POLICY_FLAGS_INJECTED_IS_UNCHANGED); std::queue<EventEntry*> injectedEntries; switch (event->getType()) { @@ -3303,11 +3305,14 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec int32_t flags = incomingKey.getFlags(); int32_t keyCode = incomingKey.getKeyCode(); + int32_t deviceId = forceVirtualKeyboardId + ? VIRTUAL_KEYBOARD_ID + : incomingKey.getDeviceId(); int32_t metaState = incomingKey.getMetaState(); - accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action, + accelerateMetaShortcuts(deviceId, action, /*byref*/ keyCode, /*byref*/ metaState); KeyEvent keyEvent; - keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(), + keyEvent.initialize(incomingKey.getId(), deviceId, incomingKey.getSource(), incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode, incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(), incomingKey.getDownTime(), incomingKey.getEventTime()); @@ -3328,7 +3333,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec mLock.lock(); KeyEntry* injectedEntry = new KeyEntry(incomingKey.getId(), incomingKey.getEventTime(), - VIRTUAL_KEYBOARD_ID, incomingKey.getSource(), + deviceId, incomingKey.getSource(), incomingKey.getDisplayId(), policyFlags, action, flags, keyCode, incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(), incomingKey.getDownTime()); @@ -3346,6 +3351,9 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) { return INPUT_EVENT_INJECTION_FAILED; } + int32_t deviceId = forceVirtualKeyboardId + ? VIRTUAL_KEYBOARD_ID + : motionEvent->getDeviceId(); if (!(policyFlags & POLICY_FLAG_FILTERED)) { nsecs_t eventTime = motionEvent->getEventTime(); @@ -3361,7 +3369,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes(); const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords(); MotionEntry* injectedEntry = - new MotionEntry(motionEvent->getId(), *sampleEventTimes, VIRTUAL_KEYBOARD_ID, + new MotionEntry(motionEvent->getId(), *sampleEventTimes, deviceId, motionEvent->getSource(), motionEvent->getDisplayId(), policyFlags, action, actionButton, motionEvent->getFlags(), motionEvent->getMetaState(), motionEvent->getButtonState(), @@ -3378,7 +3386,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec samplePointerCoords += pointerCount; MotionEntry* nextInjectedEntry = new MotionEntry(motionEvent->getId(), *sampleEventTimes, - VIRTUAL_KEYBOARD_ID, motionEvent->getSource(), + deviceId, motionEvent->getSource(), motionEvent->getDisplayId(), policyFlags, action, actionButton, motionEvent->getFlags(), motionEvent->getMetaState(), motionEvent->getButtonState(), |