summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean McCreary <mccreary@mcwest.org>2021-06-17 10:39:54 -0600
committerJan Altensen <info@stricted.net>2021-07-23 18:19:37 +0200
commit240b8119bc45fc604ff163038d5a3d4ce95cdae1 (patch)
tree191acdb6873a522c07bff23bc847d4f650892363
parented2228209cffc4c51ac8adf6271d53f0908a0d50 (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.h6
-rw-r--r--libs/input/Input.cpp42
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp18
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(),