Fix input injection with zero coords
In the native MotionEvent class, setting an axis value to 0 is
equivalent to removing the axis from the bitfield of valid axes. This is
because getting an axis value that is not set in the bitfield will
return 0 by default.
This means that we cannot rely on the bitfield of valid axes to know
exactly which axes are valid, since all axes are always valid with a
default value of 0.
Rather than transforming only the axies that are set in the bitfield, we
add a helper function to MotionEvent to transform the entire
PointerCoords.
Bug: 219711163
Test: manual, see bug: adb shell input draganddrop 665 531 0 531 1000
Change-Id: I335beebf8263a38f180f2f4c6a788fbd69d15a6f
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 3073d94..fe1754c 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -846,6 +846,7 @@
return calculateTransformedXYUnchecked(source, transform, xy);
}
+// Keep in sync with calculateTransformedCoords.
float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source,
const ui::Transform& transform,
const PointerCoords& coords) {
@@ -874,6 +875,34 @@
return coords.getAxisValue(axis);
}
+// Keep in sync with calculateTransformedAxisValue. This is an optimization of
+// calculateTransformedAxisValue for all PointerCoords axes.
+PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source,
+ const ui::Transform& transform,
+ const PointerCoords& coords) {
+ if (shouldDisregardTransformation(source)) {
+ return coords;
+ }
+ PointerCoords out = coords;
+
+ const vec2 xy = calculateTransformedXYUnchecked(source, transform, coords.getXYValue());
+ out.setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
+ out.setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
+
+ const vec2 relativeXy =
+ transformWithoutTranslation(transform,
+ {coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
+ coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)});
+ out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, relativeXy.x);
+ out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, relativeXy.y);
+
+ out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
+ transformAngle(transform,
+ coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION)));
+
+ return out;
+}
+
// --- FocusEvent ---
void FocusEvent::initialize(int32_t id, bool hasFocus) {