VerifiedMotionEvent: Sign transformed raw values
The values for axes X/Y that are stored in MotionEvent are
transformed to values used for its getRaw API based on the source.
This is because non-pointer sources should not have translation applied
to them.
We need to ensure that we use the same raw coordinates when we sign a
VerifiedMotionEvent in InputDispatcher that we would get with the
MotionEvent#getRaw API. To do this, we re-use the same logic used to
transform the raw coordinates in MotionEvent in InputDispatcher.
Bug: 179274888
Test: atest inputflinger_tests
Test: atest VerifyInputEventTest
Change-Id: I552f94064f15573ddda8f7c0b588cd3b984b6a94
diff --git a/include/input/Input.h b/include/input/Input.h
index d397313..5015e68 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -801,6 +801,8 @@
static std::string actionToString(int32_t action);
+ static vec2 calculateTransformedXY(uint32_t source, const ui::Transform&, const vec2& xy);
+
protected:
int32_t mAction;
int32_t mActionButton;
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index a1542c8..1bc244c 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -65,8 +65,8 @@
return result;
}
-vec2 transformWithoutTranslation(const ui::Transform& transform, float x, float y) {
- const vec2 transformedXy = transform.transform(x, y);
+vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy) {
+ const vec2 transformedXy = transform.transform(xy);
const vec2 transformedOrigin = transform.transform(0, 0);
return transformedXy - transformedOrigin;
}
@@ -501,21 +501,16 @@
const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
- // For compatibility, convert raw coordinates into logical display space.
- const vec2 xy = shouldDisregardTranslation(mSource)
- ? transformWithoutTranslation(mRawTransform, coords->getX(), coords->getY())
- : mRawTransform.transform(coords->getX(), coords->getY());
+ const vec2 xy = calculateTransformedXY(mSource, mRawTransform, coords->getXYValue());
static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
return xy[axis];
}
if (axis == AMOTION_EVENT_AXIS_RELATIVE_X || axis == AMOTION_EVENT_AXIS_RELATIVE_Y) {
- // For compatibility, since we report raw coordinates in logical display space, we
- // need to convert the relative axes into the same orientation for consistency.
const vec2 relativeXy =
transformWithoutTranslation(mRawTransform,
- coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
- coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+ {coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
+ coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)});
return axis == AMOTION_EVENT_AXIS_RELATIVE_X ? relativeXy.x : relativeXy.y;
}
@@ -527,9 +522,7 @@
const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
- const vec2 xy = shouldDisregardTranslation(mSource)
- ? transformWithoutTranslation(mTransform, coords->getX(), coords->getY())
- : mTransform.transform(coords->getXYValue());
+ const vec2 xy = calculateTransformedXY(mSource, mTransform, coords->getXYValue());
static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
return xy[axis];
}
@@ -537,8 +530,8 @@
if (axis == AMOTION_EVENT_AXIS_RELATIVE_X || axis == AMOTION_EVENT_AXIS_RELATIVE_Y) {
const vec2 relativeXy =
transformWithoutTranslation(mTransform,
- coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
- coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+ {coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
+ coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)});
return axis == AMOTION_EVENT_AXIS_RELATIVE_X ? relativeXy.x : relativeXy.y;
}
@@ -815,6 +808,12 @@
return android::base::StringPrintf("%" PRId32, action);
}
+vec2 MotionEvent::calculateTransformedXY(uint32_t source, const ui::Transform& transform,
+ const vec2& xy) {
+ return shouldDisregardTranslation(source) ? transformWithoutTranslation(transform, xy)
+ : transform.transform(xy);
+}
+
// --- FocusEvent ---
void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) {
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index bcb0071..c03581d 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -40,14 +40,15 @@
entry.repeatCount};
}
-VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry) {
- const float rawX = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X);
- const float rawY = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y);
+VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry,
+ const ui::Transform& rawTransform) {
+ const vec2 rawXY = MotionEvent::calculateTransformedXY(entry.source, rawTransform,
+ entry.pointerCoords[0].getXYValue());
const int actionMasked = entry.action & AMOTION_EVENT_ACTION_MASK;
return {{VerifiedInputEvent::Type::MOTION, entry.deviceId, entry.eventTime, entry.source,
entry.displayId},
- rawX,
- rawY,
+ rawXY.x,
+ rawXY.y,
actionMasked,
entry.downTime,
entry.flags & VERIFIED_MOTION_EVENT_FLAGS,
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index 7a121ce..477781a 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -254,7 +254,8 @@
};
VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry);
-VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry);
+VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry,
+ const ui::Transform& rawTransform);
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 695dd17..52a88d7 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3360,16 +3360,18 @@
const std::array<uint8_t, 32> InputDispatcher::getSignature(
const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
- int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
- if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
+ const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
+ if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
// Only sign events up and down events as the purely move events
// are tied to their up/down counterparts so signing would be redundant.
- VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
- verifiedEvent.actionMasked = actionMasked;
- verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
- return sign(verifiedEvent);
+ return INVALID_HMAC;
}
- return INVALID_HMAC;
+
+ VerifiedMotionEvent verifiedEvent =
+ verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
+ verifiedEvent.actionMasked = actionMasked;
+ verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
+ return sign(verifiedEvent);
}
const std::array<uint8_t, 32> InputDispatcher::getSignature(
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 42d3e58..ca77d7a 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2801,7 +2801,14 @@
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
- mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+ ui::Transform transform;
+ transform.set({1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 0, 0, 1});
+
+ gui::DisplayInfo displayInfo;
+ displayInfo.displayId = ADISPLAY_ID_DEFAULT;
+ displayInfo.transform = transform;
+
+ mDispatcher->onWindowInfosChanged({*window->getInfo()}, {displayInfo});
NotifyMotionArgs motionArgs =
generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -2822,8 +2829,11 @@
const VerifiedMotionEvent& verifiedMotion = static_cast<const VerifiedMotionEvent&>(*verified);
- EXPECT_EQ(motionArgs.pointerCoords[0].getX(), verifiedMotion.rawX);
- EXPECT_EQ(motionArgs.pointerCoords[0].getY(), verifiedMotion.rawY);
+ const vec2 rawXY =
+ MotionEvent::calculateTransformedXY(motionArgs.source, transform,
+ motionArgs.pointerCoords[0].getXYValue());
+ EXPECT_EQ(rawXY.x, verifiedMotion.rawX);
+ EXPECT_EQ(rawXY.y, verifiedMotion.rawY);
EXPECT_EQ(motionArgs.action & AMOTION_EVENT_ACTION_MASK, verifiedMotion.actionMasked);
EXPECT_EQ(motionArgs.downTime, verifiedMotion.downTimeNanos);
EXPECT_EQ(motionArgs.flags & VERIFIED_MOTION_EVENT_FLAGS, verifiedMotion.flags);