Merge "MotionEvent: Get offsets in raw coordinate space" into main
diff --git a/include/input/Input.h b/include/input/Input.h
index 374254f..ddc3768 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -662,10 +662,6 @@
 
     inline void setActionButton(int32_t button) { mActionButton = button; }
 
-    inline float getXOffset() const { return mTransform.tx(); }
-
-    inline float getYOffset() const { return mTransform.ty(); }
-
     inline const ui::Transform& getTransform() const { return mTransform; }
 
     std::optional<ui::Rotation> getSurfaceRotation() const;
@@ -880,6 +876,22 @@
 
     void offsetLocation(float xOffset, float yOffset);
 
+    /**
+     * Get the X offset of this motion event relative to the origin of the raw coordinate space.
+     *
+     * In practice, this is the delta that was added to the raw screen coordinates (i.e. in logical
+     * display space) to adjust for the absolute position of the containing windows and views.
+     */
+    float getRawXOffset() const;
+
+    /**
+     * Get the Y offset of this motion event relative to the origin of the raw coordinate space.
+     *
+     * In practice, this is the delta that was added to the raw screen coordinates (i.e. in logical
+     * display space) to adjust for the absolute position of the containing windows and views.
+     */
+    float getRawYOffset() const;
+
     void scale(float globalScaleFactor);
 
     // Set 3x3 perspective matrix transformation.
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index d58fb42..ff9d9a9 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -751,6 +751,18 @@
     mTransform.set(currXOffset + xOffset, currYOffset + yOffset);
 }
 
+float MotionEvent::getRawXOffset() const {
+    // This is equivalent to the x-coordinate of the point that the origin of the raw coordinate
+    // space maps to.
+    return (mTransform * mRawTransform.inverse()).tx();
+}
+
+float MotionEvent::getRawYOffset() const {
+    // This is equivalent to the y-coordinate of the point that the origin of the raw coordinate
+    // space maps to.
+    return (mTransform * mRawTransform.inverse()).ty();
+}
+
 void MotionEvent::scale(float globalScaleFactor) {
     mTransform.set(mTransform.tx() * globalScaleFactor, mTransform.ty() * globalScaleFactor);
     mRawTransform.set(mRawTransform.tx() * globalScaleFactor,
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index 540766d..0df06b7 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -371,8 +371,10 @@
     ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, event->getButtonState());
     ASSERT_EQ(MotionClassification::NONE, event->getClassification());
     EXPECT_EQ(mTransform, event->getTransform());
-    ASSERT_EQ(X_OFFSET, event->getXOffset());
-    ASSERT_EQ(Y_OFFSET, event->getYOffset());
+    ASSERT_NEAR((-RAW_X_OFFSET / RAW_X_SCALE) * X_SCALE + X_OFFSET, event->getRawXOffset(),
+                EPSILON);
+    ASSERT_NEAR((-RAW_Y_OFFSET / RAW_Y_SCALE) * Y_SCALE + Y_OFFSET, event->getRawYOffset(),
+                EPSILON);
     ASSERT_EQ(2.0f, event->getXPrecision());
     ASSERT_EQ(2.1f, event->getYPrecision());
     ASSERT_EQ(ARBITRARY_DOWN_TIME, event->getDownTime());
@@ -709,22 +711,26 @@
 TEST_F(MotionEventTest, OffsetLocation) {
     MotionEvent event;
     initializeEventWithHistory(&event);
+    const float xOffset = event.getRawXOffset();
+    const float yOffset = event.getRawYOffset();
 
     event.offsetLocation(5.0f, -2.0f);
 
-    ASSERT_EQ(X_OFFSET + 5.0f, event.getXOffset());
-    ASSERT_EQ(Y_OFFSET - 2.0f, event.getYOffset());
+    ASSERT_EQ(xOffset + 5.0f, event.getRawXOffset());
+    ASSERT_EQ(yOffset - 2.0f, event.getRawYOffset());
 }
 
 TEST_F(MotionEventTest, Scale) {
     MotionEvent event;
     initializeEventWithHistory(&event);
     const float unscaledOrientation = event.getOrientation(0);
+    const float unscaledXOffset = event.getRawXOffset();
+    const float unscaledYOffset = event.getRawYOffset();
 
     event.scale(2.0f);
 
-    ASSERT_EQ(X_OFFSET * 2, event.getXOffset());
-    ASSERT_EQ(Y_OFFSET * 2, event.getYOffset());
+    ASSERT_EQ(unscaledXOffset * 2, event.getRawXOffset());
+    ASSERT_EQ(unscaledYOffset * 2, event.getRawYOffset());
 
     ASSERT_NEAR((RAW_X_OFFSET + 210 * RAW_X_SCALE) * 2, event.getRawX(0), EPSILON);
     ASSERT_NEAR((RAW_Y_OFFSET + 211 * RAW_Y_SCALE) * 2, event.getRawY(0), EPSILON);
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
index 3543020..30f9a42 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -135,8 +135,10 @@
     EXPECT_EQ(args.buttonState, motionEvent.getButtonState());
     EXPECT_EQ(args.classification, motionEvent.getClassification());
     EXPECT_EQ(args.transform, motionEvent.getTransform());
-    EXPECT_EQ(args.xOffset, motionEvent.getXOffset());
-    EXPECT_EQ(args.yOffset, motionEvent.getYOffset());
+    EXPECT_NEAR((-args.rawXOffset / args.rawXScale) * args.xScale + args.xOffset,
+                motionEvent.getRawXOffset(), EPSILON);
+    EXPECT_NEAR((-args.rawYOffset / args.rawYScale) * args.yScale + args.yOffset,
+                motionEvent.getRawYOffset(), EPSILON);
     EXPECT_EQ(args.xPrecision, motionEvent.getXPrecision());
     EXPECT_EQ(args.yPrecision, motionEvent.getYPrecision());
     EXPECT_NEAR(args.xCursorPosition, motionEvent.getRawXCursorPosition(), EPSILON);