diff options
| author | 2025-02-20 16:35:42 +0000 | |
|---|---|---|
| committer | 2025-02-21 12:26:36 +0000 | |
| commit | fc66a3aa926177c6c66c5838fc6c3803b4c82d30 (patch) | |
| tree | 2a9cbd8b4a9f6904608d36378ad63365871d29dd | |
| parent | 3c769a4d1ba7f422e5b21d6d5f7e0f6b1ae5b2f0 (diff) | |
[CD Cursor] Fix cursorState lookup for non-primary displays
In connected display scenario touchstate display for mouse is always
identified by primary display. At present
DispatcherTouchState::forTouchAndCursorStatesOnDisplay is the only API
in TouchStates that does not adhere to this mapping. This can cause the
lookup for cursorState to fail.
IsPointerInWindow is the only public API in dispatcher that uses this
and fails. This Cl updates the lookup and adds tests for API called with
the non-primary display in topology.
Test: inputflinger_tests with the flag enabled/disabled
Bug: 395033854
Flag: com.android.input.flags.connected_displays_cursor
Change-Id: I1515171802478a7132206562e41a7586b8ca8559
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 7 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 43 |
2 files changed, 47 insertions, 3 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index ba7507133e..ef50fc0036 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -7553,9 +7553,10 @@ void InputDispatcher::DispatcherTouchState::forTouchAndCursorStatesOnDisplay( return; } - // TODO(b/383092013): This is currently not accounting for the "topology group" concept. - // Proper implementation requires looking tghrough all the displays in the topology group. - const auto cursorStateIt = mCursorStateByDisplay.find(displayId); + // DisplayId for the Cursor state may not be same as supplied displayId if display is part of + // topology. Instead we should to check from the topology's primary display. + const auto cursorStateIt = + mCursorStateByDisplay.find(mWindowInfos.getPrimaryDisplayId(displayId)); if (cursorStateIt != mCursorStateByDisplay.end()) { f(cursorStateIt->second); } diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 1778f6d508..2b9b470a21 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -15403,4 +15403,47 @@ TEST_F(InputDispatcherConnectedDisplayTest, MultiDisplayMouseDragAndDropFromNonP mWindowOnSecondDisplay->assertNoEvents(); } +using InputDispatcherConnectedDisplayPointerInWindowTest = InputDispatcherConnectedDisplayTest; + +TEST_F(InputDispatcherConnectedDisplayPointerInWindowTest, MouseOnWindowOnPrimaryDisplay) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_MOUSE) + .pointer(PointerBuilder(/*id=*/0, ToolType::MOUSE).x(50).y(50)) + .build()); + + mWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER)); + mSpyWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER)); + mWindowOnSecondDisplay->assertNoEvents(); + + ASSERT_TRUE(mDispatcher->isPointerInWindow(mWindow->getToken(), DISPLAY_ID, DEVICE_ID, + /*pointerId=*/0)); + ASSERT_TRUE(mDispatcher->isPointerInWindow(mSpyWindow->getToken(), DISPLAY_ID, DEVICE_ID, + /*pointerId=*/0)); + ASSERT_FALSE(mDispatcher->isPointerInWindow(mWindowOnSecondDisplay->getToken(), + SECOND_DISPLAY_ID, DEVICE_ID, /*pointerId=*/0)); +} + +TEST_F(InputDispatcherConnectedDisplayPointerInWindowTest, MouseOnWindowOnNonPrimaryDisplay) { + SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true); + + mDispatcher->notifyMotion( + MotionArgsBuilder(ACTION_HOVER_ENTER, AINPUT_SOURCE_MOUSE) + .displayId(SECOND_DISPLAY_ID) + .pointer(PointerBuilder(/*id=*/0, ToolType::MOUSE).x(50).y(50)) + .build()); + + mWindow->assertNoEvents(); + mSpyWindow->assertNoEvents(); + mWindowOnSecondDisplay->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER)); + + ASSERT_FALSE(mDispatcher->isPointerInWindow(mWindow->getToken(), DISPLAY_ID, DEVICE_ID, + /*pointerId=*/0)); + ASSERT_FALSE(mDispatcher->isPointerInWindow(mSpyWindow->getToken(), DISPLAY_ID, DEVICE_ID, + /*pointerId=*/0)); + ASSERT_TRUE(mDispatcher->isPointerInWindow(mWindowOnSecondDisplay->getToken(), + SECOND_DISPLAY_ID, DEVICE_ID, /*pointerId=*/0)); +} + } // namespace android::inputdispatcher |