Add display transform to MotionEvent for raw coords

Since input now works in display coordinates, we need to include the
display projection with MotionEvent so that the getRaw API can continue
to report logical display coordinates.

It is also important to highlight the difference in the coordinate
systems used by regular input windows and input monitors. MotionEvents
coming from input monitors will always report values in unrotated
logical display coordinates, because we do not yet have an API to report
unrotated values in MotionEvents.

Bug: 179274888
Test: presubmit
Test: manual, ensure input works
Change-Id: Ief3b2b31c6644beaa2f8c4b90302f441f93ab960
diff --git a/include/input/Input.h b/include/input/Input.h
index f170f0f..d397313 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -579,9 +579,7 @@
 
     void setCursorPosition(float x, float y);
 
-    uint32_t getDisplayOrientation() const { return mDisplayOrientation; }
-
-    int2 getDisplaySize() const { return {mDisplayWidth, mDisplayHeight}; }
+    ui::Transform getRawTransform() const { return mRawTransform; }
 
     static inline bool isValidCursorPosition(float x, float y) { return !isnan(x) && !isnan(y); }
 
@@ -757,8 +755,8 @@
                     int32_t flags, int32_t edgeFlags, int32_t metaState, int32_t buttonState,
                     MotionClassification classification, const ui::Transform& transform,
                     float xPrecision, float yPrecision, float rawXCursorPosition,
-                    float rawYCursorPosition, uint32_t displayOrientation, int32_t displayWidth,
-                    int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime, size_t pointerCount,
+                    float rawYCursorPosition, const ui::Transform& rawTransform, nsecs_t downTime,
+                    nsecs_t eventTime, size_t pointerCount,
                     const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
 
     void copyFrom(const MotionEvent* other, bool keepHistory);
@@ -816,9 +814,7 @@
     float mYPrecision;
     float mRawXCursorPosition;
     float mRawYCursorPosition;
