Merge changes from topic "revert-16306432-revert-16295572-ORWQJPYRMQ-IQBEBXXQNX"
* changes:
Reland "Remove x/y offset from MotionEntry"
Reland "Input injection: Assume transformed values are i..."
diff --git a/include/input/Input.h b/include/input/Input.h
index 29503af..70c7909 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -382,7 +382,6 @@
// 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);
@@ -572,7 +571,7 @@
inline float getYOffset() const { return mTransform.ty(); }
- inline ui::Transform getTransform() const { return mTransform; }
+ inline const ui::Transform& getTransform() const { return mTransform; }
int getSurfaceRotation() const;
@@ -590,7 +589,7 @@
void setCursorPosition(float x, float y);
- ui::Transform getRawTransform() const { return mRawTransform; }
+ inline const 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 44487c3..349880c 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -344,11 +344,6 @@
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 f6bb6a6..d8636dd 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, float xOffset, float yOffset)
+ const PointerCoords* pointerCoords)
: EventEntry(id, Type::MOTION, eventTime, policyFlags),
deviceId(deviceId),
source(source),
@@ -235,9 +235,6 @@
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 477781a..0f79296 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -184,8 +184,7 @@
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,
- float xOffset, float yOffset);
+ const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
std::string getDescription() const override;
~MotionEntry() override;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index c9397c3..de4090c 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(), 0 /* xOffset */, 0 /* yOffset */);
+ pointerCoords.data());
if (motionEntry.injectionState) {
combinedMotionEntry->injectionState = motionEntry.injectionState;
@@ -506,12 +506,6 @@
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) {
@@ -3763,7 +3757,7 @@
originalMotionEntry.xCursorPosition,
originalMotionEntry.yCursorPosition,
originalMotionEntry.downTime, splitPointerCount,
- splitPointerProperties, splitPointerCoords, 0, 0);
+ splitPointerProperties, splitPointerCoords);
if (originalMotionEntry.injectionState) {
splitMotionEntry->injectionState = originalMotionEntry.injectionState;
@@ -3989,7 +3983,7 @@
args->xPrecision, args->yPrecision,
args->xCursorPosition, args->yCursorPosition,
args->downTime, args->pointerCount,
- args->pointerProperties, args->pointerCoords, 0, 0);
+ args->pointerProperties, args->pointerCoords);
if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
@@ -4219,10 +4213,8 @@
motionEvent.getRawXCursorPosition(),
motionEvent.getRawYCursorPosition(),
motionEvent.getDownTime(), uint32_t(pointerCount),
- pointerProperties, samplePointerCoords,
- motionEvent.getXOffset(),
- motionEvent.getYOffset());
- transformMotionEntryForInjectionLocked(*injectedEntry);
+ pointerProperties, samplePointerCoords);
+ transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
injectedEntries.push(std::move(injectedEntry));
for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
sampleEventTimes += 1;
@@ -4241,9 +4233,9 @@
motionEvent.getRawYCursorPosition(),
motionEvent.getDownTime(),
uint32_t(pointerCount), pointerProperties,
- samplePointerCoords, motionEvent.getXOffset(),
- motionEvent.getYOffset());
- transformMotionEntryForInjectionLocked(*nextInjectedEntry);
+ samplePointerCoords);
+ transformMotionEntryForInjectionLocked(*nextInjectedEntry,
+ motionEvent.getTransform());
injectedEntries.push(std::move(nextInjectedEntry));
}
break;
@@ -4407,35 +4399,28 @@
}
}
-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;
- }
-
+void InputDispatcher::transformMotionEntryForInjectionLocked(
+ MotionEntry& entry, const ui::Transform& injectedTransform) const {
// 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();
+ const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
for (uint32_t i = 0; i < entry.pointerCount; i++) {
PointerCoords& pc = 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);
+ // 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];
- // 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);
+ 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);
+ }
}
}
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 8a551cf..6f05670 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -280,7 +280,9 @@
bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
void setInjectionResult(EventEntry& entry,
android::os::InputEventInjectionResult injectionResult);
- void transformMotionEntryForInjectionLocked(MotionEntry&) const REQUIRES(mLock);
+ void transformMotionEntryForInjectionLocked(MotionEntry&,
+ const ui::Transform& injectedTransform) 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 3bb0bc9..ad3c615 100644
--- a/services/inputflinger/dispatcher/InputState.cpp
+++ b/services/inputflinger/dispatcher/InputState.cpp
@@ -296,8 +296,7 @@
memento.yPrecision, memento.xCursorPosition,
memento.yCursorPosition, memento.downTime,
memento.pointerCount, memento.pointerProperties,
- memento.pointerCoords, 0 /*xOffset*/,
- 0 /*yOffset*/));
+ memento.pointerCoords));
}
}
return events;
@@ -349,8 +348,7 @@
AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
memento.yPrecision, memento.xCursorPosition,
memento.yCursorPosition, memento.downTime,
- pointerCount, pointerProperties, pointerCoords,
- 0 /*xOffset*/, 0 /*yOffset*/));
+ pointerCount, pointerProperties, pointerCoords));
}
memento.firstNewPointerIdx = INVALID_POINTER_INDEX;
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 39c5262..8122b4a 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2176,6 +2176,33 @@
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();