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) {