Merge changes from topic "revert-16336498-revert-16306432-revert-16295572-ORWQJPYRMQ-IQBEBXXQNX-CARGQZNFNA"

* changes:
  Revert "Reland "Input injection: Assume transformed values are i...""
  Revert "Reland "Remove x/y offset from MotionEntry""
diff --git a/include/input/Input.h b/include/input/Input.h
index 70c7909..29503af 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -382,6 +382,7 @@
     // window scale. The global scale will be applied to TOUCH/TOOL_MAJOR/MINOR
     // axes, however the window scaling will not.
     void scale(float globalScale, float windowXScale, float windowYScale);
+    void applyOffset(float xOffset, float yOffset);
 
     void transform(const ui::Transform& transform);
 
@@ -571,7 +572,7 @@
 
     inline float getYOffset() const { return mTransform.ty(); }
 
-    inline const ui::Transform& getTransform() const { return mTransform; }
+    inline ui::Transform getTransform() const { return mTransform; }
 
     int getSurfaceRotation() const;
 
@@ -589,7 +590,7 @@
 
     void setCursorPosition(float x, float y);
 
-    inline const ui::Transform& getRawTransform() const { return mRawTransform; }
+    ui::Transform getRawTransform() const { return mRawTransform; }
 
     static inline bool isValidCursorPosition(float x, float y) { return !isnan(x) && !isnan(y); }
 
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 349880c..44487c3 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -344,6 +344,11 @@
     scaleAxisValue(*this, AMOTION_EVENT_AXIS_RELATIVE_Y, windowYScale);
 }
 
+void PointerCoords::applyOffset(float xOffset, float yOffset) {
+    setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
+    setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
+}
+
 #ifdef __linux__
 status_t PointerCoords::readFromParcel(Parcel* parcel) {
     bits = parcel->readInt64();
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index d8636dd..f6bb6a6 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -214,7 +214,7 @@
                          int32_t edgeFlags, float xPrecision, float yPrecision,
                          float xCursorPosition, float yCursorPosition, nsecs_t downTime,
                          uint32_t pointerCount, const PointerProperties* pointerProperties,
-                         const PointerCoords* pointerCoords)
+                         const PointerCoords* pointerCoords, float xOffset, float yOffset)
       : EventEntry(id, Type::MOTION, eventTime, policyFlags),
         deviceId(deviceId),
         source(source),
@@ -235,6 +235,9 @@
     for (uint32_t i = 0; i < pointerCount; i++) {
         this->pointerProperties[i].copyFrom(pointerProperties[i]);
         this->pointerCoords[i].copyFrom(pointerCoords[i]);
+        if (xOffset || yOffset) {
+            this->pointerCoords[i].applyOffset(xOffset, yOffset);
+        }
     }
 }
 
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index 0f79296..477781a 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -184,7 +184,8 @@
                 int32_t metaState, int32_t buttonState, MotionClassification classification,
                 int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
                 float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
-                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
+                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
+                float xOffset, float yOffset);
     std::string getDescription() const override;
 
     ~MotionEntry() override;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index de4090c..c9397c3 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -378,7 +378,7 @@
                                           motionEntry.yPrecision, motionEntry.xCursorPosition,
                                           motionEntry.yCursorPosition, motionEntry.downTime,
                                           motionEntry.pointerCount, motionEntry.pointerProperties,
-                                          pointerCoords.data());
+                                          pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
 
     if (motionEntry.injectionState) {
         combinedMotionEntry->injectionState = motionEntry.injectionState;
@@ -506,6 +506,12 @@
     return true;
 }
 
+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;
+}
+
 // Returns true if the event type passed as argument represents a user activity.
 bool isUserActivityEvent(const EventEntry& eventEntry) {
     switch (eventEntry.type) {
@@ -3757,7 +3763,7 @@
                                           originalMotionEntry.xCursorPosition,
                                           originalMotionEntry.yCursorPosition,
                                           originalMotionEntry.downTime, splitPointerCount,
-                                          splitPointerProperties, splitPointerCoords);
+                                          splitPointerProperties, splitPointerCoords, 0, 0);
 
     if (originalMotionEntry.injectionState) {
         splitMotionEntry->injectionState = originalMotionEntry.injectionState;
@@ -3983,7 +3989,7 @@
                                               args->xPrecision, args->yPrecision,
                                               args->xCursorPosition, args->yCursorPosition,
                                               args->downTime, args->pointerCount,
-                                              args->pointerProperties, args->pointerCoords);
+                                              args->pointerProperties, args->pointerCoords, 0, 0);
 
         if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
             IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
@@ -4213,8 +4219,10 @@
                                                   motionEvent.getRawXCursorPosition(),
                                                   motionEvent.getRawYCursorPosition(),
                                                   motionEvent.getDownTime(), uint32_t(pointerCount),
-                                                  pointerProperties, samplePointerCoords);
-            transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
+                                                  pointerProperties, samplePointerCoords,
+                                                  motionEvent.getXOffset(),
+                                                  motionEvent.getYOffset());
+            transformMotionEntryForInjectionLocked(*injectedEntry);
             injectedEntries.push(std::move(injectedEntry));
             for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
                 sampleEventTimes += 1;
@@ -4233,9 +4241,9 @@
                                                       motionEvent.getRawYCursorPosition(),
                                                       motionEvent.getDownTime(),
                                                       uint32_t(pointerCount), pointerProperties,
-                                                      samplePointerCoords);
-                transformMotionEntryForInjectionLocked(*nextInjectedEntry,
-                                                       motionEvent.getTransform());
+                                                      samplePointerCoords, motionEvent.getXOffset(),
+                                                      motionEvent.getYOffset());
+                transformMotionEntryForInjectionLocked(*nextInjectedEntry);
                 injectedEntries.push(std::move(nextInjectedEntry));
             }
             break;
