diff options
author | 2021-04-16 10:42:42 -0700 | |
---|---|---|
committer | 2021-04-29 13:24:06 -0700 | |
commit | 84f07f0cbec87736f3d04846a7558869d69a2005 (patch) | |
tree | 3c53336d3f203a99953f64a1827f6325a78426c6 | |
parent | 9e8dd09f886e14585d2018f713b7d384e768856a (diff) |
Add enough information to compatibility-transform getRaw()
Many apps are mis-using getRaw (assuming it means screen-coordinates).
This means, for now, we have to do a compatibility transform on the
API to prevent breaking said apps.
Fortunately, since the input window transform includes rotation,
the only extra information we need to calculate this compat-raw
is the display size.
This CL topic pipes the display size around so that it makes into the
MotionEvent and can be used to calculate getRaw()
Bug: 179274888
Test: atest inputflinger_tests:InputDispatcherTest
Change-Id: Iff893643312e8ec9f38eeb96d76a41fdb3a28350
-rw-r--r-- | include/input/Input.h | 36 | ||||
-rw-r--r-- | include/input/InputTransport.h | 7 | ||||
-rw-r--r-- | include/input/InputWindow.h | 4 | ||||
-rw-r--r-- | libs/input/Input.cpp | 57 | ||||
-rw-r--r-- | libs/input/InputTransport.cpp | 13 | ||||
-rw-r--r-- | libs/input/tests/InputEvent_test.cpp | 76 | ||||
-rw-r--r-- | libs/input/tests/InputPublisherAndConsumer_test.cpp | 15 | ||||
-rw-r--r-- | libs/input/tests/StructLayout_test.cpp | 8 | ||||
-rw-r--r-- | libs/input/tests/VelocityTracker_test.cpp | 3 | ||||
-rw-r--r-- | libs/input/tests/VerifiedInputEvent_test.cpp | 6 | ||||
-rw-r--r-- | services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp | 3 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/Entry.cpp | 3 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/Entry.h | 3 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 16 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputTarget.h | 3 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 62 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 2 |
17 files changed, 264 insertions, 53 deletions
diff --git a/include/input/Input.h b/include/input/Input.h index bb5ca0ef04..7b522bbc1e 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -318,6 +318,12 @@ private: */ constexpr float AMOTION_EVENT_INVALID_CURSOR_POSITION = std::numeric_limits<float>::quiet_NaN(); +/** + * Invalid value for display size. Used when display size isn't available for an event or doesn't + * matter. This is just a constant 0 so that it has no effect if unused. + */ +constexpr int32_t AMOTION_EVENT_INVALID_DISPLAY_SIZE = 0; + /* * Pointer coordinate data. */ @@ -360,6 +366,8 @@ struct PointerCoords { return getAxisValue(AMOTION_EVENT_AXIS_Y); } + vec2 getXYValue() const { return vec2(getX(), getY()); } + #ifdef __linux__ status_t readFromParcel(Parcel* parcel); status_t writeToParcel(Parcel* parcel) const; @@ -548,6 +556,8 @@ public: void setCursorPosition(float x, float y); + int2 getDisplaySize() const { return {mDisplayWidth, mDisplayHeight}; } + static inline bool isValidCursorPosition(float x, float y) { return !isnan(x) && !isnan(y); } inline nsecs_t getDownTime() const { return mDownTime; } @@ -570,8 +580,17 @@ public: inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; } + /** + * The actual raw pointer coords: whatever comes from the input device without any external + * transforms applied. + */ const PointerCoords* getRawPointerCoords(size_t pointerIndex) const; + /** + * This is the raw axis value. However, for X/Y axes, this currently applies a "compat-raw" + * transform because many apps (incorrectly) assumed that raw == oriented-screen-space. + * "compat raw" is raw coordinates with screen rotation applied. + */ float getRawAxisValue(int32_t axis, size_t pointerIndex) const; inline float getRawX(size_t pointerIndex) const { @@ -634,9 +653,18 @@ public: return mSampleEventTimes[historicalIndex]; } + /** + * The actual raw pointer coords: whatever comes from the input device without any external + * transforms applied. + */ const PointerCoords* getHistoricalRawPointerCoords( size_t pointerIndex, size_t historicalIndex) const; + /** + * This is the raw axis value. However, for X/Y axes, this currently applies a "compat-raw" + * transform because many apps (incorrectly) assumed that raw == oriented-screen-space. + * "compat raw" is raw coordinates with screen rotation applied. + */ float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const; @@ -704,9 +732,9 @@ public: 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, nsecs_t downTime, nsecs_t eventTime, - size_t pointerCount, const PointerProperties* pointerProperties, - const PointerCoords* pointerCoords); + float rawYCursorPosition, int32_t displayWidth, int32_t displayHeight, + nsecs_t downTime, nsecs_t eventTime, size_t pointerCount, + const PointerProperties* pointerProperties, const PointerCoords* pointerCoords); void copyFrom(const MotionEvent* other, bool keepHistory); @@ -759,6 +787,8 @@ protected: float mYPrecision; float mRawXCursorPosition; float mRawYCursorPosition; + int32_t mDisplayWidth; + int32_t mDisplayHeight; nsecs_t mDownTime; Vector<PointerProperties> mPointerProperties; std::vector<nsecs_t> mSampleEventTimes; diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index 898d1a937c..ff3367839d 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -136,6 +136,8 @@ struct InputMessage { float yPrecision; float xCursorPosition; float yCursorPosition; + int32_t displayWidth; + int32_t displayHeight; uint32_t pointerCount; uint32_t empty3; /** @@ -353,8 +355,9 @@ public: int32_t metaState, int32_t buttonState, MotionClassification classification, const ui::Transform& transform, float xPrecision, float yPrecision, float xCursorPosition, - float yCursorPosition, nsecs_t downTime, nsecs_t eventTime, - uint32_t pointerCount, const PointerProperties* pointerProperties, + float yCursorPosition, int32_t displayWidth, int32_t displayHeight, + nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount, + const PointerProperties* pointerProperties, const PointerCoords* pointerCoords); /* Publishes a focus event to the input channel. diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h index 36097d6d65..121be6d963 100644 --- a/include/input/InputWindow.h +++ b/include/input/InputWindow.h @@ -168,6 +168,10 @@ struct InputWindowInfo : public Parcelable { // Transform applied to individual windows. ui::Transform transform; + // Display size in its natural rotation. Used to rotate raw coordinates for compatibility. + int32_t displayWidth = AMOTION_EVENT_INVALID_DISPLAY_SIZE; + int32_t displayHeight = AMOTION_EVENT_INVALID_DISPLAY_SIZE; + /* * This is filled in by the WM relative to the frame and then translated * to absolute coordinates by SurfaceFlinger once the frame is computed. diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 5600eb3f5e..deb4679558 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -340,7 +340,8 @@ void MotionEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int3 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, nsecs_t downTime, + float rawXCursorPosition, float rawYCursorPosition, + int32_t displayWidth, int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime, size_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) { @@ -357,6 +358,8 @@ void MotionEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int3 mYPrecision = yPrecision; mRawXCursorPosition = rawXCursorPosition; mRawYCursorPosition = rawYCursorPosition; + mDisplayWidth = displayWidth; + mDisplayHeight = displayHeight; mDownTime = downTime; mPointerProperties.clear(); mPointerProperties.appendArray(pointerProperties, pointerCount); @@ -380,6 +383,8 @@ void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) { mYPrecision = other->mYPrecision; mRawXCursorPosition = other->mRawXCursorPosition; mRawYCursorPosition = other->mRawYCursorPosition; + mDisplayWidth = other->mDisplayWidth; + mDisplayHeight = other->mDisplayHeight; mDownTime = other->mDownTime; mPointerProperties = other->mPointerProperties; @@ -426,7 +431,7 @@ const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const } float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const { - return getRawPointerCoords(pointerIndex)->getAxisValue(axis); + return getHistoricalRawAxisValue(axis, pointerIndex, getHistorySize()); } float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const { @@ -440,7 +445,32 @@ const PointerCoords* MotionEvent::getHistoricalRawPointerCoords( float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const { - return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); + if (axis != AMOTION_EVENT_AXIS_X && axis != AMOTION_EVENT_AXIS_Y) { + return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); + } + // 0x7 encapsulates all 3 rotations (see ui::Transform::RotationFlags) + static const int ALL_ROTATIONS_MASK = 0x7; + uint32_t orientation = (mTransform.getOrientation() & ALL_ROTATIONS_MASK); + if (orientation == ui::Transform::ROT_0) { + return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); + } + + // For compatibility, convert raw coordinates into "oriented screen space". Once app developers + // are educated about getRaw, we can consider removing this. + vec2 xy = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getXYValue(); + const float unrotatedX = xy.x; + if (orientation == ui::Transform::ROT_90) { + xy.x = mDisplayHeight - xy.y; + xy.y = unrotatedX; + } else if (orientation == ui::Transform::ROT_180) { + xy.x = mDisplayWidth - xy.x; + xy.y = mDisplayHeight - xy.y; + } else if (orientation == ui::Transform::ROT_270) { + xy.x = xy.y; + xy.y = mDisplayWidth - unrotatedX; + } + static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1); + return xy[axis]; } float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex, @@ -449,19 +479,10 @@ float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex, return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); } - float rawX = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getX(); - float rawY = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getY(); - vec2 vals = mTransform.transform(rawX, rawY); - - switch (axis) { - case AMOTION_EVENT_AXIS_X: - return vals.x; - case AMOTION_EVENT_AXIS_Y: - return vals.y; - } - - // This should never happen - return 0; + vec2 vals = mTransform.transform( + getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getXYValue()); + static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1); + return vals[axis]; } ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const { @@ -606,6 +627,8 @@ status_t MotionEvent::readFromParcel(Parcel* parcel) { mYPrecision = parcel->readFloat(); mRawXCursorPosition = parcel->readFloat(); mRawYCursorPosition = parcel->readFloat(); + mDisplayWidth = parcel->readInt32(); + mDisplayHeight = parcel->readInt32(); mDownTime = parcel->readInt64(); mPointerProperties.clear(); @@ -665,6 +688,8 @@ status_t MotionEvent::writeToParcel(Parcel* parcel) const { parcel->writeFloat(mYPrecision); parcel->writeFloat(mRawXCursorPosition); parcel->writeFloat(mRawYCursorPosition); + parcel->writeInt32(mDisplayWidth); + parcel->writeInt32(mDisplayHeight); parcel->writeInt64(mDownTime); for (size_t i = 0; i < pointerCount; i++) { diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index 56a064bd26..de75691cc7 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -228,6 +228,10 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const { msg->body.motion.xCursorPosition = body.motion.xCursorPosition; // float yCursorPosition msg->body.motion.yCursorPosition = body.motion.yCursorPosition; + // int32_t displayW + msg->body.motion.displayWidth = body.motion.displayWidth; + // int32_t displayH + msg->body.motion.displayHeight = body.motion.displayHeight; // uint32_t pointerCount msg->body.motion.pointerCount = body.motion.pointerCount; //struct Pointer pointers[MAX_POINTERS] @@ -517,9 +521,9 @@ status_t InputPublisher::publishMotionEvent( 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, nsecs_t downTime, - nsecs_t eventTime, uint32_t pointerCount, const PointerProperties* pointerProperties, - const PointerCoords* pointerCoords) { + float yPrecision, float xCursorPosition, float yCursorPosition, int32_t displayWidth, + int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount, + const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) { if (ATRACE_ENABLED()) { std::string message = StringPrintf( "publishMotionEvent(inputChannel=%s, action=%" PRId32 ")", @@ -577,6 +581,8 @@ status_t InputPublisher::publishMotionEvent( msg.body.motion.yPrecision = yPrecision; msg.body.motion.xCursorPosition = xCursorPosition; msg.body.motion.yCursorPosition = yCursorPosition; + msg.body.motion.displayWidth = displayWidth; + msg.body.motion.displayHeight = displayHeight; msg.body.motion.downTime = downTime; msg.body.motion.eventTime = eventTime; msg.body.motion.pointerCount = pointerCount; @@ -1343,6 +1349,7 @@ void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage 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.displayWidth, msg->body.motion.displayHeight, msg->body.motion.downTime, msg->body.motion.eventTime, pointerCount, pointerProperties, pointerCoords); } diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp index 601d8dabf7..15ab428979 100644 --- a/libs/input/tests/InputEvent_test.cpp +++ b/libs/input/tests/InputEvent_test.cpp @@ -271,6 +271,7 @@ void MotionEventTest::initializeEventWithHistory(MotionEvent* event) { 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, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2, pointerProperties, pointerCoords); @@ -592,6 +593,7 @@ TEST_F(MotionEventTest, Transform) { AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE, identityTransform, 0 /*xPrecision*/, 0 /*yPrecision*/, 3 + RADIUS /*xCursorPosition*/, 2 /*yCursorPosition*/, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE, 0 /*downTime*/, 0 /*eventTime*/, pointerCount, pointerProperties, pointerCoords); float originalRawX = 0 + 3; @@ -634,6 +636,71 @@ TEST_F(MotionEventTest, Transform) { ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001); } +TEST_F(MotionEventTest, RawCompatTransform) { + auto createTouchDownEvent = [](int x, int y, ui::Transform transform) { + std::vector<PointerProperties> pointerProperties; + pointerProperties.push_back(PointerProperties{/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER}); + std::vector<PointerCoords> pointerCoords; + pointerCoords.emplace_back().clear(); + pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, x); + pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, y); + nsecs_t eventTime = systemTime(SYSTEM_TIME_MONOTONIC); + MotionEvent event; + event.initialize(InputEvent::nextId(), /* deviceId */ 1, AINPUT_SOURCE_TOUCHSCREEN, + /* displayId */ 0, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, + /* 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, /* displayWidth */ 400, + /* displayHeight */ 800, eventTime, eventTime, pointerCoords.size(), + pointerProperties.data(), pointerCoords.data()); + return event; + }; + + { + // Make sure raw is raw regardless of transform translation. + ui::Transform xform; + xform.set(20, 40); + MotionEvent event = createTouchDownEvent(60, 100, 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)); + } + + // 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, xform); + 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)); + } + + { + // 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, xform); + ASSERT_EQ(340, event.getRawX(0)); + ASSERT_EQ(700, event.getRawY(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, xform); + ASSERT_EQ(100, event.getRawX(0)); + ASSERT_EQ(340, event.getRawY(0)); + } +} + TEST_F(MotionEventTest, Initialize_SetsClassification) { std::array<MotionClassification, 3> classifications = { MotionClassification::NONE, @@ -657,7 +724,8 @@ TEST_F(MotionEventTest, Initialize_SetsClassification) { 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, 0 /*downTime*/, 0 /*eventTime*/, + AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, 0 /*downTime*/, 0 /*eventTime*/, pointerCount, pointerProperties, pointerCoords); ASSERT_EQ(classification, event.getClassification()); } @@ -678,8 +746,10 @@ TEST_F(MotionEventTest, Initialize_SetsCursorPosition) { 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*/, 0 /*downTime*/, - 0 /*eventTime*/, pointerCount, pointerProperties, pointerCoords); + 280 /*xCursorPosition*/, 540 /*yCursorPosition*/, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + 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 088e00b59c..a2cfaa1cc0 100644 --- a/libs/input/tests/InputPublisherAndConsumer_test.cpp +++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp @@ -162,6 +162,8 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { constexpr float yPrecision = 0.5; constexpr float xCursorPosition = 1.3; constexpr float yCursorPosition = 50.6; + 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; @@ -190,8 +192,9 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { status = mPublisher->publishMotionEvent(seq, eventId, deviceId, source, displayId, hmac, action, actionButton, flags, edgeFlags, metaState, buttonState, classification, transform, xPrecision, yPrecision, - xCursorPosition, yCursorPosition, downTime, eventTime, - pointerCount, pointerProperties, pointerCoords); + xCursorPosition, yCursorPosition, displayWidth, + displayHeight, downTime, eventTime, pointerCount, + pointerProperties, pointerCoords); ASSERT_EQ(OK, status) << "publisher publishMotionEvent should return OK"; @@ -228,6 +231,8 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() { EXPECT_EQ(yCursorPosition, motionEvent->getRawYCursorPosition()); EXPECT_EQ(xCursorPosition * xScale + xOffset, motionEvent->getXCursorPosition()); EXPECT_EQ(yCursorPosition * yScale + yOffset, motionEvent->getYCursorPosition()); + EXPECT_EQ(displayWidth, motionEvent->getDisplaySize().x); + EXPECT_EQ(displayHeight, motionEvent->getDisplaySize().y); EXPECT_EQ(downTime, motionEvent->getDownTime()); EXPECT_EQ(eventTime, motionEvent->getEventTime()); EXPECT_EQ(pointerCount, motionEvent->getPointerCount()); @@ -455,7 +460,7 @@ TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenSequenceNumberIsZer 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, 0, 0, + AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords); ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE"; @@ -471,7 +476,7 @@ TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessTha 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, 0, 0, + AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords); ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE"; @@ -492,7 +497,7 @@ TEST_F(InputPublisherAndConsumerTest, 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, 0, 0, + AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0, 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 585779e472..5861d55156 100644 --- a/libs/input/tests/StructLayout_test.cpp +++ b/libs/input/tests/StructLayout_test.cpp @@ -74,9 +74,11 @@ void TestInputMessageAlignment() { 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, pointerCount, 136); - CHECK_OFFSET(InputMessage::Body::Motion, empty3, 140); - CHECK_OFFSET(InputMessage::Body::Motion, pointers, 144); + CHECK_OFFSET(InputMessage::Body::Motion, displayWidth, 136); + CHECK_OFFSET(InputMessage::Body::Motion, displayHeight, 140); + CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 144); + CHECK_OFFSET(InputMessage::Body::Motion, empty3, 148); + CHECK_OFFSET(InputMessage::Body::Motion, pointers, 152); 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 d049d05ac5..aefc2ec47d 100644 --- a/libs/input/tests/VelocityTracker_test.cpp +++ b/libs/input/tests/VelocityTracker_test.cpp @@ -183,7 +183,8 @@ static std::vector<MotionEvent> createMotionEventStream( 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, 0 /*downTime*/, + AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, 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 36f87b8a6a..f79098c63c 100644 --- a/libs/input/tests/VerifiedInputEvent_test.cpp +++ b/libs/input/tests/VerifiedInputEvent_test.cpp @@ -46,8 +46,10 @@ static MotionEvent getMotionEventWithFlags(int32_t flags) { 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*/, 100 /*downTime*/, - 200 /*eventTime*/, pointerCount, pointerProperties, pointerCoords); + 280 /*xCursorPosition*/, 540 /*yCursorPosition*/, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + 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 7bd0c6b1b8..1b5f1ab76e 100644 --- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp +++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp @@ -232,7 +232,8 @@ static MotionEvent generateMotionEvent() { /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE, identityTransform, /* xPrecision */ 0, /* yPrecision */ 0, AMOTION_EVENT_INVALID_CURSOR_POSITION, - AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, currentTime, + AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, currentTime, currentTime, /*pointerCount*/ 1, pointerProperties, pointerCoords); return event; } diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp index 5270b8a107..6ed959306b 100644 --- a/services/inputflinger/dispatcher/Entry.cpp +++ b/services/inputflinger/dispatcher/Entry.cpp @@ -296,12 +296,13 @@ std::string SensorEntry::getDescription() const { volatile int32_t DispatchEntry::sNextSeqAtomic; DispatchEntry::DispatchEntry(std::shared_ptr<EventEntry> eventEntry, int32_t targetFlags, - ui::Transform transform, float globalScaleFactor) + ui::Transform transform, float globalScaleFactor, vec2 displaySize) : seq(nextSeq()), eventEntry(std::move(eventEntry)), targetFlags(targetFlags), transform(transform), globalScaleFactor(globalScaleFactor), + displaySize(displaySize), deliveryTime(0), resolvedAction(0), resolvedFlags(0) {} diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h index f3ef64ba8e..45c5e24395 100644 --- a/services/inputflinger/dispatcher/Entry.h +++ b/services/inputflinger/dispatcher/Entry.h @@ -215,6 +215,7 @@ struct DispatchEntry { int32_t targetFlags; ui::Transform transform; float globalScaleFactor; + vec2 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 @@ -227,7 +228,7 @@ struct DispatchEntry { int32_t resolvedFlags; DispatchEntry(std::shared_ptr<EventEntry> eventEntry, int32_t targetFlags, - ui::Transform transform, float globalScaleFactor); + ui::Transform transform, float globalScaleFactor, vec2 displaySize); inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; } diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 27443b0666..16cb7d7a51 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -339,14 +339,16 @@ static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inp // values do not represent on-screen coordinates, so they should not have any window // transformations applied to them. return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform, - 1.0f /*globalScaleFactor*/); + 1.0f /*globalScaleFactor*/, + inputTarget.displaySize); } } if (inputTarget.useDefaultPointerTransform()) { const ui::Transform& transform = inputTarget.getDefaultPointerTransform(); return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform, - inputTarget.globalScaleFactor); + inputTarget.globalScaleFactor, + inputTarget.displaySize); } ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION); @@ -397,7 +399,8 @@ static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inp std::unique_ptr<DispatchEntry> dispatchEntry = std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags, - firstPointerTransform, inputTarget.globalScaleFactor); + firstPointerTransform, inputTarget.globalScaleFactor, + inputTarget.displaySize); return dispatchEntry; } @@ -2402,6 +2405,8 @@ void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowH inputTarget.inputChannel = inputChannel; inputTarget.flags = targetFlags; inputTarget.globalScaleFactor = windowInfo->globalScaleFactor; + inputTarget.displaySize = + vec2(windowHandle->getInfo()->displayWidth, windowHandle->getInfo()->displayHeight); inputTargets.push_back(inputTarget); it = inputTargets.end() - 1; } @@ -3107,6 +3112,8 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, motionEntry.xPrecision, motionEntry.yPrecision, motionEntry.xCursorPosition, motionEntry.yCursorPosition, + dispatchEntry->displaySize.x, + dispatchEntry->displaySize.y, motionEntry.downTime, motionEntry.eventTime, motionEntry.pointerCount, motionEntry.pointerProperties, usingCoords); @@ -3819,7 +3826,8 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) { args->action, args->actionButton, args->flags, args->edgeFlags, args->metaState, args->buttonState, args->classification, transform, args->xPrecision, args->yPrecision, args->xCursorPosition, - args->yCursorPosition, args->downTime, args->eventTime, + args->yCursorPosition, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, args->downTime, args->eventTime, args->pointerCount, args->pointerProperties, args->pointerCoords); policyFlags |= POLICY_FLAG_FILTERED; diff --git a/services/inputflinger/dispatcher/InputTarget.h b/services/inputflinger/dispatcher/InputTarget.h index debf8058b3..2543852788 100644 --- a/services/inputflinger/dispatcher/InputTarget.h +++ b/services/inputflinger/dispatcher/InputTarget.h @@ -100,6 +100,9 @@ struct InputTarget { // (ignored for KeyEvents) float globalScaleFactor = 1.0f; + // Display-size in its natural rotation. Used for compatibility transform of raw coordinates. + vec2 displaySize = {AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE}; + // The subset of pointer ids to include in motion events dispatched to this input target // if FLAG_SPLIT is set. BitSet32 pointerIds; diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 31d6900ef2..9687c83ca2 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -526,7 +526,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 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, ARBITRARY_TIME, ARBITRARY_TIME, + AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(InputEventInjectionResult::FAILED, mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, @@ -539,6 +540,7 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { (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, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(InputEventInjectionResult::FAILED, @@ -551,6 +553,7 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { (~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, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(InputEventInjectionResult::FAILED, @@ -564,6 +567,7 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { (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, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(InputEventInjectionResult::FAILED, @@ -576,6 +580,7 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { (~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, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(InputEventInjectionResult::FAILED, @@ -587,7 +592,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 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, ARBITRARY_TIME, ARBITRARY_TIME, + AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 0, pointerProperties, pointerCoords); ASSERT_EQ(InputEventInjectionResult::FAILED, mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, @@ -597,7 +603,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 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, ARBITRARY_TIME, ARBITRARY_TIME, + AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords); ASSERT_EQ(InputEventInjectionResult::FAILED, mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, @@ -609,7 +616,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 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, ARBITRARY_TIME, ARBITRARY_TIME, + AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(InputEventInjectionResult::FAILED, mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, @@ -620,7 +628,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 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, ARBITRARY_TIME, ARBITRARY_TIME, + AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(InputEventInjectionResult::FAILED, mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, @@ -633,7 +642,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 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, ARBITRARY_TIME, ARBITRARY_TIME, + AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE, + AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 2, pointerProperties, pointerCoords); ASSERT_EQ(InputEventInjectionResult::FAILED, mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, @@ -1237,8 +1247,8 @@ public: mAction, mActionButton, /* flags */ 0, /* edgeFlags */ 0, AMETA_NONE, mButtonState, MotionClassification::NONE, identityTransform, /* xPrecision */ 0, /* yPrecision */ 0, mRawXCursorPosition, - mRawYCursorPosition, mEventTime, mEventTime, mPointers.size(), - pointerProperties.data(), pointerCoords.data()); + mRawYCursorPosition, mDisplayWidth, mDisplayHeight, mEventTime, mEventTime, + mPointers.size(), pointerProperties.data(), pointerCoords.data()); return event; } @@ -1252,6 +1262,8 @@ private: int32_t mButtonState{0}; float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION}; float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION}; + int32_t mDisplayWidth{AMOTION_EVENT_INVALID_DISPLAY_SIZE}; + int32_t mDisplayHeight{AMOTION_EVENT_INVALID_DISPLAY_SIZE}; std::vector<PointerBuilder> mPointers; }; @@ -2029,6 +2041,19 @@ public: expectedDisplayId, expectedFlags); } + MotionEvent* consumeMotion() { + InputEvent* event = mInputReceiver->consume(); + if (!event) { + ADD_FAILURE() << "No event was produced"; + return nullptr; + } + if (event->getType() != AINPUT_EVENT_TYPE_MOTION) { + ADD_FAILURE() << "Received event of type " << event->getType() << " instead of motion"; + return nullptr; + } + return static_cast<MotionEvent*>(event); + } + void assertNoEvents() { mInputReceiver->assertNoEvents(); } private: @@ -2115,6 +2140,27 @@ TEST_F(InputDispatcherTest, UnresponsiveGestureMonitor_GetsAnr) { mFakePolicy->assertNotifyMonitorResponsiveWasCalled(); } +// Tests for gesture monitors +TEST_F(InputDispatcherTest, GestureMonitor_NoWindowTransform) { + std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); + sp<FakeWindowHandle> window = + new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); + mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); + window->setWindowOffset(20, 40); + window->setWindowTransform(0, 1, -1, 0); + + FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT, + true /*isGestureMonitor*/); + + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT)) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + window->consumeMotionDown(ADISPLAY_ID_DEFAULT); + MotionEvent* event = monitor.consumeMotion(); + // Even though window has transform, gesture monitor must not. + ASSERT_EQ(ui::Transform(), event->getTransform()); +} + TEST_F(InputDispatcherTest, TestMoveEvent) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); sp<FakeWindowHandle> window = diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 7707aaf624..0d673eab78 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2449,6 +2449,8 @@ InputWindowInfo Layer::fillInputInfo(const sp<DisplayDevice>& display) { ui::Transform toPhysicalDisplay; if (display) { toPhysicalDisplay = display->getTransform(); + info.displayWidth = display->getWidth(); + info.displayHeight = display->getHeight(); } fillInputFrameInfo(info, toPhysicalDisplay); |