-    uint32_t mDisplayOrientation;
-    int32_t mDisplayWidth;
-    int32_t mDisplayHeight;
+    ui::Transform mRawTransform;
     nsecs_t mDownTime;
     Vector<PointerProperties> mPointerProperties;
     std::vector<nsecs_t> mSampleEventTimes;
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 7632b30..d655b28 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -114,7 +114,7 @@
 
         struct Motion {
             int32_t eventId;
-            uint32_t empty1;
+            uint32_t pointerCount;
             nsecs_t eventTime __attribute__((aligned(8)));
             int32_t deviceId;
             int32_t source;
@@ -129,20 +129,22 @@
             uint8_t empty2[3];                   // 3 bytes to fill gap created by classification
             int32_t edgeFlags;
             nsecs_t downTime __attribute__((aligned(8)));
-            float dsdx;
-            float dtdx;
-            float dtdy;
-            float dsdy;
-            float tx;
-            float ty;
+            float dsdx; // Begin window transform
+            float dtdx; //
+            float dtdy; //
+            float dsdy; //
+            float tx;   //
+            float ty;   // End window transform
             float xPrecision;
             float yPrecision;
             float xCursorPosition;
             float yCursorPosition;
-            uint32_t displayOrientation;
-            int32_t displayWidth;
-            int32_t displayHeight;
-            uint32_t pointerCount;
+            float dsdxRaw; // Begin raw transform
+            float dtdxRaw; //
+            float dtdyRaw; //
+            float dsdyRaw; //
+            float txRaw;   //
+            float tyRaw;   // End raw transform
             /**
              * The "pointers" field must be the last field of the struct InputMessage.
              * When we send the struct InputMessage across the socket, we are not
@@ -367,9 +369,8 @@
                                 int32_t metaState, int32_t buttonState,
                                 MotionClassification classification, const ui::Transform& transform,
                                 float xPrecision, float yPrecision, float xCursorPosition,
-                                float yCursorPosition, uint32_t displayOrientation,
-                                int32_t displayWidth, int32_t displayHeight, nsecs_t downTime,
-                                nsecs_t eventTime, uint32_t pointerCount,
+                                float yCursorPosition, const ui::Transform& rawTransform,
+                                nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
                                 const PointerProperties* pointerProperties,
                                 const PointerCoords* pointerCoords);
 
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 037849e..30e5d5b 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -76,36 +76,13 @@
     return result;
 }
 
-// Rotates the given point to the specified orientation. If the display width and height are
-// provided, the point is rotated in the screen space. Otherwise, the point is rotated about the
-// origin. This helper is used to avoid the extra overhead of creating new Transforms.
-vec2 rotatePoint(uint32_t orientation, float x, float y, int32_t displayWidth = 0,
-                 int32_t displayHeight = 0) {
-    if (orientation == ui::Transform::ROT_0) {
-        return {x, y};
-    }
-
-    vec2 xy(x, y);
-    if (orientation == ui::Transform::ROT_90) {
-        xy.x = displayHeight - y;
-        xy.y = x;
-    } else if (orientation == ui::Transform::ROT_180) {
-        xy.x = displayWidth - x;
-        xy.y = displayHeight - y;
-    } else if (orientation == ui::Transform::ROT_270) {
-        xy.x = y;
-        xy.y = displayWidth - x;
-    }
-    return xy;
-}
-
-vec2 applyTransformWithoutTranslation(const ui::Transform& transform, float x, float y) {
+vec2 transformWithoutTranslation(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) {
+bool shouldDisregardTranslation(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.
@@ -431,8 +408,7 @@
                              int32_t buttonState, MotionClassification classification,
                              const ui::Transform& transform, float xPrecision, float yPrecision,
                              float rawXCursorPosition, float rawYCursorPosition,
-                             uint32_t displayOrientation, int32_t displayWidth,
-                             int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime,
+                             const ui::Transform& rawTransform, nsecs_t downTime, nsecs_t eventTime,
                              size_t pointerCount, const PointerProperties* pointerProperties,
                              const PointerCoords* pointerCoords) {
     InputEvent::initialize(id, deviceId, source, displayId, hmac);
@@ -448,9 +424,7 @@
     mYPrecision = yPrecision;
     mRawXCursorPosition = rawXCursorPosition;
     mRawYCursorPosition = rawYCursorPosition;
-    mDisplayOrientation = displayOrientation;
-    mDisplayWidth = displayWidth;
-    mDisplayHeight = displayHeight;
+    mRawTransform = rawTransform;
     mDownTime = downTime;
     mPointerProperties.clear();
     mPointerProperties.appendArray(pointerProperties, pointerCount);
@@ -474,9 +448,7 @@
     mYPrecision = other->mYPrecision;
     mRawXCursorPosition = other->mRawXCursorPosition;
     mRawYCursorPosition = other->mRawYCursorPosition;
-    mDisplayOrientation = other->mDisplayOrientation;
-    mDisplayWidth = other->mDisplayWidth;
-    mDisplayHeight = other->mDisplayHeight;
+    mRawTransform = other->mRawTransform;
     mDownTime = other->mDownTime;
     mPointerProperties = other->mPointerProperties;
 
@@ -542,20 +514,19 @@
     if (!isPerWindowInputRotationEnabled()) return coords->getAxisValue(axis);
 
     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 = shouldDisregardWindowTranslation(mSource)
-                ? rotatePoint(mDisplayOrientation, coords->getX(), coords->getY())
-                : rotatePoint(mDisplayOrientation, coords->getX(), coords->getY(), mDisplayWidth,
-                              mDisplayHeight);
+        // For compatibility, convert raw coordinates into logical display space.
+        const vec2 xy = shouldDisregardTranslation(mSource)
+                ? transformWithoutTranslation(mRawTransform, coords->getX(), coords->getY())
+                : mRawTransform.transform(coords->getX(), coords->getY());
         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) {
-        // For compatibility, since we convert raw coordinates into "oriented screen space", we
+        // For compatibility, since we report raw coordinates in logical display space, we
         // need to convert the relative axes into the same orientation for consistency.
-        const vec2 relativeXy = rotatePoint(mDisplayOrientation,
+        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;
@@ -569,8 +540,8 @@
     const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
 
     if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
-        const vec2 xy = shouldDisregardWindowTranslation(mSource)
-                ? applyTransformWithoutTranslation(mTransform, coords->getX(), coords->getY())
+        const vec2 xy = shouldDisregardTranslation(mSource)
+                ? transformWithoutTranslation(mTransform, coords->getX(), coords->getY())
                 : mTransform.transform(coords->getXYValue());
         static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
         return xy[axis];
@@ -578,11 +549,9 @@
 
     if (axis == AMOTION_EVENT_AXIS_RELATIVE_X || axis == AMOTION_EVENT_AXIS_RELATIVE_Y) {
         const vec2 relativeXy =
-                applyTransformWithoutTranslation(mTransform,
-                                                 coords->getAxisValue(
-                                                         AMOTION_EVENT_AXIS_RELATIVE_X),
-                                                 coords->getAxisValue(
-                                                         AMOTION_EVENT_AXIS_RELATIVE_Y));
+                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;
     }
 
@@ -607,6 +576,8 @@
 
 void MotionEvent::scale(float globalScaleFactor) {
     mTransform.set(mTransform.tx() * globalScaleFactor, mTransform.ty() * globalScaleFactor);
+    mRawTransform.set(mRawTransform.tx() * globalScaleFactor,
+                      mRawTransform.ty() * globalScaleFactor);
     mXPrecision *= globalScaleFactor;
     mYPrecision *= globalScaleFactor;
 
@@ -708,9 +679,11 @@
     mYPrecision = parcel->readFloat();
     mRawXCursorPosition = parcel->readFloat();
     mRawYCursorPosition = parcel->readFloat();
-    mDisplayOrientation = parcel->readUint32();
-    mDisplayWidth = parcel->readInt32();
-    mDisplayHeight = parcel->readInt32();
+
+    result = android::readFromParcel(mRawTransform, *parcel);
+    if (result != OK) {
+        return result;
+    }
     mDownTime = parcel->readInt64();
 
     mPointerProperties.clear();
@@ -770,9 +743,11 @@
     parcel->writeFloat(mYPrecision);
     parcel->writeFloat(mRawXCursorPosition);
     parcel->writeFloat(mRawYCursorPosition);
-    parcel->writeUint32(mDisplayOrientation);
-    parcel->writeInt32(mDisplayWidth);
-    parcel->writeInt32(mDisplayHeight);
+
+    result = android::writeToParcel(mRawTransform, *parcel);
+    if (result != OK) {
+        return result;
+    }
     parcel->writeInt64(mDownTime);
 
     for (size_t i = 0; i < pointerCount; i++) {
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 91ab008..02a5a08 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -203,6 +203,8 @@
         case InputMessage::Type::MOTION: {
             // int32_t eventId
             msg->body.motion.eventId = body.motion.eventId;
+            // uint32_t pointerCount
+            msg->body.motion.pointerCount = body.motion.pointerCount;
             // nsecs_t eventTime
             msg->body.motion.eventTime = body.motion.eventTime;
             // int32_t deviceId
@@ -245,14 +247,14 @@
             msg->body.motion.xCursorPosition = body.motion.xCursorPosition;
             // float yCursorPosition
             msg->body.motion.yCursorPosition = body.motion.yCursorPosition;
-            // uint32_t displayOrientation
-            msg->body.motion.displayOrientation = body.motion.displayOrientation;
-            // int32_t displayWidth
-            msg->body.motion.displayWidth = body.motion.displayWidth;
-            // int32_t displayHeight
-            msg->body.motion.displayHeight = body.motion.displayHeight;
-            // uint32_t pointerCount
-            msg->body.motion.pointerCount = body.motion.pointerCount;
+
+            msg->body.motion.dsdxRaw = body.motion.dsdxRaw;
+            msg->body.motion.dtdxRaw = body.motion.dtdxRaw;
+            msg->body.motion.dtdyRaw = body.motion.dtdyRaw;
+            msg->body.motion.dsdyRaw = body.motion.dsdyRaw;
+            msg->body.motion.txRaw = body.motion.txRaw;
+            msg->body.motion.tyRaw = body.motion.tyRaw;
+
             //struct Pointer pointers[MAX_POINTERS]
             for (size_t i = 0; i < body.motion.pointerCount; i++) {
                 // PointerProperties properties
@@ -542,8 +544,8 @@
         std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton, int32_t flags,
         int32_t edgeFlags, int32_t metaState, int32_t buttonState,
         MotionClassification classification, const ui::Transform& transform, float xPrecision,
-        float yPrecision, float xCursorPosition, float yCursorPosition, uint32_t displayOrientation,
-        int32_t displayWidth, int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime,
+        float yPrecision, float xCursorPosition, float yCursorPosition,
+        const ui::Transform& rawTransform, nsecs_t downTime, nsecs_t eventTime,
         uint32_t pointerCount, const PointerProperties* pointerProperties,
         const PointerCoords* pointerCoords) {
     if (ATRACE_ENABLED()) {
@@ -603,9 +605,12 @@
     msg.body.motion.yPrecision = yPrecision;
     msg.body.motion.xCursorPosition = xCursorPosition;
     msg.body.motion.yCursorPosition = yCursorPosition;
-    msg.body.motion.displayOrientation = displayOrientation;
-    msg.body.motion.displayWidth = displayWidth;
-    msg.body.motion.displayHeight = displayHeight;
+    msg.body.motion.dsdxRaw = rawTransform.dsdx();
+    msg.body.motion.dtdxRaw = rawTransform.dtdx();
+    msg.body.motion.dtdyRaw = rawTransform.dtdy();
+    msg.body.motion.dsdyRaw = rawTransform.dsdy();
+    msg.body.motion.txRaw = rawTransform.tx();
+    msg.body.motion.tyRaw = rawTransform.ty();
     msg.body.motion.downTime = downTime;
     msg.body.motion.eventTime = eventTime;
     msg.body.motion.pointerCount = pointerCount;
@@ -1391,6 +1396,10 @@
     ui::Transform transform;
     transform.set({msg->body.motion.dsdx, msg->body.motion.dtdx, msg->body.motion.tx,
                    msg->body.motion.dtdy, msg->body.motion.dsdy, msg->body.motion.ty, 0, 0, 1});
+    ui::Transform displayTransform;
+    displayTransform.set({msg->body.motion.dsdxRaw, msg->body.motion.dtdxRaw,
+                          msg->body.motion.txRaw, msg->body.motion.dtdyRaw,
+                          msg->body.motion.dsdyRaw, msg->body.motion.tyRaw, 0, 0, 1});
     event->initialize(msg->body.motion.eventId, msg->body.motion.deviceId, msg->body.motion.source,
                       msg->body.motion.displayId, msg->body.motion.hmac, msg->body.motion.action,
                       msg->body.motion.actionButton, msg->body.motion.flags,
@@ -1398,9 +1407,8 @@
                       msg->body.motion.buttonState, msg->body.motion.classification, transform,
                       msg->body.motion.xPrecision, msg->body.motion.yPrecision,
                       msg->body.motion.xCursorPosition, msg->body.motion.yCursorPosition,
-                      msg->body.motion.displayOrientation, msg->body.motion.displayWidth,
-                      msg->body.motion.displayHeight, msg->body.motion.downTime,
-                      msg->body.motion.eventTime, pointerCount, pointerProperties, pointerCoords);
+                      displayTransform, msg->body.motion.downTime, msg->body.motion.eventTime,
+                      pointerCount, pointerProperties, pointerCoords);
 }
 
 void InputConsumer::initializeTouchModeEvent(TouchModeEvent* event, const InputMessage* msg) {
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index b1ef753..7e7dfd5 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -226,11 +226,16 @@
     static constexpr float Y_SCALE = 3.0;
     static constexpr float X_OFFSET = 1;
     static constexpr float Y_OFFSET = 1.1;
+    static constexpr float RAW_X_SCALE = 4.0;
+    static constexpr float RAW_Y_SCALE = -5.0;
+    static constexpr float RAW_X_OFFSET = 12;
+    static constexpr float RAW_Y_OFFSET = -41.1;
 
     static const std::optional<bool> INITIAL_PER_WINDOW_INPUT_ROTATION_FLAG_VALUE;
 
     int32_t mId;
     ui::Transform mTransform;
+    ui::Transform mRawTransform;
 
     void SetUp() override;
     void TearDown() override;
@@ -259,6 +264,7 @@
 void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
     mId = InputEvent::nextId();
     mTransform.set({X_SCALE, 0, X_OFFSET, 0, Y_SCALE, Y_OFFSET, 0, 0, 1});
+    mRawTransform.set({RAW_X_SCALE, 0, RAW_X_OFFSET, 0, RAW_Y_SCALE, RAW_Y_OFFSET, 0, 0, 1});
 
     PointerProperties pointerProperties[2];
     pointerProperties[0].clear();
@@ -294,9 +300,8 @@
                       AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
                       MotionClassification::NONE, mTransform, 2.0f, 2.1f,
                       AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                      ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
-                      ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2, pointerProperties,
-                      pointerCoords);
+                      mRawTransform, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2,
+                      pointerProperties, pointerCoords);
 
     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
@@ -373,39 +378,37 @@
     ASSERT_EQ(ARBITRARY_EVENT_TIME + 1, event->getHistoricalEventTime(1));
     ASSERT_EQ(ARBITRARY_EVENT_TIME + 2, event->getEventTime());
 
-    ASSERT_EQ(11, event->getHistoricalRawPointerCoords(0, 0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(21, event->getHistoricalRawPointerCoords(1, 0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(111, event->getHistoricalRawPointerCoords(0, 1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(121, event->getHistoricalRawPointerCoords(1, 1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(211, event->getRawPointerCoords(0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(221, event->getRawPointerCoords(1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(11, event->getHistoricalRawPointerCoords(0, 0)->getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(21, event->getHistoricalRawPointerCoords(1, 0)->getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(111, event->getHistoricalRawPointerCoords(0, 1)->getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(121, event->getHistoricalRawPointerCoords(1, 1)->getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(211, event->getRawPointerCoords(0)->getAxisValue(AMOTION_EVENT_AXIS_Y));
+    ASSERT_EQ(221, event->getRawPointerCoords(1)->getAxisValue(AMOTION_EVENT_AXIS_Y));
 
-    ASSERT_EQ(11, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 0));
-    ASSERT_EQ(21, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 0));
-    ASSERT_EQ(111, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 1));
-    ASSERT_EQ(121, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 1));
-    ASSERT_EQ(211, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 0));
-    ASSERT_EQ(221, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 1));
+    ASSERT_EQ(RAW_Y_OFFSET + 11 * RAW_Y_SCALE,
+              event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 0));
+    ASSERT_EQ(RAW_Y_OFFSET + 21 * RAW_Y_SCALE,
+              event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 0));
+    ASSERT_EQ(RAW_Y_OFFSET + 111 * RAW_Y_SCALE,
+              event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 1));
+    ASSERT_EQ(RAW_Y_OFFSET + 121 * RAW_Y_SCALE,
+              event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 1));
+    ASSERT_EQ(RAW_Y_OFFSET + 211 * RAW_Y_SCALE, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 0));
+    ASSERT_EQ(RAW_Y_OFFSET + 221 * RAW_Y_SCALE, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 1));
 
-    ASSERT_EQ(10, event->getHistoricalRawX(0, 0));
-    ASSERT_EQ(20, event->getHistoricalRawX(1, 0));
-    ASSERT_EQ(110, event->getHistoricalRawX(0, 1));
-    ASSERT_EQ(120, event->getHistoricalRawX(1, 1));
-    ASSERT_EQ(210, event->getRawX(0));
-    ASSERT_EQ(220, event->getRawX(1));
+    ASSERT_EQ(RAW_X_OFFSET + 10 * RAW_X_SCALE, event->getHistoricalRawX(0, 0));
+    ASSERT_EQ(RAW_X_OFFSET + 20 * RAW_X_SCALE, event->getHistoricalRawX(1, 0));
+    ASSERT_EQ(RAW_X_OFFSET + 110 * RAW_X_SCALE, event->getHistoricalRawX(0, 1));
+    ASSERT_EQ(RAW_X_OFFSET + 120 * RAW_X_SCALE, event->getHistoricalRawX(1, 1));
+    ASSERT_EQ(RAW_X_OFFSET + 210 * RAW_X_SCALE, event->getRawX(0));
+    ASSERT_EQ(RAW_X_OFFSET + 220 * RAW_X_SCALE, event->getRawX(1));
 
-    ASSERT_EQ(11, event->getHistoricalRawY(0, 0));
-    ASSERT_EQ(21, event->getHistoricalRawY(1, 0));
-    ASSERT_EQ(111, event->getHistoricalRawY(0, 1));
-    ASSERT_EQ(121, event->getHistoricalRawY(1, 1));
-    ASSERT_EQ(211, event->getRawY(0));
-    ASSERT_EQ(221, event->getRawY(1));
+    ASSERT_EQ(RAW_Y_OFFSET + 11 * RAW_Y_SCALE, event->getHistoricalRawY(0, 0));
+    ASSERT_EQ(RAW_Y_OFFSET + 21 * RAW_Y_SCALE, event->getHistoricalRawY(1, 0));
+    ASSERT_EQ(RAW_Y_OFFSET + 111 * RAW_Y_SCALE, event->getHistoricalRawY(0, 1));
+    ASSERT_EQ(RAW_Y_OFFSET + 121 * RAW_Y_SCALE, event->getHistoricalRawY(1, 1));
+    ASSERT_EQ(RAW_Y_OFFSET + 211 * RAW_Y_SCALE, event->getRawY(0));
+    ASSERT_EQ(RAW_Y_OFFSET + 221 * RAW_Y_SCALE, event->getRawY(1));
 
     ASSERT_EQ(X_OFFSET + 10 * X_SCALE, event->getHistoricalX(0, 0));
     ASSERT_EQ(X_OFFSET + 20 * X_SCALE, event->getHistoricalX(1, 0));
@@ -543,8 +546,8 @@
     ASSERT_EQ(X_OFFSET * 2, event.getXOffset());
     ASSERT_EQ(Y_OFFSET * 2, event.getYOffset());
 
-    ASSERT_EQ(210 * 2, event.getRawX(0));
-    ASSERT_EQ(211 * 2, event.getRawY(0));
+    ASSERT_EQ((RAW_X_OFFSET + 210 * RAW_X_SCALE) * 2, event.getRawX(0));
+    ASSERT_EQ((RAW_Y_OFFSET + 211 * RAW_Y_SCALE) * 2, event.getRawY(0));
     ASSERT_EQ((X_OFFSET + 210 * X_SCALE) * 2, event.getX(0));
     ASSERT_EQ((Y_OFFSET + 211 * Y_SCALE) * 2, event.getY(0));
     ASSERT_EQ(212, event.getPressure(0));
@@ -592,10 +595,10 @@
     // The geometrical representation is irrelevant to the test, it's just easy to generate
     // and check rotation.  We set the orientation to the same angle.
     // Coordinate system: down is increasing Y, right is increasing X.
-    const float PI_180 = float(M_PI / 180);
-    const float RADIUS = 10;
-    const float ARC = 36;
-    const float ROTATION = ARC * 2;
+    static constexpr float PI_180 = float(M_PI / 180);
+    static constexpr float RADIUS = 10;
+    static constexpr float ARC = 36;
+    static constexpr float ROTATION = ARC * 2;
 
     const size_t pointerCount = 11;
     PointerProperties pointerProperties[pointerCount];
@@ -616,9 +619,8 @@
                      AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
                      MotionClassification::NONE, identityTransform, 0 /*xPrecision*/,
                      0 /*yPrecision*/, 3 + RADIUS /*xCursorPosition*/, 2 /*yCursorPosition*/,
-                     ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
-                     0 /*downTime*/, 0 /*eventTime*/, pointerCount, pointerProperties,
-                     pointerCoords);
+                     identityTransform, 0 /*downTime*/, 0 /*eventTime*/, pointerCount,
+                     pointerProperties, pointerCoords);
     float originalRawX = 0 + 3;
     float originalRawY = -RADIUS + 2;
 
