Dispatch mouse events to window under the cursor.
This CL adds cursor positions to NotifyMotionArgs, MotionEntry,
InputMessage motion body and MotionEvent.
Bug: 134788085
Test: The window under the cursor always responds to the gesture.
Test: atest inputflinger_tests
Test: atest libinput_tests
Change-Id: I8ea460ed8738ffc3a5e997215685889cc1e1f2fe
diff --git a/include/input/Input.h b/include/input/Input.h
index 805957a..a976246 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -24,12 +24,14 @@
*/
#include <android/input.h>
+#include <stdint.h>
#include <utils/BitSet.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <utils/Vector.h>
-#include <stdint.h>
+
+#include <limits>
/*
* Additional private constants not defined in ndk/ui/input.h.
@@ -246,6 +248,13 @@
*/
const char* motionClassificationToString(MotionClassification classification);
+/**
+ * Invalid value for cursor position. Used for non-mouse events, tests and injected events. Don't
+ * use it for direct comparison with any other value, because NaN isn't equal to itself according to
+ * IEEE 754. Use isnan() instead to check if a cursor position is valid.
+ */
+constexpr float AMOTION_EVENT_INVALID_CURSOR_POSITION = std::numeric_limits<float>::quiet_NaN();
+
/*
* Pointer coordinate data.
*/
@@ -459,6 +468,14 @@
inline float getYPrecision() const { return mYPrecision; }
+ inline float getRawXCursorPosition() const { return mXCursorPosition; }
+
+ float getXCursorPosition() const;
+
+ inline float getRawYCursorPosition() const { return mYCursorPosition; }
+
+ float getYCursorPosition() const;
+
inline nsecs_t getDownTime() const { return mDownTime; }
inline void setDownTime(nsecs_t downTime) { mDownTime = downTime; }
@@ -600,26 +617,13 @@
ssize_t findPointerIndex(int32_t pointerId) const;
- void initialize(
- int32_t deviceId,
- int32_t source,
- int32_t displayId,
- int32_t action,
- int32_t actionButton,
- int32_t flags,
- int32_t edgeFlags,
- int32_t metaState,
- int32_t buttonState,
- MotionClassification classification,
- float xOffset,
- float yOffset,
- float xPrecision,
- float yPrecision,
- nsecs_t downTime,
- nsecs_t eventTime,
- size_t pointerCount,
- const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords);
+ void initialize(int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
+ int32_t actionButton, int32_t flags, int32_t edgeFlags, int32_t metaState,
+ int32_t buttonState, MotionClassification classification, float xOffset,
+ float yOffset, float xPrecision, float yPrecision, float mXCursorPosition,
+ float mYCursorPosition, nsecs_t downTime, nsecs_t eventTime,
+ size_t pointerCount, const PointerProperties* pointerProperties,
+ const PointerCoords* pointerCoords);
void copyFrom(const MotionEvent* other, bool keepHistory);
@@ -669,6 +673,8 @@
float mYOffset;
float mXPrecision;
float mYPrecision;
+ float mXCursorPosition;
+ float mYCursorPosition;
nsecs_t mDownTime;
Vector<PointerProperties> mPointerProperties;
Vector<nsecs_t> mSampleEventTimes;
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 63606e5..df23f61 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -113,6 +113,8 @@
float yOffset;
float xPrecision;
float yPrecision;
+ float xCursorPosition;
+ float yCursorPosition;
uint32_t pointerCount;
uint32_t empty3;
// Note that PointerCoords requires 8 byte alignment.
@@ -261,27 +263,14 @@
* Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS.
* Other errors probably indicate that the channel is broken.
*/
- status_t publishMotionEvent(
- uint32_t seq,
- int32_t deviceId,
- int32_t source,
- int32_t displayId,
- int32_t action,
- int32_t actionButton,
- int32_t flags,
- int32_t edgeFlags,
- int32_t metaState,
- int32_t buttonState,
- MotionClassification classification,
- float xOffset,
- float yOffset,
- float xPrecision,
- float yPrecision,
- nsecs_t downTime,
- nsecs_t eventTime,
- uint32_t pointerCount,
- const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords);
+ status_t publishMotionEvent(uint32_t seq, int32_t deviceId, int32_t source, int32_t displayId,
+ int32_t action, int32_t actionButton, int32_t flags,
+ int32_t edgeFlags, int32_t metaState, int32_t buttonState,
+ MotionClassification classification, float xOffset, float yOffset,
+ float xPrecision, float yPrecision, float xCursorPosition,
+ float yCursorPosition, nsecs_t downTime, nsecs_t eventTime,
+ uint32_t pointerCount, const PointerProperties* pointerProperties,
+ const PointerCoords* pointerCoords);
/* Receives the finished signal from the consumer in reply to the original dispatch signal.
* If a signal was received, returns the message sequence number,
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 9fd25f9..3266b07 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -235,26 +235,14 @@
// --- MotionEvent ---
-void MotionEvent::initialize(
- int32_t deviceId,
- int32_t source,
- int32_t displayId,
- int32_t action,
- int32_t actionButton,
- int32_t flags,
- int32_t edgeFlags,
- int32_t metaState,
- int32_t buttonState,
- MotionClassification classification,
- float xOffset,
- float yOffset,
- float xPrecision,
- float yPrecision,
- nsecs_t downTime,
- nsecs_t eventTime,
- size_t pointerCount,
- const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords) {
+void MotionEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
+ int32_t actionButton, int32_t flags, int32_t edgeFlags,
+ int32_t metaState, int32_t buttonState,
+ MotionClassification classification, float xOffset, float yOffset,
+ float xPrecision, float yPrecision, float xCursorPosition,
+ float yCursorPosition, nsecs_t downTime, nsecs_t eventTime,
+ size_t pointerCount, const PointerProperties* pointerProperties,
+ const PointerCoords* pointerCoords) {
InputEvent::initialize(deviceId, source, displayId);
mAction = action;
mActionButton = actionButton;
@@ -267,6 +255,8 @@
mYOffset = yOffset;
mXPrecision = xPrecision;
mYPrecision = yPrecision;
+ mXCursorPosition = xCursorPosition;
+ mYCursorPosition = yCursorPosition;
mDownTime = downTime;
mPointerProperties.clear();
mPointerProperties.appendArray(pointerProperties, pointerCount);
@@ -288,6 +278,8 @@
mYOffset = other->mYOffset;
mXPrecision = other->mXPrecision;
mYPrecision = other->mYPrecision;
+ mXCursorPosition = other->mXCursorPosition;
+ mYCursorPosition = other->mYCursorPosition;
mDownTime = other->mDownTime;
mPointerProperties = other->mPointerProperties;
@@ -312,6 +304,16 @@
mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
}
+float MotionEvent::getXCursorPosition() const {
+ const float rawX = getRawXCursorPosition();
+ return rawX + mXOffset;
+}
+
+float MotionEvent::getYCursorPosition() const {
+ const float rawY = getRawYCursorPosition();
+ return rawY + mYOffset;
+}
+
const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
}
@@ -431,6 +433,15 @@
float originX, originY;
transformPoint(matrix, 0, 0, &originX, &originY);
+ // Apply the transformation to cursor position.
+ if (!isnan(mXCursorPosition) && !isnan(mYCursorPosition)) {
+ float x = mXCursorPosition + oldXOffset;
+ float y = mYCursorPosition + oldYOffset;
+ transformPoint(matrix, x, y, &x, &y);
+ mXCursorPosition = x - mXOffset;
+ mYCursorPosition = y - mYOffset;
+ }
+
// Apply the transformation to all samples.
size_t numSamples = mSamplePointerCoords.size();
for (size_t i = 0; i < numSamples; i++) {
@@ -470,6 +481,8 @@
mYOffset = parcel->readFloat();
mXPrecision = parcel->readFloat();
mYPrecision = parcel->readFloat();
+ mXCursorPosition = parcel->readFloat();
+ mYCursorPosition = parcel->readFloat();
mDownTime = parcel->readInt64();
mPointerProperties.clear();
@@ -521,6 +534,8 @@
parcel->writeFloat(mYOffset);
parcel->writeFloat(mXPrecision);
parcel->writeFloat(mYPrecision);
+ parcel->writeFloat(mXCursorPosition);
+ parcel->writeFloat(mYCursorPosition);
parcel->writeInt64(mDownTime);
for (size_t i = 0; i < pointerCount; i++) {
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index d02cb8e..904a6fe 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -191,6 +191,10 @@
msg->body.motion.xPrecision = body.motion.xPrecision;
// float yPrecision
msg->body.motion.yPrecision = body.motion.yPrecision;
+ // float xCursorPosition
+ msg->body.motion.xCursorPosition = body.motion.xCursorPosition;
+ // float yCursorPosition
+ msg->body.motion.yCursorPosition = body.motion.yCursorPosition;
// uint32_t pointerCount
msg->body.motion.pointerCount = body.motion.pointerCount;
//struct Pointer pointers[MAX_POINTERS]
@@ -465,26 +469,12 @@
}
status_t InputPublisher::publishMotionEvent(
- uint32_t seq,
- int32_t deviceId,
- int32_t source,
- int32_t displayId,
- int32_t action,
- int32_t actionButton,
- int32_t flags,
- int32_t edgeFlags,
- int32_t metaState,
- int32_t buttonState,
- MotionClassification classification,
- float xOffset,
- float yOffset,
- float xPrecision,
- float yPrecision,
- nsecs_t downTime,
- nsecs_t eventTime,
- uint32_t pointerCount,
- const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords) {
+ uint32_t seq, int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
+ int32_t actionButton, int32_t flags, int32_t edgeFlags, int32_t metaState,
+ int32_t buttonState, MotionClassification classification, float xOffset, float yOffset,
+ float xPrecision, float yPrecision, float xCursorPosition, float yCursorPosition,
+ 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 ")",
@@ -532,6 +522,8 @@
msg.body.motion.yOffset = yOffset;
msg.body.motion.xPrecision = xPrecision;
msg.body.motion.yPrecision = yPrecision;
+ msg.body.motion.xCursorPosition = xCursorPosition;
+ msg.body.motion.yCursorPosition = yCursorPosition;
msg.body.motion.downTime = downTime;
msg.body.motion.eventTime = eventTime;
msg.body.motion.pointerCount = pointerCount;
@@ -1135,26 +1127,16 @@
pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
}
- event->initialize(
- msg->body.motion.deviceId,
- msg->body.motion.source,
- msg->body.motion.displayId,
- msg->body.motion.action,
- msg->body.motion.actionButton,
- msg->body.motion.flags,
- msg->body.motion.edgeFlags,
- msg->body.motion.metaState,
- msg->body.motion.buttonState,
- msg->body.motion.classification,
- msg->body.motion.xOffset,
- msg->body.motion.yOffset,
- msg->body.motion.xPrecision,
- msg->body.motion.yPrecision,
- msg->body.motion.downTime,
- msg->body.motion.eventTime,
- pointerCount,
- pointerProperties,
- pointerCoords);
+ event->initialize(msg->body.motion.deviceId, msg->body.motion.source,
+ msg->body.motion.displayId, msg->body.motion.action,
+ msg->body.motion.actionButton, msg->body.motion.flags,
+ msg->body.motion.edgeFlags, msg->body.motion.metaState,
+ msg->body.motion.buttonState, msg->body.motion.classification,
+ msg->body.motion.xOffset, msg->body.motion.yOffset,
+ msg->body.motion.xPrecision, msg->body.motion.yPrecision,
+ msg->body.motion.xCursorPosition, msg->body.motion.yCursorPosition,
+ msg->body.motion.downTime, msg->body.motion.eventTime, pointerCount,
+ pointerProperties, pointerCoords);
}
void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index 2b75c82..ec34f3e 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -255,11 +255,11 @@
pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 27);
pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, AMOTION_EVENT_ACTION_MOVE, 0,
- AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
- AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
- MotionClassification::NONE, X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
- ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME,
- 2, pointerProperties, pointerCoords);
+ AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, AMOTION_EVENT_EDGE_FLAG_TOP,
+ AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY, MotionClassification::NONE,
+ X_OFFSET, Y_OFFSET, 2.0f, 2.1f, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, 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);
@@ -571,10 +571,11 @@
}
MotionEvent event;
event.initialize(0 /*deviceId*/, AINPUT_SOURCE_UNKNOWN, DISPLAY_ID, AMOTION_EVENT_ACTION_MOVE,
- 0 /*actionButton*/, 0 /*flags*/, AMOTION_EVENT_EDGE_FLAG_NONE,
- AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE,
- 0 /*xOffset*/, 0 /*yOffset*/, 0 /*xPrecision*/, 0 /*yPrecision*/,
- 0 /*downTime*/, 0 /*eventTime*/, pointerCount, pointerProperties, pointerCoords);
+ 0 /*actionButton*/, 0 /*flags*/, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE,
+ 0 /*buttonState*/, MotionClassification::NONE, 0 /*xOffset*/, 0 /*yOffset*/,
+ 0 /*xPrecision*/, 0 /*yPrecision*/, 3 + RADIUS /*xCursorPosition*/,
+ 2 /*yCursorPosition*/, 0 /*downTime*/, 0 /*eventTime*/, pointerCount,
+ pointerProperties, pointerCoords);
float originalRawX = 0 + 3;
float originalRawY = -RADIUS + 2;
@@ -602,6 +603,10 @@
ASSERT_NEAR(tanf(angle), tanf(event.getOrientation(i)), 0.1);
}
+ // Check cursor positions.
+ ASSERT_NEAR(sinf(PI_180 * (90 + ROTATION)) * RADIUS, event.getXCursorPosition(), 0.001);
+ ASSERT_NEAR(-cosf(PI_180 * (90 + ROTATION)) * RADIUS, event.getYCursorPosition(), 0.001);
+
// Applying the transformation should preserve the raw X and Y of the first point.
ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
@@ -626,11 +631,34 @@
for (MotionClassification classification : classifications) {
event.initialize(0 /*deviceId*/, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
- AMOTION_EVENT_ACTION_DOWN, 0, 0, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0,
- classification, 0, 0, 0, 0, 0 /*downTime*/, 0 /*eventTime*/,
- pointerCount, pointerProperties, pointerCoords);
+ AMOTION_EVENT_ACTION_DOWN, 0, 0, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE,
+ 0, classification, 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, 0 /*downTime*/, 0 /*eventTime*/,
+ pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(classification, event.getClassification());
}
}
+TEST_F(MotionEventTest, Initialize_SetsCursorPosition) {
+ MotionEvent event;
+ constexpr size_t pointerCount = 1;
+ PointerProperties pointerProperties[pointerCount];
+ PointerCoords pointerCoords[pointerCount];
+ for (size_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].clear();
+ pointerProperties[i].id = i;
+ pointerCoords[i].clear();
+ }
+
+ event.initialize(0 /*deviceId*/, AINPUT_SOURCE_MOUSE, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0,
+ 0, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0, MotionClassification::NONE, 0,
+ 0, 0, 0, 280 /*xCursorPosition*/, 540 /*yCursorPosition*/, 0 /*downTime*/,
+ 0 /*eventTime*/, pointerCount, pointerProperties, pointerCoords);
+ event.offsetLocation(20, 60);
+ ASSERT_EQ(280, event.getRawXCursorPosition());
+ ASSERT_EQ(540, event.getRawYCursorPosition());
+ ASSERT_EQ(300, event.getXCursorPosition());
+ ASSERT_EQ(600, event.getYCursorPosition());
+}
+
} // namespace android
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
index f2cd1be..a362f32 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -146,6 +146,8 @@
constexpr float yOffset = -20;
constexpr float xPrecision = 0.25;
constexpr float yPrecision = 0.5;
+ constexpr float xCursorPosition = 1.3;
+ constexpr float yCursorPosition = 50.6;
constexpr nsecs_t downTime = 3;
constexpr size_t pointerCount = 3;
constexpr nsecs_t eventTime = 4;
@@ -168,10 +170,12 @@
pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i);
}
- status = mPublisher->publishMotionEvent(seq, deviceId, source, displayId, action, actionButton,
- flags, edgeFlags, metaState, buttonState, classification,
- xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount,
- pointerProperties, pointerCoords);
+ status =
+ mPublisher->publishMotionEvent(seq, deviceId, source, displayId, action, actionButton,
+ flags, edgeFlags, metaState, buttonState, classification,
+ xOffset, yOffset, xPrecision, yPrecision,
+ xCursorPosition, yCursorPosition, downTime, eventTime,
+ pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(OK, status)
<< "publisher publishMotionEvent should return OK";
@@ -199,6 +203,10 @@
EXPECT_EQ(classification, motionEvent->getClassification());
EXPECT_EQ(xPrecision, motionEvent->getXPrecision());
EXPECT_EQ(yPrecision, motionEvent->getYPrecision());
+ EXPECT_EQ(xCursorPosition, motionEvent->getRawXCursorPosition());
+ EXPECT_EQ(yCursorPosition, motionEvent->getRawYCursorPosition());
+ EXPECT_EQ(xCursorPosition + xOffset, motionEvent->getXCursorPosition());
+ EXPECT_EQ(yCursorPosition + yOffset, motionEvent->getYCursorPosition());
EXPECT_EQ(downTime, motionEvent->getDownTime());
EXPECT_EQ(eventTime, motionEvent->getEventTime());
EXPECT_EQ(pointerCount, motionEvent->getPointerCount());
@@ -266,9 +274,11 @@
pointerCoords[i].clear();
}
- status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- MotionClassification::NONE, 0, 0, 0, 0, 0, 0,
- pointerCount, pointerProperties, pointerCoords);
+ status =
+ mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MotionClassification::NONE,
+ 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
+ pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(BAD_VALUE, status)
<< "publisher publishMotionEvent should return BAD_VALUE";
}
@@ -279,9 +289,11 @@
PointerProperties pointerProperties[pointerCount];
PointerCoords pointerCoords[pointerCount];
- status = mPublisher->publishMotionEvent(1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- MotionClassification::NONE, 0, 0, 0, 0, 0, 0,
- pointerCount, pointerProperties, pointerCoords);
+ status =
+ mPublisher->publishMotionEvent(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, MotionClassification::NONE,
+ 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, 0,
+ pointerCount, pointerProperties, pointerCoords);
ASSERT_EQ(BAD_VALUE, status)
<< "publisher publishMotionEvent should return BAD_VALUE";
}
@@ -297,9 +309,11 @@
pointerCoords[i].clear();
}
- status = mPublisher->publishMotionEvent(1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- MotionClassification::NONE, 0, 0, 0, 0, 0, 0,
- pointerCount, pointerProperties, pointerCoords);
+ status =
+ mPublisher->publishMotionEvent(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, MotionClassification::NONE,
+ 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, 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 62023fb..8d8cf06 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -64,8 +64,10 @@
CHECK_OFFSET(InputMessage::Body::Motion, yOffset, 68);
CHECK_OFFSET(InputMessage::Body::Motion, xPrecision, 72);
CHECK_OFFSET(InputMessage::Body::Motion, yPrecision, 76);
- CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 80);
- CHECK_OFFSET(InputMessage::Body::Motion, pointers, 88);
+ CHECK_OFFSET(InputMessage::Body::Motion, xCursorPosition, 80);
+ CHECK_OFFSET(InputMessage::Body::Motion, yCursorPosition, 84);
+ CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 88);
+ CHECK_OFFSET(InputMessage::Body::Motion, pointers, 96);
CHECK_OFFSET(InputMessage::Body::Finished, seq, 0);
CHECK_OFFSET(InputMessage::Body::Finished, handled, 4);
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index 368446f..968e2fa 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -176,12 +176,13 @@
EXPECT_EQ(pointerIndex, pointerCount);
MotionEvent event;
- event.initialize(0 /*deviceId*/, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
- action, 0 /*actionButton*/, 0 /*flags*/,
- AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
- MotionClassification::NONE,
- 0 /*xOffset*/, 0 /*yOffset*/, 0 /*xPrecision*/, 0 /*yPrecision*/,
- 0 /*downTime*/, entry.eventTime.count(), pointerCount, properties, coords);
+ event.initialize(0 /*deviceId*/, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, action,
+ 0 /*actionButton*/, 0 /*flags*/, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE,
+ 0 /*buttonState*/, MotionClassification::NONE, 0 /*xOffset*/,
+ 0 /*yOffset*/, 0 /*xPrecision*/, 0 /*yPrecision*/,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, 0 /*downTime*/,
+ entry.eventTime.count(), pointerCount, properties, coords);
events.emplace_back(event);
}
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index c2ff4c9..b323099 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -262,14 +262,18 @@
// --- InputDispatcher ---
-InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
- mPolicy(policy),
- mPendingEvent(nullptr), mLastDropReason(DROP_REASON_NOT_DROPPED),
- mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
- mNextUnblockedEvent(nullptr),
- mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
- mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
- mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
+InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
+ : mPolicy(policy),
+ mPendingEvent(nullptr),
+ mLastDropReason(DROP_REASON_NOT_DROPPED),
+ mAppSwitchSawKeyDown(false),
+ mAppSwitchDueTime(LONG_LONG_MAX),
+ mNextUnblockedEvent(nullptr),
+ mDispatchEnabled(false),
+ mDispatchFrozen(false),
+ mInputFilterEnabled(false),
+ mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
+ mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
mLooper = new Looper(false);
mReporter = createInputReporter();
@@ -1326,6 +1330,7 @@
bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
|| maskedAction == AMOTION_EVENT_ACTION_SCROLL
|| isHoverAction);
+ const bool isFromMouse = entry->source == AINPUT_SOURCE_MOUSE;
bool wrongDevice = false;
if (newGesture) {
bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
@@ -1361,11 +1366,17 @@
if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
/* Case 1: New splittable pointer going down, or need target for hover or scroll. */
+ int32_t x;
+ int32_t y;
int32_t pointerIndex = getMotionEventActionPointerIndex(action);
- int32_t x = int32_t(entry->pointerCoords[pointerIndex].
- getAxisValue(AMOTION_EVENT_AXIS_X));
- int32_t y = int32_t(entry->pointerCoords[pointerIndex].
- getAxisValue(AMOTION_EVENT_AXIS_Y));
+ // Always dispatch mouse events to cursor position.
+ if (isFromMouse) {
+ x = int32_t(entry->xCursorPosition);
+ y = int32_t(entry->yCursorPosition);
+ } else {
+ x = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
+ y = int32_t(entry->pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
+ }
bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(
displayId, x, y, isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
@@ -2256,15 +2267,21 @@
}
// Publish the motion event.
- status = connection->inputPublisher.publishMotionEvent(dispatchEntry->seq,
- motionEntry->deviceId, motionEntry->source, motionEntry->displayId,
- dispatchEntry->resolvedAction, motionEntry->actionButton,
- dispatchEntry->resolvedFlags, motionEntry->edgeFlags,
- motionEntry->metaState, motionEntry->buttonState, motionEntry->classification,
- xOffset, yOffset, motionEntry->xPrecision, motionEntry->yPrecision,
- motionEntry->downTime, motionEntry->eventTime,
- motionEntry->pointerCount, motionEntry->pointerProperties,
- usingCoords);
+ status =
+ connection->inputPublisher
+ .publishMotionEvent(dispatchEntry->seq, motionEntry->deviceId,
+ motionEntry->source, motionEntry->displayId,
+ dispatchEntry->resolvedAction,
+ motionEntry->actionButton,
+ dispatchEntry->resolvedFlags,
+ motionEntry->edgeFlags, motionEntry->metaState,
+ motionEntry->buttonState,
+ motionEntry->classification, xOffset, yOffset,
+ motionEntry->xPrecision, motionEntry->yPrecision,
+ motionEntry->xCursorPosition,
+ motionEntry->yCursorPosition, motionEntry->downTime,
+ motionEntry->eventTime, motionEntry->pointerCount,
+ motionEntry->pointerProperties, usingCoords);
break;
}
@@ -2590,24 +2607,17 @@
}
}
- MotionEntry* splitMotionEntry = new MotionEntry(
- originalMotionEntry->sequenceNum,
- originalMotionEntry->eventTime,
- originalMotionEntry->deviceId,
- originalMotionEntry->source,
- originalMotionEntry->displayId,
- originalMotionEntry->policyFlags,
- action,
- originalMotionEntry->actionButton,
- originalMotionEntry->flags,
- originalMotionEntry->metaState,
- originalMotionEntry->buttonState,
- originalMotionEntry->classification,
- originalMotionEntry->edgeFlags,
- originalMotionEntry->xPrecision,
- originalMotionEntry->yPrecision,
- originalMotionEntry->downTime,
- splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
+ MotionEntry* splitMotionEntry =
+ new MotionEntry(originalMotionEntry->sequenceNum, originalMotionEntry->eventTime,
+ originalMotionEntry->deviceId, originalMotionEntry->source,
+ originalMotionEntry->displayId, originalMotionEntry->policyFlags,
+ action, originalMotionEntry->actionButton, originalMotionEntry->flags,
+ originalMotionEntry->metaState, originalMotionEntry->buttonState,
+ originalMotionEntry->classification, originalMotionEntry->edgeFlags,
+ originalMotionEntry->xPrecision, originalMotionEntry->yPrecision,
+ originalMotionEntry->xCursorPosition,
+ originalMotionEntry->yCursorPosition, originalMotionEntry->downTime,
+ splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
if (originalMotionEntry->injectionState) {
splitMotionEntry->injectionState = originalMotionEntry->injectionState;
@@ -2753,12 +2763,14 @@
void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
ALOGD("notifyMotion - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
- ", policyFlags=0x%x, "
- "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x,"
- "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
- args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
- args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
- args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
+ ", policyFlags=0x%x, "
+ "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
+ "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
+ "mYCursorPosition=%f, downTime=%" PRId64,
+ args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
+ args->action, args->actionButton, args->flags, args->metaState, args->buttonState,
+ args->edgeFlags, args->xPrecision, args->yPrecision, arg->xCursorPosition,
+ args->yCursorPosition, args->downTime);
for (uint32_t i = 0; i < args->pointerCount; i++) {
ALOGD(" Pointer %d: id=%d, toolType=%d, "
"x=%f, y=%f, pressure=%f, size=%f, "
@@ -2800,12 +2812,12 @@
mLock.unlock();
MotionEvent event;
- event.initialize(args->deviceId, args->source, args->displayId,
- args->action, args->actionButton,
- args->flags, args->edgeFlags, args->metaState, args->buttonState,
- args->classification, 0, 0, args->xPrecision, args->yPrecision,
- args->downTime, args->eventTime,
- args->pointerCount, args->pointerProperties, args->pointerCoords);
+ event.initialize(args->deviceId, args->source, args->displayId, args->action,
+ args->actionButton, args->flags, args->edgeFlags, args->metaState,
+ args->buttonState, args->classification, 0, 0, args->xPrecision,
+ args->yPrecision, args->xCursorPosition, args->yCursorPosition,
+ args->downTime, args->eventTime, args->pointerCount,
+ args->pointerProperties, args->pointerCoords);
policyFlags |= POLICY_FLAG_FILTERED;
if (!mPolicy->filterInputEvent(&event, policyFlags)) {
@@ -2816,12 +2828,14 @@
}
// Just enqueue a new motion event.
- MotionEntry* newEntry = new MotionEntry(args->sequenceNum, args->eventTime,
- args->deviceId, args->source, args->displayId, policyFlags,
- args->action, args->actionButton, args->flags,
- args->metaState, args->buttonState, args->classification,
- args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
- args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0);
+ MotionEntry* newEntry =
+ new MotionEntry(args->sequenceNum, args->eventTime, args->deviceId, args->source,
+ args->displayId, policyFlags, args->action, args->actionButton,
+ args->flags, args->metaState, args->buttonState,
+ args->classification, args->edgeFlags, args->xPrecision,
+ args->yPrecision, args->xCursorPosition, args->yCursorPosition,
+ args->downTime, args->pointerCount, args->pointerProperties,
+ args->pointerCoords, 0, 0);
needWake = enqueueInboundEventLocked(newEntry);
mLock.unlock();
@@ -2952,31 +2966,34 @@
mLock.lock();
const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
- firstInjectedEntry = new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
- motionEvent->getDeviceId(), motionEvent->getSource(), motionEvent->getDisplayId(),
- policyFlags,
- action, actionButton, motionEvent->getFlags(),
- motionEvent->getMetaState(), motionEvent->getButtonState(),
- motionEvent->getClassification(), motionEvent->getEdgeFlags(),
- motionEvent->getXPrecision(), motionEvent->getYPrecision(),
- motionEvent->getDownTime(),
- uint32_t(pointerCount), pointerProperties, samplePointerCoords,
- motionEvent->getXOffset(), motionEvent->getYOffset());
+ firstInjectedEntry =
+ new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
+ motionEvent->getDeviceId(), motionEvent->getSource(),
+ motionEvent->getDisplayId(), policyFlags, action, actionButton,
+ motionEvent->getFlags(), motionEvent->getMetaState(),
+ motionEvent->getButtonState(), motionEvent->getClassification(),
+ motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
+ motionEvent->getYPrecision(), motionEvent->getRawXCursorPosition(),
+ motionEvent->getRawYCursorPosition(), motionEvent->getDownTime(),
+ uint32_t(pointerCount), pointerProperties, samplePointerCoords,
+ motionEvent->getXOffset(), motionEvent->getYOffset());
lastInjectedEntry = firstInjectedEntry;
for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
sampleEventTimes += 1;
samplePointerCoords += pointerCount;
- MotionEntry* nextInjectedEntry = new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM,
- *sampleEventTimes,
- motionEvent->getDeviceId(), motionEvent->getSource(),
- motionEvent->getDisplayId(), policyFlags,
- action, actionButton, motionEvent->getFlags(),
- motionEvent->getMetaState(), motionEvent->getButtonState(),
- motionEvent->getClassification(), motionEvent->getEdgeFlags(),
- motionEvent->getXPrecision(), motionEvent->getYPrecision(),
- motionEvent->getDownTime(),
- uint32_t(pointerCount), pointerProperties, samplePointerCoords,
- motionEvent->getXOffset(), motionEvent->getYOffset());
+ MotionEntry* nextInjectedEntry =
+ new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes,
+ motionEvent->getDeviceId(), motionEvent->getSource(),
+ motionEvent->getDisplayId(), policyFlags, action, actionButton,
+ motionEvent->getFlags(), motionEvent->getMetaState(),
+ motionEvent->getButtonState(), motionEvent->getClassification(),
+ motionEvent->getEdgeFlags(), motionEvent->getXPrecision(),
+ motionEvent->getYPrecision(),
+ motionEvent->getRawXCursorPosition(),
+ motionEvent->getRawYCursorPosition(),
+ motionEvent->getDownTime(), uint32_t(pointerCount),
+ pointerProperties, samplePointerCoords,
+ motionEvent->getXOffset(), motionEvent->getYOffset());
lastInjectedEntry->next = nextInjectedEntry;
lastInjectedEntry = nextInjectedEntry;
}
@@ -4633,21 +4650,32 @@
// --- InputDispatcher::MotionEntry ---
-InputDispatcher::MotionEntry::MotionEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId,
- uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
- int32_t actionButton,
+InputDispatcher::MotionEntry::MotionEntry(
+ uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
+ int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification,
- int32_t edgeFlags, float xPrecision, float yPrecision, nsecs_t downTime,
- uint32_t pointerCount,
+ 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) :
- EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
+ float xOffset, float yOffset)
+ : EventEntry(sequenceNum, TYPE_MOTION, eventTime, policyFlags),
eventTime(eventTime),
- deviceId(deviceId), source(source), displayId(displayId), action(action),
- actionButton(actionButton), flags(flags), metaState(metaState), buttonState(buttonState),
- classification(classification), edgeFlags(edgeFlags),
- xPrecision(xPrecision), yPrecision(yPrecision),
- downTime(downTime), pointerCount(pointerCount) {
+ deviceId(deviceId),
+ source(source),
+ displayId(displayId),
+ action(action),
+ actionButton(actionButton),
+ flags(flags),
+ metaState(metaState),
+ buttonState(buttonState),
+ classification(classification),
+ edgeFlags(edgeFlags),
+ xPrecision(xPrecision),
+ yPrecision(yPrecision),
+ xCursorPosition(xCursorPosition),
+ yCursorPosition(yCursorPosition),
+ downTime(downTime),
+ pointerCount(pointerCount) {
for (uint32_t i = 0; i < pointerCount; i++) {
this->pointerProperties[i].copyFrom(pointerProperties[i]);
this->pointerCoords[i].copyFrom(pointerCoords[i]);
@@ -4662,11 +4690,14 @@
void InputDispatcher::MotionEntry::appendDescription(std::string& msg) const {
msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
- ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, "
- "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, pointers=[",
- deviceId, source, displayId, motionActionToString(action).c_str(), actionButton, flags,
- metaState, buttonState, motionClassificationToString(classification), edgeFlags,
- xPrecision, yPrecision);
+ ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
+ "buttonState=0x%08x, "
+ "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
+ "xCursorPosition=%0.1f, yCursorPosition=%0.1f, pointers=[",
+ deviceId, source, displayId, motionActionToString(action).c_str(),
+ actionButton, flags, metaState, buttonState,
+ motionClassificationToString(classification), edgeFlags, xPrecision,
+ yPrecision, xCursorPosition, yCursorPosition);
for (uint32_t i = 0; i < pointerCount; i++) {
if (i) {
@@ -4936,6 +4967,8 @@
memento.flags = flags;
memento.xPrecision = entry->xPrecision;
memento.yPrecision = entry->yPrecision;
+ memento.xCursorPosition = entry->xCursorPosition;
+ memento.yCursorPosition = entry->yCursorPosition;
memento.downTime = entry->downTime;
memento.setPointers(entry);
memento.hovering = hovering;
@@ -4966,13 +4999,16 @@
if (shouldCancelMotion(memento, options)) {
const int32_t action = memento.hovering ?
AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
- outEvents.push_back(new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime,
- memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
- action, 0 /*actionButton*/, memento.flags, AMETA_NONE, 0 /*buttonState*/,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
- memento.xPrecision, memento.yPrecision, memento.downTime,
- memento.pointerCount, memento.pointerProperties, memento.pointerCoords,
- 0 /*xOffset*/, 0 /*yOffset*/));
+ outEvents.push_back(
+ new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId,
+ memento.source, memento.displayId, memento.policyFlags, action,
+ 0 /*actionButton*/, memento.flags, AMETA_NONE,
+ 0 /*buttonState*/, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
+ memento.yPrecision, memento.xCursorPosition,
+ memento.yCursorPosition, memento.downTime, memento.pointerCount,
+ memento.pointerProperties, memento.pointerCoords, 0 /*xOffset*/,
+ 0 /*yOffset*/));
}
}
}
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 753b748..46dd9bd 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -570,19 +570,21 @@
int32_t edgeFlags;
float xPrecision;
float yPrecision;
+ float xCursorPosition;
+ float yCursorPosition;
nsecs_t downTime;
uint32_t pointerCount;
PointerProperties pointerProperties[MAX_POINTERS];
PointerCoords pointerCoords[MAX_POINTERS];
- MotionEntry(uint32_t sequenceNum, nsecs_t eventTime,
- int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags,
- int32_t action, int32_t actionButton, int32_t flags,
- int32_t metaState, int32_t buttonState, MotionClassification classification,
- int32_t edgeFlags, float xPrecision, float yPrecision,
- nsecs_t downTime, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
- float xOffset, float yOffset);
+ MotionEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
+ int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
+ int32_t flags, 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);
virtual void appendDescription(std::string& msg) const;
protected:
@@ -830,6 +832,8 @@
int32_t flags;
float xPrecision;
float yPrecision;
+ float xCursorPosition;
+ float yCursorPosition;
nsecs_t downTime;
uint32_t pointerCount;
PointerProperties pointerProperties[MAX_POINTERS];
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index 423b69c..0498e87 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -21,6 +21,7 @@
#include "InputListener.h"
#include <android/log.h>
+#include <math.h>
namespace android {
@@ -87,21 +88,33 @@
// --- NotifyMotionArgs ---
-NotifyMotionArgs::NotifyMotionArgs(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId,
- uint32_t source, int32_t displayId, uint32_t policyFlags,
- int32_t action, int32_t actionButton, int32_t flags, int32_t metaState,
- int32_t buttonState, MotionClassification classification,
+NotifyMotionArgs::NotifyMotionArgs(
+ uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
+ int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
+ int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification,
int32_t edgeFlags, uint32_t deviceTimestamp, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime,
- const std::vector<TouchVideoFrame>& videoFrames) :
- NotifyArgs(sequenceNum, eventTime), deviceId(deviceId), source(source),
- displayId(displayId), policyFlags(policyFlags),
- action(action), actionButton(actionButton),
- flags(flags), metaState(metaState), buttonState(buttonState),
- classification(classification), edgeFlags(edgeFlags), deviceTimestamp(deviceTimestamp),
+ float xPrecision, float yPrecision, float xCursorPosition, float yCursorPosition,
+ nsecs_t downTime, const std::vector<TouchVideoFrame>& videoFrames)
+ : NotifyArgs(sequenceNum, eventTime),
+ deviceId(deviceId),
+ source(source),
+ displayId(displayId),
+ policyFlags(policyFlags),
+ action(action),
+ actionButton(actionButton),
+ flags(flags),
+ metaState(metaState),
+ buttonState(buttonState),
+ classification(classification),
+ edgeFlags(edgeFlags),
+ deviceTimestamp(deviceTimestamp),
pointerCount(pointerCount),
- xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime),
+ xPrecision(xPrecision),
+ yPrecision(yPrecision),
+ xCursorPosition(xCursorPosition),
+ yCursorPosition(yCursorPosition),
+ downTime(downTime),
videoFrames(videoFrames) {
for (uint32_t i = 0; i < pointerCount; i++) {
this->pointerProperties[i].copyFrom(pointerProperties[i]);
@@ -109,14 +122,26 @@
}
}
-NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other) :
- NotifyArgs(other.sequenceNum, other.eventTime), deviceId(other.deviceId),
- source(other.source), displayId(other.displayId), policyFlags(other.policyFlags),
- action(other.action), actionButton(other.actionButton), flags(other.flags),
- metaState(other.metaState), buttonState(other.buttonState),
- classification(other.classification), edgeFlags(other.edgeFlags),
- deviceTimestamp(other.deviceTimestamp), pointerCount(other.pointerCount),
- xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime),
+NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other)
+ : NotifyArgs(other.sequenceNum, other.eventTime),
+ deviceId(other.deviceId),
+ source(other.source),
+ displayId(other.displayId),
+ policyFlags(other.policyFlags),
+ action(other.action),
+ actionButton(other.actionButton),
+ flags(other.flags),
+ metaState(other.metaState),
+ buttonState(other.buttonState),
+ classification(other.classification),
+ edgeFlags(other.edgeFlags),
+ deviceTimestamp(other.deviceTimestamp),
+ pointerCount(other.pointerCount),
+ xPrecision(other.xPrecision),
+ yPrecision(other.yPrecision),
+ xCursorPosition(other.xCursorPosition),
+ yCursorPosition(other.yCursorPosition),
+ downTime(other.downTime),
videoFrames(other.videoFrames) {
for (uint32_t i = 0; i < pointerCount; i++) {
pointerProperties[i].copyFrom(other.pointerProperties[i]);
@@ -124,28 +149,23 @@
}
}
+static inline bool isCursorPositionEqual(float lhs, float rhs) {
+ return (isnan(lhs) && isnan(rhs)) || lhs == rhs;
+}
+
bool NotifyMotionArgs::operator==(const NotifyMotionArgs& rhs) const {
- bool equal =
- sequenceNum == rhs.sequenceNum
- && eventTime == rhs.eventTime
- && deviceId == rhs.deviceId
- && source == rhs.source
- && displayId == rhs.displayId
- && policyFlags == rhs.policyFlags
- && action == rhs.action
- && actionButton == rhs.actionButton
- && flags == rhs.flags
- && metaState == rhs.metaState
- && buttonState == rhs.buttonState
- && classification == rhs.classification
- && edgeFlags == rhs.edgeFlags
- && deviceTimestamp == rhs.deviceTimestamp
- && pointerCount == rhs.pointerCount
+ bool equal = sequenceNum == rhs.sequenceNum && eventTime == rhs.eventTime &&
+ deviceId == rhs.deviceId && source == rhs.source && displayId == rhs.displayId &&
+ policyFlags == rhs.policyFlags && action == rhs.action &&
+ actionButton == rhs.actionButton && flags == rhs.flags && metaState == rhs.metaState &&
+ buttonState == rhs.buttonState && classification == rhs.classification &&
+ edgeFlags == rhs.edgeFlags && deviceTimestamp == rhs.deviceTimestamp &&
+ pointerCount == rhs.pointerCount
// PointerProperties and PointerCoords are compared separately below
- && xPrecision == rhs.xPrecision
- && yPrecision == rhs.yPrecision
- && downTime == rhs.downTime
- && videoFrames == rhs.videoFrames;
+ && xPrecision == rhs.xPrecision && yPrecision == rhs.yPrecision &&
+ isCursorPositionEqual(xCursorPosition, rhs.xCursorPosition) &&
+ isCursorPositionEqual(yCursorPosition, rhs.yCursorPosition) &&
+ downTime == rhs.downTime && videoFrames == rhs.videoFrames;
if (!equal) {
return false;
}
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index a45b8a5..9e59909 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -2782,6 +2782,8 @@
mPointerVelocityControl.move(when, &deltaX, &deltaY);
int32_t displayId;
+ float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
+ float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
if (mSource == AINPUT_SOURCE_MOUSE) {
if (moved || scrolled || buttonsChanged) {
mPointerController->setPresentation(
@@ -2798,10 +2800,9 @@
mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
}
- float x, y;
- mPointerController->getPosition(&x, &y);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+ mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, xCursorPosition);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, yCursorPosition);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
displayId = mPointerController->getDisplayId();
@@ -2845,21 +2846,25 @@
int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());
buttonState &= ~actionButton;
NotifyMotionArgs releaseArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
- metaState, buttonState,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
- /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
- mXPrecision, mYPrecision, downTime, /* videoFrames */ {});
+ mSource, displayId, policyFlags,
+ AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
+ metaState, buttonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0, 1, &pointerProperties,
+ &pointerCoords, mXPrecision, mYPrecision,
+ xCursorPosition, yCursorPosition, downTime,
+ /* videoFrames */ {});
getListener()->notifyMotion(&releaseArgs);
}
}
NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
- displayId, policyFlags, motionEventAction, 0, 0, metaState, currentButtonState,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
- /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
- mXPrecision, mYPrecision, downTime, /* videoFrames */ {});
+ displayId, policyFlags, motionEventAction, 0, 0, metaState,
+ currentButtonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ mXPrecision, mYPrecision, xCursorPosition, yCursorPosition, downTime,
+ /* videoFrames */ {});
getListener()->notifyMotion(&args);
if (buttonsPressed) {
@@ -2868,11 +2873,14 @@
int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());
buttonState |= actionButton;
NotifyMotionArgs pressArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags, AMOTION_EVENT_ACTION_BUTTON_PRESS,
- actionButton, 0, metaState, buttonState,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
- /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
- mXPrecision, mYPrecision, downTime, /* videoFrames */ {});
+ mSource, displayId, policyFlags,
+ AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
+ metaState, buttonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0, 1, &pointerProperties,
+ &pointerCoords, mXPrecision, mYPrecision,
+ xCursorPosition, yCursorPosition, downTime,
+ /* videoFrames */ {});
getListener()->notifyMotion(&pressArgs);
}
}
@@ -2882,12 +2890,14 @@
// Send hover move after UP to tell the application that the mouse is hovering now.
if (motionEventAction == AMOTION_EVENT_ACTION_UP
&& (mSource == AINPUT_SOURCE_MOUSE)) {
- NotifyMotionArgs hoverArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
- metaState, currentButtonState,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
- /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
- mXPrecision, mYPrecision, downTime, /* videoFrames */ {});
+ NotifyMotionArgs hoverArgs(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
+ 0, metaState, currentButtonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0, 1, &pointerProperties,
+ &pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
+ yCursorPosition, downTime,
+ /* videoFrames */ {});
getListener()->notifyMotion(&hoverArgs);
}
@@ -2897,11 +2907,14 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
NotifyMotionArgs scrollArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, currentButtonState,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
- /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
- mXPrecision, mYPrecision, downTime, /* videoFrames */ {});
+ mSource, displayId, policyFlags,
+ AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState,
+ currentButtonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0, 1, &pointerProperties,
+ &pointerCoords, mXPrecision, mYPrecision, xCursorPosition,
+ yCursorPosition, downTime,
+ /* videoFrames */ {});
getListener()->notifyMotion(&scrollArgs);
}
}
@@ -3041,12 +3054,13 @@
int32_t metaState = mContext->getGlobalMetaState();
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_SCROLL, scroll * mScalingFactor);
- NotifyMotionArgs scrollArgs(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, /* buttonState */ 0,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
- /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
- 0, 0, 0, /* videoFrames */ {});
+ NotifyMotionArgs scrollArgs(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0,
+ metaState, /* buttonState */ 0, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
+ 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, /* videoFrames */ {});
getListener()->notifyMotion(&scrollArgs);
}
@@ -5450,12 +5464,12 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
const int32_t displayId = mPointerController->getDisplayId();
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
- metaState, buttonState, MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
- /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,
- 0, 0, mPointerGesture.downTime, /* videoFrames */ {});
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
+ metaState, buttonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords, 0, 0,
+ x, y, mPointerGesture.downTime, /* videoFrames */ {});
getListener()->notifyMotion(&args);
}
@@ -6360,29 +6374,31 @@
int32_t metaState = getContext()->getGlobalMetaState();
int32_t displayId = mViewport.displayId;
- if (mPointerController != nullptr) {
- if (down || hovering) {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
- mPointerController->clearSpots();
- mPointerController->setButtonState(mCurrentRawState.buttonState);
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
- } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
- displayId = mPointerController->getDisplayId();
+ if (down || hovering) {
+ mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+ mPointerController->clearSpots();
+ mPointerController->setButtonState(mCurrentRawState.buttonState);
+ mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
}
+ displayId = mPointerController->getDisplayId();
+
+ float xCursorPosition;
+ float yCursorPosition;
+ mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
if (mPointerSimple.down && !down) {
mPointerSimple.down = false;
// Send up.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_UP, 0, 0, metaState, mLastRawState.buttonState,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0,
- 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime, /* videoFrames */ {});
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_UP, 0, 0, metaState,
+ mLastRawState.buttonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1,
+ &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
+ mOrientedXPrecision, mOrientedYPrecision, xCursorPosition,
+ yCursorPosition, mPointerSimple.downTime, /* videoFrames */ {});
getListener()->notifyMotion(&args);
}
@@ -6390,13 +6406,13 @@
mPointerSimple.hovering = false;
// Send hover exit.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState, mLastRawState.buttonState,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0,
- 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime, /* videoFrames */ {});
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0,
+ metaState, mLastRawState.buttonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1,
+ &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
+ mOrientedXPrecision, mOrientedYPrecision, xCursorPosition,
+ yCursorPosition, mPointerSimple.downTime, /* videoFrames */ {});
getListener()->notifyMotion(&args);
}
@@ -6406,25 +6422,25 @@
mPointerSimple.downTime = when;
// Send down.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_DOWN, 0, 0, metaState, mCurrentRawState.buttonState,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
- /* deviceTimestamp */ 0,
- 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime, /* videoFrames */ {});
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_DOWN, 0, 0,
+ metaState, mCurrentRawState.buttonState,
+ MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0, 1, &mPointerSimple.currentProperties,
+ &mPointerSimple.currentCoords, mOrientedXPrecision,
+ mOrientedYPrecision, xCursorPosition, yCursorPosition,
+ mPointerSimple.downTime, /* videoFrames */ {});
getListener()->notifyMotion(&args);
}
// Send move.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, mCurrentRawState.buttonState,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0,
- 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime, /* videoFrames */ {});
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState,
+ mCurrentRawState.buttonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1,
+ &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
+ mOrientedXPrecision, mOrientedYPrecision, xCursorPosition,
+ yCursorPosition, mPointerSimple.downTime, /* videoFrames */ {});
getListener()->notifyMotion(&args);
}
@@ -6433,26 +6449,25 @@
mPointerSimple.hovering = true;
// Send hover enter.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0, metaState,
- mCurrentRawState.buttonState, MotionClassification::NONE,
- AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0,
- 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime, /* videoFrames */ {});
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0,
+ metaState, mCurrentRawState.buttonState,
+ MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0, 1, &mPointerSimple.currentProperties,
+ &mPointerSimple.currentCoords, mOrientedXPrecision,
+ mOrientedYPrecision, xCursorPosition, yCursorPosition,
+ mPointerSimple.downTime, /* videoFrames */ {});
getListener()->notifyMotion(&args);
}
// Send hover move.
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
- mCurrentRawState.buttonState, MotionClassification::NONE,
- AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0,
- 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime, /* videoFrames */ {});
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
+ metaState, mCurrentRawState.buttonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1,
+ &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
+ mOrientedXPrecision, mOrientedYPrecision, xCursorPosition,
+ yCursorPosition, mPointerSimple.downTime, /* videoFrames */ {});
getListener()->notifyMotion(&args);
}
@@ -6468,13 +6483,13 @@
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- mSource, displayId, policyFlags,
- AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, mCurrentRawState.buttonState,
- MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0,
- 1, &mPointerSimple.currentProperties, &pointerCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime, /* videoFrames */ {});
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
+ displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState,
+ mCurrentRawState.buttonState, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1,
+ &mPointerSimple.currentProperties, &pointerCoords,
+ mOrientedXPrecision, mOrientedYPrecision, xCursorPosition,
+ yCursorPosition, mPointerSimple.downTime, /* videoFrames */ {});
getListener()->notifyMotion(&args);
}
@@ -6531,16 +6546,21 @@
ALOG_ASSERT(false);
}
}
+ float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
+ float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
+ if (mDeviceMode == DEVICE_MODE_POINTER) {
+ mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
+ }
const int32_t displayId = getAssociatedDisplay().value_or(ADISPLAY_ID_NONE);
const int32_t deviceId = getDeviceId();
std::vector<TouchVideoFrame> frames = mDevice->getEventHub()->getVideoFrames(deviceId);
std::for_each(frames.begin(), frames.end(),
[this](TouchVideoFrame& frame) { frame.rotate(this->mSurfaceOrientation); });
- NotifyMotionArgs args(mContext->getNextSequenceNum(), when, deviceId,
- source, displayId, policyFlags,
- action, actionButton, flags, metaState, buttonState, MotionClassification::NONE,
- edgeFlags, deviceTimestamp, pointerCount, pointerProperties, pointerCoords,
- xPrecision, yPrecision, downTime, std::move(frames));
+ NotifyMotionArgs args(mContext->getNextSequenceNum(), when, deviceId, source, displayId,
+ policyFlags, action, actionButton, flags, metaState, buttonState,
+ MotionClassification::NONE, edgeFlags, deviceTimestamp, pointerCount,
+ pointerProperties, pointerCoords, xPrecision, yPrecision, xCursorPosition,
+ yCursorPosition, downTime, std::move(frames));
getListener()->notifyMotion(&args);
}
@@ -7462,10 +7482,12 @@
uint32_t policyFlags = 0;
NotifyMotionArgs args(mContext->getNextSequenceNum(), when, getDeviceId(),
- AINPUT_SOURCE_JOYSTICK, ADISPLAY_ID_NONE, policyFlags,
- AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState, MotionClassification::NONE,
- AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1,
- &pointerProperties, &pointerCoords, 0, 0, 0, /* videoFrames */ {});
+ AINPUT_SOURCE_JOYSTICK, ADISPLAY_ID_NONE, policyFlags,
+ AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState,
+ MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
+ /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, 0, /* videoFrames */ {});
getListener()->notifyMotion(&args);
}
diff --git a/services/inputflinger/include/InputListener.h b/services/inputflinger/include/InputListener.h
index b51dcb6..57c894b 100644
--- a/services/inputflinger/include/InputListener.h
+++ b/services/inputflinger/include/InputListener.h
@@ -119,19 +119,27 @@
PointerCoords pointerCoords[MAX_POINTERS];
float xPrecision;
float yPrecision;
+ /**
+ * Mouse cursor position when this event is reported relative to the origin of the specified
+ * display. Only valid if this is a mouse event (originates from a mouse or from a trackpad in
+ * gestures enabled mode.
+ */
+ float xCursorPosition;
+ float yCursorPosition;
nsecs_t downTime;
std::vector<TouchVideoFrame> videoFrames;
inline NotifyMotionArgs() { }
NotifyMotionArgs(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
- int32_t displayId, uint32_t policyFlags,
- int32_t action, int32_t actionButton, int32_t flags,
- int32_t metaState, int32_t buttonState, MotionClassification classification,
- int32_t edgeFlags, uint32_t deviceTimestamp, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime,
- const std::vector<TouchVideoFrame>& videoFrames);
+ int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
+ int32_t flags, int32_t metaState, int32_t buttonState,
+ MotionClassification classification, int32_t edgeFlags,
+ uint32_t deviceTimestamp, uint32_t pointerCount,
+ const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
+ float xPrecision, float yPrecision, float xCursorPosition,
+ float yCursorPosition, nsecs_t downTime,
+ const std::vector<TouchVideoFrame>& videoFrames);
NotifyMotionArgs(const NotifyMotionArgs& other);
diff --git a/services/inputflinger/tests/InputClassifierConverter_test.cpp b/services/inputflinger/tests/InputClassifierConverter_test.cpp
index 813b69e..ba1c7c9 100644
--- a/services/inputflinger/tests/InputClassifierConverter_test.cpp
+++ b/services/inputflinger/tests/InputClassifierConverter_test.cpp
@@ -38,12 +38,15 @@
coords.setAxisValue(AMOTION_EVENT_AXIS_Y, 2);
coords.setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.5);
static constexpr nsecs_t downTime = 2;
- NotifyMotionArgs motionArgs(1/*sequenceNum*/, downTime/*eventTime*/, 3/*deviceId*/,
- AINPUT_SOURCE_ANY, ADISPLAY_ID_DEFAULT, 4/*policyFlags*/, AMOTION_EVENT_ACTION_DOWN,
- 0/*actionButton*/, 0/*flags*/, AMETA_NONE, 0/*buttonState*/, MotionClassification::NONE,
- AMOTION_EVENT_EDGE_FLAG_NONE, 5/*deviceTimestamp*/,
- 1/*pointerCount*/, &properties, &coords, 0/*xPrecision*/, 0/*yPrecision*/,
- downTime, {}/*videoFrames*/);
+ NotifyMotionArgs motionArgs(1 /*sequenceNum*/, downTime /*eventTime*/, 3 /*deviceId*/,
+ AINPUT_SOURCE_ANY, ADISPLAY_ID_DEFAULT, 4 /*policyFlags*/,
+ AMOTION_EVENT_ACTION_DOWN, 0 /*actionButton*/, 0 /*flags*/,
+ AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, 5 /*deviceTimestamp*/,
+ 1 /*pointerCount*/, &properties, &coords, 0 /*xPrecision*/,
+ 0 /*yPrecision*/, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, downTime,
+ {} /*videoFrames*/);
return motionArgs;
}
diff --git a/services/inputflinger/tests/InputClassifier_test.cpp b/services/inputflinger/tests/InputClassifier_test.cpp
index 7cc17a2..9bc4282 100644
--- a/services/inputflinger/tests/InputClassifier_test.cpp
+++ b/services/inputflinger/tests/InputClassifier_test.cpp
@@ -38,12 +38,15 @@
coords.setAxisValue(AMOTION_EVENT_AXIS_X, 1);
coords.setAxisValue(AMOTION_EVENT_AXIS_Y, 1);
static constexpr nsecs_t downTime = 2;
- NotifyMotionArgs motionArgs(1/*sequenceNum*/, downTime/*eventTime*/, 3/*deviceId*/,
- AINPUT_SOURCE_ANY, ADISPLAY_ID_DEFAULT, 4/*policyFlags*/, AMOTION_EVENT_ACTION_DOWN,
- 0/*actionButton*/, 0/*flags*/, AMETA_NONE, 0/*buttonState*/, MotionClassification::NONE,
- AMOTION_EVENT_EDGE_FLAG_NONE, 5/*deviceTimestamp*/,
- 1/*pointerCount*/, &properties, &coords, 0/*xPrecision*/, 0/*yPrecision*/,
- downTime, {}/*videoFrames*/);
+ NotifyMotionArgs motionArgs(1 /*sequenceNum*/, downTime /*eventTime*/, 3 /*deviceId*/,
+ AINPUT_SOURCE_ANY, ADISPLAY_ID_DEFAULT, 4 /*policyFlags*/,
+ AMOTION_EVENT_ACTION_DOWN, 0 /*actionButton*/, 0 /*flags*/,
+ AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, 5 /*deviceTimestamp*/,
+ 1 /*pointerCount*/, &properties, &coords, 0 /*xPrecision*/,
+ 0 /*yPrecision*/, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, downTime,
+ {} /*videoFrames*/);
return motionArgs;
}
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 9fe6481..c28a621 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -249,8 +249,10 @@
// Rejects undefined motion actions.
event.initialize(DEVICE_ID, source, DISPLAY_ID,
- /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
+ /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
&event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
@@ -258,18 +260,24 @@
// Rejects pointer down with invalid index.
event.initialize(DEVICE_ID, source, DISPLAY_ID,
- AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
+ AMOTION_EVENT_ACTION_POINTER_DOWN |
+ (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
&event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with pointer down index too large.";
event.initialize(DEVICE_ID, source, DISPLAY_ID,
- AMOTION_EVENT_ACTION_POINTER_DOWN | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
+ AMOTION_EVENT_ACTION_POINTER_DOWN |
+ (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
&event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
@@ -277,36 +285,45 @@
// Rejects pointer up with invalid index.
event.initialize(DEVICE_ID, source, DISPLAY_ID,
- AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
&event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with pointer up index too large.";
event.initialize(DEVICE_ID, source, DISPLAY_ID,
- AMOTION_EVENT_ACTION_POINTER_UP | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
- 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
+ AMOTION_EVENT_ACTION_POINTER_UP |
+ (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
&event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with pointer up index too small.";
// Rejects motion events with invalid number of pointers.
- event.initialize(DEVICE_ID, source, DISPLAY_ID,
- AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 0, pointerProperties, pointerCoords);
+ event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
+ metaState, 0, classification, 0, 0, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 0, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
&event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with 0 pointers.";
- event.initialize(DEVICE_ID, source, DISPLAY_ID,
- AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
- ARBITRARY_TIME, ARBITRARY_TIME,
- /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
+ event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
+ metaState, 0, classification, 0, 0, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
&event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
@@ -314,18 +331,22 @@
// Rejects motion events with invalid pointer ids.
pointerProperties[0].id = -1;
- event.initialize(DEVICE_ID, source, DISPLAY_ID,
- AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
+ event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
+ metaState, 0, classification, 0, 0, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
&event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
<< "Should reject motion events with pointer ids less than 0.";
pointerProperties[0].id = MAX_POINTER_ID + 1;
- event.initialize(DEVICE_ID, source, DISPLAY_ID,
- AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
+ event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
+ metaState, 0, classification, 0, 0, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
&event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
@@ -334,9 +355,11 @@
// Rejects motion events with duplicate pointer ids.
pointerProperties[0].id = 1;
pointerProperties[1].id = 1;
- event.initialize(DEVICE_ID, source, DISPLAY_ID,
- AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
- ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 2, pointerProperties, pointerCoords);
+ event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
+ metaState, 0, classification, 0, 0, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ ARBITRARY_TIME, ARBITRARY_TIME,
+ /*pointerCount*/ 2, pointerProperties, pointerCoords);
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
&event,
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
@@ -463,6 +486,7 @@
mInfo.frameRight = mFrame.right;
mInfo.frameBottom = mFrame.bottom;
mInfo.globalScaleFactor = 1.0;
+ mInfo.touchableRegion.clear();
mInfo.addTouchableRegion(mFrame);
mInfo.visible = true;
mInfo.canReceiveKeys = true;
@@ -521,8 +545,10 @@
INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
}
-static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
- int32_t displayId, int32_t x = 100, int32_t y = 200) {
+static int32_t injectMotionEvent(const sp<InputDispatcher>& dispatcher, int32_t action,
+ int32_t source, int32_t displayId, int32_t x, int32_t y,
+ int32_t xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ int32_t yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION) {
MotionEvent event;
PointerProperties pointerProperties[1];
PointerCoords pointerCoords[1];
@@ -537,12 +563,11 @@
nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
// Define a valid motion down event.
- event.initialize(DEVICE_ID, source, displayId,
- AMOTION_EVENT_ACTION_DOWN, /* actionButton */ 0, /* flags */ 0, /* edgeFlags */ 0,
- AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
- /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
- /* yPrecision */ 0, currentTime, currentTime, /*pointerCount*/ 1, pointerProperties,
- pointerCoords);
+ event.initialize(DEVICE_ID, source, displayId, action, /* actionButton */ 0, /* flags */ 0,
+ /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
+ /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
+ /* yPrecision */ 0, xCursorPosition, yCursorPosition, currentTime, currentTime,
+ /*pointerCount*/ 1, pointerProperties, pointerCoords);
// Inject event until dispatch out.
return dispatcher->injectInputEvent(
@@ -551,6 +576,11 @@
INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
}
+static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
+ int32_t displayId, int32_t x = 100, int32_t y = 200) {
+ return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, x, y);
+}
+
static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
// Define a valid key event.
@@ -576,11 +606,12 @@
nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
// Define a valid motion event.
NotifyMotionArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, source, displayId,
- POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
- AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
- AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1, pointerProperties,
- pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0, currentTime,
- /* videoFrames */ {});
+ POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
+ AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
+ AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1,
+ pointerProperties, pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
return args;
}
@@ -704,6 +735,32 @@
windowSecond->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
}
+TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
+ sp<FakeApplicationHandle> application = new FakeApplicationHandle();
+
+ sp<FakeWindowHandle> windowLeft =
+ new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
+ windowLeft->setFrame(Rect(0, 0, 600, 800));
+ windowLeft->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
+ sp<FakeWindowHandle> windowRight =
+ new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
+ windowRight->setFrame(Rect(600, 0, 1200, 800));
+ windowRight->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
+
+ mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
+
+ std::vector<sp<InputWindowHandle>> inputWindowHandles{windowLeft, windowRight};
+ mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
+
+ // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
+ // left window. This event should be dispatched to the left window.
+ ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
+ ADISPLAY_ID_DEFAULT, 610, 400, 599, 400));
+ windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
+ windowRight->assertNoEvents();
+}
+
/* Test InputDispatcher for MultiDisplay */
class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
public: