Apply translation/offset to events from pointer sources only

Non-pointer events from a relative motion device such as a trackball or
relative mouse (Pointer Capture) should be oriented in the same way as
the window it is directed to. We want them to be rotated if the window
transform has a rotation applied to it, but these relative events should
not be translated.

We only apply window translation to events from pointer sources because
they are the only ones that refer to absolute coordinates on the
display. We apply rotation for all motion events.

Bug: 179274888
Test: atest inputflinger_tests
Test: manual with test app
Change-Id: I8170697119d3d8e121b7b86de3201bac0edaaed9
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 70ed438..e83341a 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -91,6 +91,19 @@
     return xy;
 }
 
+vec2 applyTransformWithoutTranslation(const ui::Transform& transform, float x, float y) {
+    const vec2 transformedXy = transform.transform(x, y);
+    const vec2 transformedOrigin = transform.transform(0, 0);
+    return transformedXy - transformedOrigin;
+}
+
+bool shouldDisregardWindowTranslation(uint32_t source) {
+    // Pointer events are the only type of events that refer to absolute coordinates on the display,
+    // so we should apply the entire window transform. For other types of events, we should make
+    // sure to not apply the window translation/offset.
+    return (source & AINPUT_SOURCE_CLASS_POINTER) == 0;
+}
+
 } // namespace
 
 const char* motionClassificationToString(MotionClassification classification) {
@@ -509,8 +522,10 @@
     if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
         // For compatibility, convert raw coordinates into "oriented screen space". Once app
         // developers are educated about getRaw, we can consider removing this.
-        const vec2 xy = rotatePoint(mTransform, coords->getX(), coords->getY(), mDisplayWidth,
-                                    mDisplayHeight);
+        const vec2 xy = shouldDisregardWindowTranslation(mSource)
+                ? rotatePoint(mTransform, coords->getX(), coords->getY())
+                : rotatePoint(mTransform, coords->getX(), coords->getY(), mDisplayWidth,
+                              mDisplayHeight);
         static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
         return xy[axis];
     }
@@ -519,11 +534,13 @@
 }
 
 float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
-        size_t historicalIndex) const {
+                                          size_t historicalIndex) const {
     const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
 
     if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
-        const vec2 xy = mTransform.transform(coords->getXYValue());
+        const vec2 xy = shouldDisregardWindowTranslation(mSource)
+                ? applyTransformWithoutTranslation(mTransform, coords->getX(), coords->getY())
+                : mTransform.transform(coords->getXYValue());
         static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
         return xy[axis];
     }