@@ -661,7 +663,7 @@
 
 MotionEvent createTouchDownEvent(float x, float y, float dx, float dy,
                                  const ui::Transform& transform,
-                                 uint32_t displayOrientation = ui::Transform::ROT_0) {
+                                 const ui::Transform& rawTransform) {
     std::vector<PointerProperties> pointerProperties;
     pointerProperties.push_back(PointerProperties{/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER});
     std::vector<PointerCoords> pointerCoords;
@@ -677,19 +679,18 @@
                      /* actionButton */ 0, /* flags */ 0, /* edgeFlags */ 0, AMETA_NONE,
                      /* buttonState */ 0, MotionClassification::NONE, transform,
                      /* xPrecision */ 0, /* yPrecision */ 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, displayOrientation,
-                     /* displayWidth */ 400,
-                     /* displayHeight */ 800, eventTime, eventTime, pointerCoords.size(),
-                     pointerProperties.data(), pointerCoords.data());
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, rawTransform, eventTime, eventTime,
+                     pointerCoords.size(), pointerProperties.data(), pointerCoords.data());
     return event;
 }
 
 TEST_F(MotionEventTest, ApplyTransform) {
     // Create a rotate-90 transform with an offset (like a window which isn't fullscreen).
     ui::Transform identity;
-    ui::Transform xform(ui::Transform::ROT_90, 800, 400);
-    xform.set(xform.tx() + 20, xform.ty() + 40);
-    MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_90);
+    ui::Transform transform(ui::Transform::ROT_90, 800, 400);
+    transform.set(transform.tx() + 20, transform.ty() + 40);
+    ui::Transform rawTransform(ui::Transform::ROT_90, 800, 400);
+    MotionEvent event = createTouchDownEvent(60, 100, 42, 96, transform, rawTransform);
     ASSERT_EQ(700, event.getRawX(0));
     ASSERT_EQ(60, event.getRawY(0));
     ASSERT_NE(event.getRawX(0), event.getX(0));
