MotionEvent: Report transformed orientation values
Previously, the AXIS_ORIENTATION value reported by MotionEvent was
unaffected by the window transform. This meant that whatever value that
was generated by InputReader was the value reported to the window. This
meant that if the window was rotated or scaled respective to the logical
display and the window received an event, it could be the case that the
0 value no longer corresponds with the "up" direction of the window.
Now that the input pipeline works in the display panel's coordinate
system, we need the orientation value reported by MotionEvent to be
affected by the window transform.
This CL also refactors the shared logic by which transformed axis values
are calculated into a common function.
Bug: 179274888
Test: atest libinput_tests
Test: atest inputflinger_tests
Test: manual with test app and stylus
Change-Id: Ibb6f135de47f7c1cbde3c023931a760dfbe08e45
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index b4d9ab6..d018800 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -493,44 +493,14 @@
float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
size_t historicalIndex) const {
- const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
-
- if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
- 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) {
- const vec2 relativeXy =
- transformWithoutTranslation(mRawTransform,
- {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;
- }
-
- return coords->getAxisValue(axis);
+ const PointerCoords& coords = *getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
+ return calculateTransformedAxisValue(axis, mSource, mRawTransform, coords);
}
float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
size_t historicalIndex) const {
- const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
-
- if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
- const vec2 xy = calculateTransformedXY(mSource, mTransform, 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) {
- const vec2 relativeXy =
- transformWithoutTranslation(mTransform,
- {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;
- }
-
- return coords->getAxisValue(axis);
+ const PointerCoords& coords = *getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
+ return calculateTransformedAxisValue(axis, mSource, mTransform, coords);
}
ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
@@ -569,15 +539,6 @@
ui::Transform newTransform;
newTransform.set(matrix);
mTransform = newTransform * mTransform;
-
- // We need to update the AXIS_ORIENTATION value here to maintain the old behavior where the
- // orientation angle is not affected by the initial transformation set in the MotionEvent.
- std::for_each(mSamplePointerCoords.begin(), mSamplePointerCoords.end(),
- [&newTransform](PointerCoords& c) {
- float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
- c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
- transformAngle(newTransform, orientation));
- });
}
void MotionEvent::applyTransform(const std::array<float, 9>& matrix) {
@@ -809,6 +770,30 @@
: transform.transform(xy);
}
+float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source,
+ const ui::Transform& transform,
+ const PointerCoords& coords) {
+ if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
+ const vec2 xy = calculateTransformedXY(source, transform, 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) {
+ const vec2 relativeXy =
+ transformWithoutTranslation(transform,
+ {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;
+ }
+
+ if (axis == AMOTION_EVENT_AXIS_ORIENTATION) {
+ return transformAngle(transform, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
+ }
+
+ return coords.getAxisValue(axis);
+}
+
// --- FocusEvent ---
void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) {