@@ -4399,28 +4407,35 @@
     }
 }
 
-void InputDispatcher::transformMotionEntryForInjectionLocked(
-        MotionEntry& entry, const ui::Transform& injectedTransform) const {
+void InputDispatcher::transformMotionEntryForInjectionLocked(MotionEntry& entry) const {
+    const bool isRelativeMouseEvent = isFromSource(entry.source, AINPUT_SOURCE_MOUSE_RELATIVE);
+    if (!isRelativeMouseEvent && !isFromSource(entry.source, AINPUT_SOURCE_CLASS_POINTER)) {
+        return;
+    }
+
     // Input injection works in the logical display coordinate space, but the input pipeline works
     // display space, so we need to transform the injected events accordingly.
     const auto it = mDisplayInfos.find(entry.displayId);
     if (it == mDisplayInfos.end()) return;
-    const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
+    const auto& transformToDisplay = it->second.transform.inverse();
 
     for (uint32_t i = 0; i < entry.pointerCount; i++) {
         PointerCoords& pc = entry.pointerCoords[i];
-        // Make a copy of the injected coords. We cannot change them in place because some of them
-        // are interdependent (for example, X coordinate might depend on the Y coordinate).
-        PointerCoords injectedCoords = entry.pointerCoords[i];
+        const auto xy = isRelativeMouseEvent
+                ? transformWithoutTranslation(transformToDisplay, pc.getX(), pc.getY())
+                : transformToDisplay.transform(pc.getXYValue());
+        pc.setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
+        pc.setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
 
-        BitSet64 bits(injectedCoords.bits);
-        while (!bits.isEmpty()) {
-            const auto axis = static_cast<int32_t>(bits.clearFirstMarkedBit());
-            const float value =
-                    MotionEvent::calculateTransformedAxisValue(axis, entry.source,
-                                                               transformToDisplay, injectedCoords);
-            pc.setAxisValue(axis, value);
-        }
+        // Axes with relative values never represent points on a screen, so they should never have
+        // translation applied. If a device does not report relative values, these values are always
+        // 0, and will remain unaffected by the following operation.
+        const auto rel =
+                transformWithoutTranslation(transformToDisplay,
+                                            pc.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
+                                            pc.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+        pc.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, rel.x);
+        pc.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, rel.y);
     }
 }
 
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 6f05670..8a551cf 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -280,9 +280,7 @@
     bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
     void setInjectionResult(EventEntry& entry,
                             android::os::InputEventInjectionResult injectionResult);
-    void transformMotionEntryForInjectionLocked(MotionEntry&,
-                                                const ui::Transform& injectedTransform) const
-            REQUIRES(mLock);
+    void transformMotionEntryForInjectionLocked(MotionEntry&) const REQUIRES(mLock);
 
     std::condition_variable mInjectionSyncFinished;
     void incrementPendingForegroundDispatches(EventEntry& entry);
diff --git a/services/inputflinger/dispatcher/InputState.cpp b/services/inputflinger/dispatcher/InputState.cpp
index ad3c615..3bb0bc9 100644
--- a/services/inputflinger/dispatcher/InputState.cpp
+++ b/services/inputflinger/dispatcher/InputState.cpp
@@ -296,7 +296,8 @@
                                                   memento.yPrecision, memento.xCursorPosition,
                                                   memento.yCursorPosition, memento.downTime,
                                                   memento.pointerCount, memento.pointerProperties,
-                                                  memento.pointerCoords));
+                                                  memento.pointerCoords, 0 /*xOffset*/,
+                                                  0 /*yOffset*/));
         }
     }
     return events;
@@ -348,7 +349,8 @@
                                                   AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
                                                   memento.yPrecision, memento.xCursorPosition,
                                                   memento.yCursorPosition, memento.downTime,
-                                                  pointerCount, pointerProperties, pointerCoords));
+                                                  pointerCount, pointerProperties, pointerCoords,
+                                                  0 /*xOffset*/, 0 /*yOffset*/));
         }
 
         memento.firstNewPointerIdx = INVALID_POINTER_INDEX;
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 8122b4a..39c5262 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2176,33 +2176,6 @@
     secondWindow->assertNoEvents();
 }
 
-// Ensure that when a MotionEvent that has a custom transform is injected, the post-transformed
-// event should be treated as being in the logical display space.
-TEST_F(InputDispatcherDisplayProjectionTest, InjectionWithTransformInLogicalDisplaySpace) {
-    auto [firstWindow, secondWindow] = setupScaledDisplayScenario();
-
-    const std::array<float, 9> matrix = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 0.0, 0.0, 1.0};
-    ui::Transform injectedEventTransform;
-    injectedEventTransform.set(matrix);
-    const vec2 expectedPoint{75, 55}; // The injected point in the logical display space.
-    const vec2 untransformedPoint = injectedEventTransform.inverse().transform(expectedPoint);
-
-    MotionEvent event = MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
-                                .displayId(ADISPLAY_ID_DEFAULT)
-                                .eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
-                                .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER)
-                                                 .x(untransformedPoint.x)
-                                                 .y(untransformedPoint.y))
-                                .build();
-    event.transform(matrix);
-
-    injectMotionEvent(mDispatcher, event, INJECT_EVENT_TIMEOUT,
-                      InputEventInjectionSync::WAIT_FOR_RESULT);
-
-    firstWindow->consumeMotionDown();
-    secondWindow->assertNoEvents();
-}
-
 TEST_F(InputDispatcherDisplayProjectionTest, WindowGetsEventsInCorrectCoordinateSpace) {
     auto [firstWindow, secondWindow] = setupScaledDisplayScenario();