@@ -698,10 +699,10 @@
     ASSERT_EQ(-96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
     ASSERT_EQ(42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
 
-    MotionEvent changedEvent = createTouchDownEvent(60, 100, 42, 96, identity);
-    const std::array<float, 9> rowMajor{xform[0][0], xform[1][0], xform[2][0],
-                                        xform[0][1], xform[1][1], xform[2][1],
-                                        xform[0][2], xform[1][2], xform[2][2]};
+    MotionEvent changedEvent = createTouchDownEvent(60, 100, 42, 96, identity, identity);
+    const std::array<float, 9> rowMajor{transform[0][0], transform[1][0], transform[2][0],
+                                        transform[0][1], transform[1][1], transform[2][1],
+                                        transform[0][2], transform[1][2], transform[2][2]};
     changedEvent.applyTransform(rowMajor);
 
     // transformContent effectively rotates the raw coordinates, so those should now include
@@ -727,9 +728,9 @@
                                                  AINPUT_SOURCE_JOYSTICK};
     for (uint32_t source : NON_POINTER_SOURCES) {
         // Create a rotate-90 transform with an offset (like a window which isn't fullscreen).
-        ui::Transform xform(ui::Transform::ROT_90, 800, 400);
-        xform.set(xform.tx() + 20, xform.ty() + 40);
-        MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_90);
+        ui::Transform transform(ui::Transform::ROT_90, 800, 400);
+        transform.set(transform.tx() + 20, transform.ty() + 40);
+        MotionEvent event = createTouchDownEvent(60, 100, 42, 96, transform, transform);
         event.setSource(source);
 
         // Since this event comes from a non-pointer source, it should include rotation but not
@@ -741,72 +742,34 @@
     }
 }
 
-TEST_F(MotionEventTest, RawCompatTransform) {
-    {
-        // Make sure raw is raw regardless of transform translation.
-        ui::Transform xform;
-        xform.set(20, 40);
-        MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform);
-        ASSERT_EQ(60, event.getRawX(0));
-        ASSERT_EQ(100, event.getRawY(0));
-        ASSERT_NE(event.getRawX(0), event.getX(0));
-        ASSERT_NE(event.getRawY(0), event.getY(0));
-        // Relative values should not be modified.
-        ASSERT_EQ(42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
-        ASSERT_EQ(96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
-    }
+TEST_F(MotionEventTest, AxesAreCorrectlyTransformed) {
+    const ui::Transform identity;
+    ui::Transform transform;
+    transform.set({1.1, -2.2, 3.3, -4.4, 5.5, -6.6, 0, 0, 1});
+    ui::Transform rawTransform;
+    rawTransform.set({-6.6, 5.5, -4.4, 3.3, -2.2, 1.1, 0, 0, 1});
+    auto transformWithoutTranslation = [](const ui::Transform& t, float x, float y) {
+        auto newPoint = t.transform(x, y);
+        auto newOrigin = t.transform(0, 0);
+        return newPoint - newOrigin;
+    };
 
-    // Next check that getRaw contains rotation (for compatibility) but otherwise is still
-    // "Screen-space". The following tests check all 3 rotations.
-    {
-        // Create a rotate-90 transform with an offset (like a window which isn't fullscreen).
-        ui::Transform xform(ui::Transform::ROT_90, 800, 400);
-        xform.set(xform.tx() + 20, xform.ty() + 40);
-        MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_90);
-        ASSERT_EQ(700, event.getRawX(0));
-        ASSERT_EQ(60, event.getRawY(0));
-        ASSERT_NE(event.getRawX(0), event.getX(0));
-        ASSERT_NE(event.getRawY(0), event.getY(0));
-        // Relative values should be rotated but not translated.
-        ASSERT_EQ(-96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
-        ASSERT_EQ(42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
-    }
+    const MotionEvent event = createTouchDownEvent(60, 100, 42, 96, transform, rawTransform);
 
-    {
-        // Same as above, but check rotate-180.
-        ui::Transform xform(ui::Transform::ROT_180, 400, 800);
-        xform.set(xform.tx() + 20, xform.ty() + 40);
-        MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_180);
-        ASSERT_EQ(340, event.getRawX(0));
-        ASSERT_EQ(700, event.getRawY(0));
-        // Relative values should be rotated but not translated.
-        ASSERT_EQ(-42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
-        ASSERT_EQ(-96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
-    }
+    // The x and y axes should have the window transform applied.
+    const auto newPoint = transform.transform(60, 100);
+    ASSERT_EQ(newPoint.x, event.getX(0));
+    ASSERT_EQ(newPoint.y, event.getY(0));
 
-    {
-        // Same as above, but check rotate-270.
-        ui::Transform xform(ui::Transform::ROT_270, 800, 400);
-        xform.set(xform.tx() + 20, xform.ty() + 40);
-        MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_270);
-        ASSERT_EQ(100, event.getRawX(0));
-        ASSERT_EQ(340, event.getRawY(0));
-        // Relative values should be rotated but not translated.
-        ASSERT_EQ(96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
-        ASSERT_EQ(-42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
-    }
+    // The raw values should have the display transform applied.
+    const auto raw = rawTransform.transform(60, 100);
+    ASSERT_EQ(raw.x, event.getRawX(0));
+    ASSERT_EQ(raw.y, event.getRawY(0));
 
-    {
-        // Finally, check that raw isn't effected by transform
-        ui::Transform xform(ui::Transform::ROT_270, 800, 400);
-        xform.set(xform.tx() + 20, xform.ty() + 40);
-        MotionEvent event = createTouchDownEvent(60, 100, 42, 96, xform, ui::Transform::ROT_90);
-        ASSERT_EQ(700, event.getRawX(0));
-        ASSERT_EQ(60, event.getRawY(0));
-        // Relative values should be rotated but not translated.
-        ASSERT_EQ(96, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
-        ASSERT_EQ(-42, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
-    }
+    // Relative values should have the window transform applied without any translation.
+    const auto rel = transformWithoutTranslation(transform, 42, 96);
+    ASSERT_EQ(rel.x, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, 0));
+    ASSERT_EQ(rel.y, event.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, 0));
 }
 
 TEST_F(MotionEventTest, Initialize_SetsClassification) {
@@ -832,8 +795,7 @@
                          DISPLAY_ID, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0,
                          AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0, classification,
                          identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                         AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
-                         INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, 0 /*downTime*/,
+                         AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, 0 /*downTime*/,
                          0 /*eventTime*/, pointerCount, pointerProperties, pointerCoords);
         ASSERT_EQ(classification, event.getClassification());
     }
@@ -854,9 +816,9 @@
     event.initialize(InputEvent::nextId(), 0 /*deviceId*/, AINPUT_SOURCE_MOUSE, DISPLAY_ID,
                      INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0, AMOTION_EVENT_EDGE_FLAG_NONE,
                      AMETA_NONE, 0, MotionClassification::NONE, identityTransform, 0, 0,
-                     280 /*xCursorPosition*/, 540 /*yCursorPosition*/, ui::Transform::ROT_0,
-                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, 0 /*downTime*/, 0 /*eventTime*/,
-                     pointerCount, pointerProperties, pointerCoords);
+                     280 /*xCursorPosition*/, 540 /*yCursorPosition*/, identityTransform,
+                     0 /*downTime*/, 0 /*eventTime*/, pointerCount, pointerProperties,
+                     pointerCoords);
     event.offsetLocation(20, 60);
     ASSERT_EQ(280, event.getRawXCursorPosition());
     ASSERT_EQ(540, event.getRawYCursorPosition());
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
index 8db5bf1..d09f2ac 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -160,13 +160,14 @@
     constexpr float yScale = 3;
     constexpr float xOffset = -10;
     constexpr float yOffset = -20;
+    constexpr float rawXScale = 4;
+    constexpr float rawYScale = -5;
+    constexpr float rawXOffset = -11;
+    constexpr float rawYOffset = 42;
     constexpr float xPrecision = 0.25;
     constexpr float yPrecision = 0.5;
     constexpr float xCursorPosition = 1.3;
     constexpr float yCursorPosition = 50.6;
-    constexpr uint32_t displayOrientation = ui::Transform::ROT_0;
-    constexpr int32_t displayWidth = 1000;
-    constexpr int32_t displayHeight = 2000;
     constexpr nsecs_t downTime = 3;
     constexpr size_t pointerCount = 3;
     constexpr nsecs_t eventTime = 4;
@@ -192,12 +193,14 @@
 
     ui::Transform transform;
     transform.set({xScale, 0, xOffset, 0, yScale, yOffset, 0, 0, 1});
+    ui::Transform rawTransform;
+    rawTransform.set({rawXScale, 0, rawXOffset, 0, rawYScale, rawYOffset, 0, 0, 1});
     status = mPublisher->publishMotionEvent(seq, eventId, deviceId, source, displayId, hmac, action,
                                             actionButton, flags, edgeFlags, metaState, buttonState,
                                             classification, transform, xPrecision, yPrecision,
-                                            xCursorPosition, yCursorPosition, displayOrientation,
-                                            displayWidth, displayHeight, downTime, eventTime,
-                                            pointerCount, pointerProperties, pointerCoords);
+                                            xCursorPosition, yCursorPosition, rawTransform,
+                                            downTime, eventTime, pointerCount, pointerProperties,
+                                            pointerCoords);
     ASSERT_EQ(OK, status)
             << "publisher publishMotionEvent should return OK";
 
@@ -234,9 +237,7 @@
     EXPECT_EQ(yCursorPosition, motionEvent->getRawYCursorPosition());
     EXPECT_EQ(xCursorPosition * xScale + xOffset, motionEvent->getXCursorPosition());
     EXPECT_EQ(yCursorPosition * yScale + yOffset, motionEvent->getYCursorPosition());
-    EXPECT_EQ(displayOrientation, motionEvent->getDisplayOrientation());
-    EXPECT_EQ(displayWidth, motionEvent->getDisplaySize().x);
-    EXPECT_EQ(displayHeight, motionEvent->getDisplaySize().y);
+    EXPECT_EQ(rawTransform, motionEvent->getRawTransform());
     EXPECT_EQ(downTime, motionEvent->getDownTime());
     EXPECT_EQ(eventTime, motionEvent->getEventTime());
     EXPECT_EQ(pointerCount, motionEvent->getPointerCount());
@@ -247,28 +248,18 @@
         EXPECT_EQ(pointerProperties[i].id, motionEvent->getPointerId(i));
         EXPECT_EQ(pointerProperties[i].toolType, motionEvent->getToolType(i));
 
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
-                motionEvent->getRawX(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
-                motionEvent->getRawY(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X) * xScale + xOffset,
-                  motionEvent->getX(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y) * yScale + yOffset,
-                  motionEvent->getY(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
-                motionEvent->getPressure(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
-                motionEvent->getSize(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
-                motionEvent->getTouchMajor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
-                motionEvent->getTouchMinor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
-                motionEvent->getToolMajor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
-                motionEvent->getToolMinor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
-                motionEvent->getOrientation(i));
+        const auto& pc = pointerCoords[i];
+        EXPECT_EQ(pc.getX() * rawXScale + rawXOffset, motionEvent->getRawX(i));
+        EXPECT_EQ(pc.getY() * rawYScale + rawYOffset, motionEvent->getRawY(i));
+        EXPECT_EQ(pc.getX() * xScale + xOffset, motionEvent->getX(i));
+        EXPECT_EQ(pc.getY() * yScale + yOffset, motionEvent->getY(i));
+        EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), motionEvent->getPressure(i));
+        EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_SIZE), motionEvent->getSize(i));
+        EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), motionEvent->getTouchMajor(i));
+        EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), motionEvent->getTouchMinor(i));
+        EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), motionEvent->getToolMajor(i));
+        EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), motionEvent->getToolMinor(i));
+        EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), motionEvent->getOrientation(i));
     }
 
     status = mConsumer->sendFinishedSignal(seq, false);
