diff options
| -rw-r--r-- | services/inputflinger/PointerChoreographer.cpp | 33 | ||||
| -rw-r--r-- | services/inputflinger/include/NotifyArgsBuilders.h | 4 | ||||
| -rw-r--r-- | services/inputflinger/tests/PointerChoreographer_test.cpp | 32 |
3 files changed, 57 insertions, 12 deletions
diff --git a/services/inputflinger/PointerChoreographer.cpp b/services/inputflinger/PointerChoreographer.cpp index 916f8c6b5f..c333814078 100644 --- a/services/inputflinger/PointerChoreographer.cpp +++ b/services/inputflinger/PointerChoreographer.cpp @@ -122,21 +122,32 @@ NotifyMotionArgs PointerChoreographer::processMouseEventLocked(const NotifyMotio } auto [displayId, pc] = ensureMouseControllerLocked(args.displayId); + NotifyMotionArgs newArgs(args); + newArgs.displayId = displayId; - const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X); - const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y); - pc.move(deltaX, deltaY); + if (MotionEvent::isValidCursorPosition(args.xCursorPosition, args.yCursorPosition)) { + // This is an absolute mouse device that knows about the location of the cursor on the + // display, so set the cursor position to the specified location. + const auto [x, y] = pc.getPosition(); + const float deltaX = args.xCursorPosition - x; + const float deltaY = args.yCursorPosition - y; + newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX); + newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); + pc.setPosition(args.xCursorPosition, args.yCursorPosition); + } else { + // This is a relative mouse, so move the cursor by the specified amount. + const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X); + const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y); + pc.move(deltaX, deltaY); + const auto [x, y] = pc.getPosition(); + newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); + newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); + newArgs.xCursorPosition = x; + newArgs.yCursorPosition = y; + } if (canUnfadeOnDisplay(displayId)) { pc.unfade(PointerControllerInterface::Transition::IMMEDIATE); } - - const auto [x, y] = pc.getPosition(); - NotifyMotionArgs newArgs(args); - newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); - newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); - newArgs.xCursorPosition = x; - newArgs.yCursorPosition = y; - newArgs.displayId = displayId; return newArgs; } diff --git a/services/inputflinger/include/NotifyArgsBuilders.h b/services/inputflinger/include/NotifyArgsBuilders.h index e4363a416c..8ffbc11a13 100644 --- a/services/inputflinger/include/NotifyArgsBuilders.h +++ b/services/inputflinger/include/NotifyArgsBuilders.h @@ -107,7 +107,9 @@ public: // Set mouse cursor position for the most common cases to avoid boilerplate. if (mSource == AINPUT_SOURCE_MOUSE && - !MotionEvent::isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition)) { + !MotionEvent::isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition) && + BitSet64::hasBit(pointerCoords[0].bits, AMOTION_EVENT_AXIS_X) && + BitSet64::hasBit(pointerCoords[0].bits, AMOTION_EVENT_AXIS_Y)) { mRawXCursorPosition = pointerCoords[0].getX(); mRawYCursorPosition = pointerCoords[0].getY(); } diff --git a/services/inputflinger/tests/PointerChoreographer_test.cpp b/services/inputflinger/tests/PointerChoreographer_test.cpp index cbfb28faea..8ddb672cfe 100644 --- a/services/inputflinger/tests/PointerChoreographer_test.cpp +++ b/services/inputflinger/tests/PointerChoreographer_test.cpp @@ -355,6 +355,38 @@ TEST_F(PointerChoreographerTest, MouseMovesPointerAndReturnsNewArgs) { AllOf(WithCoords(110, 220), WithDisplayId(DISPLAY_ID), WithCursorPosition(110, 220))); } +TEST_F(PointerChoreographerTest, AbsoluteMouseMovesPointerAndReturnsNewArgs) { + mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID})); + mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID); + mChoreographer.notifyInputDevicesChanged( + {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ADISPLAY_ID_NONE)}}); + auto pc = assertPointerControllerCreated(ControllerType::MOUSE); + ASSERT_EQ(DISPLAY_ID, pc->getDisplayId()); + + // Set initial position of the PointerController. + pc->setPosition(100, 200); + const auto absoluteMousePointer = PointerBuilder(/*id=*/0, ToolType::MOUSE) + .axis(AMOTION_EVENT_AXIS_X, 110) + .axis(AMOTION_EVENT_AXIS_Y, 220); + + // Make NotifyMotionArgs and notify Choreographer. + mChoreographer.notifyMotion( + MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE) + .pointer(absoluteMousePointer) + .deviceId(DEVICE_ID) + .displayId(ADISPLAY_ID_NONE) + .build()); + + // Check that the PointerController updated the position and the pointer is shown. + pc->assertPosition(110, 220); + ASSERT_TRUE(pc->isPointerShown()); + + // Check that x-y coordinates, displayId and cursor position are correctly updated. + mTestListener.assertNotifyMotionWasCalled( + AllOf(WithCoords(110, 220), WithRelativeMotion(10, 20), WithDisplayId(DISPLAY_ID), + WithCursorPosition(110, 220))); +} + TEST_F(PointerChoreographerTest, AssociatedMouseMovesPointerOnAssociatedDisplayAndDoesNotMovePointerOnDefaultDisplay) { // Add two displays and set one to default. |