@@ -505,12 +496,12 @@
     }
 
     ui::Transform identityTransform;
-    status = mPublisher->publishMotionEvent(0, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
-                                            0, 0, 0, MotionClassification::NONE, identityTransform,
-                                            0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                                            AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                                            ui::Transform::ROT_0, 0, 0, 0, 0, pointerCount,
-                                            pointerProperties, pointerCoords);
+    status =
+            mPublisher->publishMotionEvent(0, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
+                                           0, 0, 0, MotionClassification::NONE, identityTransform,
+                                           0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                                           AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform,
+                                           0, 0, pointerCount, pointerProperties, pointerCoords);
     ASSERT_EQ(BAD_VALUE, status)
             << "publisher publishMotionEvent should return BAD_VALUE";
 }
@@ -522,12 +513,12 @@
     PointerCoords pointerCoords[pointerCount];
 
     ui::Transform identityTransform;
-    status = mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
-                                            0, 0, 0, MotionClassification::NONE, identityTransform,
-                                            0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                                            AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                                            ui::Transform::ROT_0, 0, 0, 0, 0, pointerCount,
-                                            pointerProperties, pointerCoords);
+    status =
+            mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
+                                           0, 0, 0, MotionClassification::NONE, identityTransform,
+                                           0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                                           AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform,
+                                           0, 0, pointerCount, pointerProperties, pointerCoords);
     ASSERT_EQ(BAD_VALUE, status)
             << "publisher publishMotionEvent should return BAD_VALUE";
 }
@@ -544,12 +535,12 @@
     }
 
     ui::Transform identityTransform;
-    status = mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
-                                            0, 0, 0, MotionClassification::NONE, identityTransform,
-                                            0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                                            AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                                            ui::Transform::ROT_0, 0, 0, 0, 0, pointerCount,
-                                            pointerProperties, pointerCoords);
+    status =
+            mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0, 0, INVALID_HMAC, 0, 0, 0,
+                                           0, 0, 0, MotionClassification::NONE, identityTransform,
+                                           0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                                           AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform,
+                                           0, 0, pointerCount, pointerProperties, pointerCoords);
     ASSERT_EQ(BAD_VALUE, status)
             << "publisher publishMotionEvent should return BAD_VALUE";
 }
diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp
index 18289a5..2f88704 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -49,7 +49,7 @@
   CHECK_OFFSET(InputMessage::Body::Key, downTime, 88);
 
   CHECK_OFFSET(InputMessage::Body::Motion, eventId, 0);
-  CHECK_OFFSET(InputMessage::Body::Motion, empty1, 4);
+  CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 4);
   CHECK_OFFSET(InputMessage::Body::Motion, eventTime, 8);
   CHECK_OFFSET(InputMessage::Body::Motion, deviceId, 16);
   CHECK_OFFSET(InputMessage::Body::Motion, source, 20);
@@ -74,11 +74,13 @@
   CHECK_OFFSET(InputMessage::Body::Motion, yPrecision, 124);
   CHECK_OFFSET(InputMessage::Body::Motion, xCursorPosition, 128);
   CHECK_OFFSET(InputMessage::Body::Motion, yCursorPosition, 132);
-  CHECK_OFFSET(InputMessage::Body::Motion, displayOrientation, 136);
-  CHECK_OFFSET(InputMessage::Body::Motion, displayWidth, 140);
-  CHECK_OFFSET(InputMessage::Body::Motion, displayHeight, 144);
-  CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 148);
-  CHECK_OFFSET(InputMessage::Body::Motion, pointers, 152);
+  CHECK_OFFSET(InputMessage::Body::Motion, dsdxRaw, 136);
+  CHECK_OFFSET(InputMessage::Body::Motion, dtdxRaw, 140);
+  CHECK_OFFSET(InputMessage::Body::Motion, dtdyRaw, 144);
+  CHECK_OFFSET(InputMessage::Body::Motion, dsdyRaw, 148);
+  CHECK_OFFSET(InputMessage::Body::Motion, txRaw, 152);
+  CHECK_OFFSET(InputMessage::Body::Motion, tyRaw, 156);
+  CHECK_OFFSET(InputMessage::Body::Motion, pointers, 160);
 
   CHECK_OFFSET(InputMessage::Body::Focus, eventId, 0);
   CHECK_OFFSET(InputMessage::Body::Focus, hasFocus, 4);
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index 13e2b02..3039362 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -184,8 +184,7 @@
                          AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
                          MotionClassification::NONE, identityTransform, 0 /*xPrecision*/,
                          0 /*yPrecision*/, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                         AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
-                         INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, 0 /*downTime*/,
+                         AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, 0 /*downTime*/,
                          entry.eventTime.count(), pointerCount, properties, coords);
 
         events.emplace_back(event);
diff --git a/libs/input/tests/VerifiedInputEvent_test.cpp b/libs/input/tests/VerifiedInputEvent_test.cpp
index b29c9a4..f2b59ea 100644
--- a/libs/input/tests/VerifiedInputEvent_test.cpp
+++ b/libs/input/tests/VerifiedInputEvent_test.cpp
@@ -43,12 +43,12 @@
 
     ui::Transform transform;
     transform.set({2, 0, 4, 0, 3, 5, 0, 0, 1});
+    ui::Transform identity;
     event.initialize(InputEvent::nextId(), 0 /*deviceId*/, AINPUT_SOURCE_MOUSE, ADISPLAY_ID_DEFAULT,
                      INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0 /*actionButton*/, flags,
                      AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
                      MotionClassification::NONE, transform, 0.1 /*xPrecision*/, 0.2 /*yPrecision*/,
-                     280 /*xCursorPosition*/, 540 /*yCursorPosition*/, ui::Transform::ROT_0,
-                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, 100 /*downTime*/,
+                     280 /*xCursorPosition*/, 540 /*yCursorPosition*/, identity, 100 /*downTime*/,
                      200 /*eventTime*/, pointerCount, pointerProperties, pointerCoords);
     return event;
 }
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index 6ce0313..68d25f9 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -236,8 +236,8 @@
                      /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
                      identityTransform, /* xPrecision */ 0,
                      /* yPrecision */ 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
-                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, currentTime, currentTime,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, currentTime,
+                     currentTime,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     return event;
 }
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index 571c126..bcb0071 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -309,15 +309,14 @@
 volatile int32_t DispatchEntry::sNextSeqAtomic;
 
 DispatchEntry::DispatchEntry(std::shared_ptr<EventEntry> eventEntry, int32_t targetFlags,
-                             ui::Transform transform, float globalScaleFactor,
-                             uint32_t displayOrientation, int2 displaySize)
+                             const ui::Transform& transform, const ui::Transform& rawTransform,
+                             float globalScaleFactor)
       : seq(nextSeq()),
         eventEntry(std::move(eventEntry)),
         targetFlags(targetFlags),
         transform(transform),
+        rawTransform(rawTransform),
         globalScaleFactor(globalScaleFactor),
-        displayOrientation(displayOrientation),
-        displaySize(displaySize),
         deliveryTime(0),
         resolvedAction(0),
         resolvedFlags(0) {}
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index 5365a78..7a121ce 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -226,9 +226,8 @@
     std::shared_ptr<EventEntry> eventEntry; // the event to dispatch
     int32_t targetFlags;
     ui::Transform transform;
+    ui::Transform rawTransform;
     float globalScaleFactor;
-    uint32_t displayOrientation;
-    int2 displaySize;
     // Both deliveryTime and timeoutTime are only populated when the entry is sent to the app,
     // and will be undefined before that.
     nsecs_t deliveryTime; // time when the event was actually delivered
@@ -241,8 +240,8 @@
     int32_t resolvedFlags;
 
     DispatchEntry(std::shared_ptr<EventEntry> eventEntry, int32_t targetFlags,
-                  ui::Transform transform, float globalScaleFactor, uint32_t displayOrientation,
-                  int2 displaySize);
+                  const ui::Transform& transform, const ui::Transform& rawTransform,
+                  float globalScaleFactor);
 
     inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; }
 
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index da3e237..22d2e9a 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -346,18 +346,15 @@
             // Use identity transform for joystick and position-based (touchpad) events because they
             // don't depend on the window transform.
             return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
-                                                   1.0f /*globalScaleFactor*/,
-                                                   inputTarget.displayOrientation,
-                                                   inputTarget.displaySize);
+                                                   identityTransform, 1.0f /*globalScaleFactor*/);
         }
     }
 
     if (inputTarget.useDefaultPointerTransform()) {
         const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
         return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
-                                               inputTarget.globalScaleFactor,
-                                               inputTarget.displayOrientation,
-                                               inputTarget.displaySize);
+                                               inputTarget.displayTransform,
+                                               inputTarget.globalScaleFactor);
     }
 
     ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
@@ -408,9 +405,8 @@
 
     std::unique_ptr<DispatchEntry> dispatchEntry =
             std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
-                                            firstPointerTransform, inputTarget.globalScaleFactor,
-                                            inputTarget.displayOrientation,
-                                            inputTarget.displaySize);
+                                            firstPointerTransform, inputTarget.displayTransform,
+                                            inputTarget.globalScaleFactor);
     return dispatchEntry;
 }
 
@@ -2347,7 +2343,7 @@
 
     for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
         addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
-                                  touchedMonitor.yOffset, inputTargets);
+                                  touchedMonitor.yOffset, displayId, inputTargets);
     }
 
     // Drop the outside or hover touch windows since we will not care about them
@@ -2526,9 +2522,7 @@
         inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
         const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
         if (displayInfoIt != mDisplayInfos.end()) {
-            const auto& displayInfo = displayInfoIt->second;
-            inputTarget.displayOrientation = displayInfo.transform.getOrientation();
-            inputTarget.displaySize = int2(displayInfo.logicalWidth, displayInfo.logicalHeight);
+            inputTarget.displayTransform = displayInfoIt->second.transform;
         } else {
             ALOGI_IF(isPerWindowInputRotationEnabled(),
                      "DisplayInfo not found for window on display: %d", windowInfo->displayId);
@@ -2552,19 +2546,38 @@
     if (it != mGlobalMonitorsByDisplay.end()) {
         const std::vector<Monitor>& monitors = it->second;
         for (const Monitor& monitor : monitors) {
-            addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
+            addMonitoringTargetLocked(monitor, xOffset, yOffset, displayId, inputTargets);
         }
     }
 }
 
 void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
-                                                float yOffset,
+                                                float yOffset, int32_t displayId,
                                                 std::vector<InputTarget>& inputTargets) {
     InputTarget target;
     target.inputChannel = monitor.inputChannel;
     target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
-    ui::Transform t;
-    t.set(xOffset, yOffset);
+    ui::Transform t = ui::Transform(xOffset, yOffset);
+    if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
+        // Input monitors always get un-rotated display coordinates. We undo the display
+        // rotation that is present in the display transform so that display rotation is not
+        // applied to these input targets.
+        const auto& displayInfo = it->second;
+        int32_t width = displayInfo.logicalWidth;
+        int32_t height = displayInfo.logicalHeight;
+        const auto orientation = displayInfo.transform.getOrientation();
+        uint32_t inverseOrientation = orientation;
+        if (orientation == ui::Transform::ROT_90) {
+            inverseOrientation = ui::Transform::ROT_270;
+            std::swap(width, height);
+        } else if (orientation == ui::Transform::ROT_270) {
+            inverseOrientation = ui::Transform::ROT_90;
+            std::swap(width, height);
+        }
+        target.displayTransform =
+                ui::Transform(inverseOrientation, width, height) * displayInfo.transform;
+        t = t * target.displayTransform;
+    }
     target.setDefaultPointerTransform(t);
     inputTargets.push_back(target);
 }
@@ -3250,9 +3263,7 @@
                                                      motionEntry.xPrecision, motionEntry.yPrecision,
                                                      motionEntry.xCursorPosition,
                                                      motionEntry.yCursorPosition,
-                                                     dispatchEntry->displayOrientation,
-                                                     dispatchEntry->displaySize.x,
-                                                     dispatchEntry->displaySize.y,
+                                                     dispatchEntry->rawTransform,
                                                      motionEntry.downTime, motionEntry.eventTime,
                                                      motionEntry.pointerCount,
                                                      motionEntry.pointerProperties, usingCoords);
@@ -3981,14 +3992,14 @@
             mLock.unlock();
 
             MotionEvent event;
-            ui::Transform transform;
+            ui::Transform identityTransform;
             event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
                              args->action, args->actionButton, args->flags, args->edgeFlags,
-                             args->metaState, args->buttonState, args->classification, transform,
-                             args->xPrecision, args->yPrecision, args->xCursorPosition,
-                             args->yCursorPosition, ui::Transform::ROT_0, INVALID_DISPLAY_SIZE,
-                             INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
-                             args->pointerCount, args->pointerProperties, args->pointerCoords);
+                             args->metaState, args->buttonState, args->classification,
+                             identityTransform, args->xPrecision, args->yPrecision,
+                             args->xCursorPosition, args->yCursorPosition, identityTransform,
+                             args->downTime, args->eventTime, args->pointerCount,
+                             args->pointerProperties, args->pointerCoords);
 
             policyFlags |= POLICY_FLAG_FILTERED;
             if (!mPolicy->filterInputEvent(&event, policyFlags)) {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 4f6d0d2..e9fe281 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -525,7 +525,8 @@
                                int32_t targetFlags, BitSet32 pointerIds,
                                std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
     void addMonitoringTargetLocked(const Monitor& monitor, float xOffset, float yOffset,
-                                   std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
+                                   int32_t displayId, std::vector<InputTarget>& inputTargets)
+            REQUIRES(mLock);
     void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId,
                                           float xOffset = 0, float yOffset = 0) REQUIRES(mLock);
     void pokeUserActivityLocked(const EventEntry& eventEntry) REQUIRES(mLock);
diff --git a/services/inputflinger/dispatcher/InputTarget.h b/services/inputflinger/dispatcher/InputTarget.h
index 7c463c8..5b76eee 100644
--- a/services/inputflinger/dispatcher/InputTarget.h
+++ b/services/inputflinger/dispatcher/InputTarget.h
@@ -101,11 +101,8 @@
     // (ignored for KeyEvents)
     float globalScaleFactor = 1.0f;
 
-    // Current display orientation
-    uint32_t displayOrientation = ui::Transform::ROT_0;
-
-    // Display-size in its natural rotation. Used for compatibility transform of raw coordinates.
-    int2 displaySize = {INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE};
+    // Current display transform. Used for compatibility for raw coordinates.
+    ui::Transform displayTransform;
 
     // The subset of pointer ids to include in motion events dispatched to this input target
     // if FLAG_SPLIT is set.
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 903f337..e9d45b2 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -542,8 +542,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
-                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, ARBITRARY_TIME,
+                     ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -556,8 +556,7 @@
                              (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
                      0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+                     identityTransform, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -569,8 +568,7 @@
                              (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
                      0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+                     identityTransform, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -583,8 +581,7 @@
                              (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
                      0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+                     identityTransform, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -596,8 +593,7 @@
                              (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
                      0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     ui::Transform::ROT_0, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
-                     ARBITRARY_TIME, ARBITRARY_TIME,
+                     identityTransform, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -608,8 +604,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
-                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, ARBITRARY_TIME,
+                     ARBITRARY_TIME,
                      /*pointerCount*/ 0, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -619,8 +615,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
-                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, ARBITRARY_TIME,
+                     ARBITRARY_TIME,
                      /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -632,8 +628,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
-                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, ARBITRARY_TIME,
+                     ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -644,8 +640,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
-                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, ARBITRARY_TIME,
+                     ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -658,8 +654,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
-                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, ARBITRARY_TIME,
+                     ARBITRARY_TIME,
                      /*pointerCount*/ 2, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -1296,9 +1292,8 @@
                          mAction, mActionButton, mFlags, /* edgeFlags */ 0, AMETA_NONE,
                          mButtonState, MotionClassification::NONE, identityTransform,
                          /* xPrecision */ 0, /* yPrecision */ 0, mRawXCursorPosition,
-                         mRawYCursorPosition, mDisplayOrientation, mDisplayWidth, mDisplayHeight,
-                         mEventTime, mEventTime, mPointers.size(), pointerProperties.data(),
-                         pointerCoords.data());
+                         mRawYCursorPosition, identityTransform, mEventTime, mEventTime,
+                         mPointers.size(), pointerProperties.data(), pointerCoords.data());
 
         return event;
     }
@@ -1313,9 +1308,6 @@
     int32_t mFlags{0};
     float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
     float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
-    uint32_t mDisplayOrientation{ui::Transform::ROT_0};
-    int32_t mDisplayWidth{INVALID_DISPLAY_SIZE};
-    int32_t mDisplayHeight{INVALID_DISPLAY_SIZE};
 
     std::vector<PointerBuilder> mPointers;
 };
@@ -3622,8 +3614,7 @@
                          DISPLAY_ID, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0,
                          AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0, MotionClassification::NONE,
                          identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                         AMOTION_EVENT_INVALID_CURSOR_POSITION, ui::Transform::ROT_0,
-                         0 /*INVALID_DISPLAY_SIZE*/, 0 /*INVALID_DISPLAY_SIZE*/, eventTime,
+                         AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, eventTime,
                          eventTime,
                          /*pointerCount*/ 1, pointerProperties, pointerCoords);