diff options
author | Tommy Nordgren <tommy.nordgren@sony.com> | 2022-10-13 11:25:57 +0200 |
---|---|---|
committer | Prabir Pradhan <prabirmsp@google.com> | 2022-12-15 18:50:59 +0000 |
commit | ff0c66e855925476c5ce06ad133f9084e725f96a (patch) | |
tree | fddd89a6be9572e503a4ef8249c907e14ab54ec3 | |
parent | 76742845662a10dcd7e9a7dbcfcd8b1b2999ce4f (diff) | |
download | native-ff0c66e855925476c5ce06ad133f9084e725f96a.tar.gz |
Check display id of the last hover window before it is cleared
The display id of the last hover window must be checked before
it is cleared when a window changes for a display.
If display id of the last hover window is not checked, then the
last hover window is cleared every time a window changes on a
different display which is faulty.
The last hover window should only be cleared when the window
is removed from the same display as the display of last
hover window.
Add test that ensure that only one hover enter is generated
followed by several hover move when the mouse is moved in
a window on primary display when windows on second display
are removed.
The CTS test, VirtualMouseTest, must also be updated.
Reference patch:
Correct CTS test VirtualMouseTest#sendRelativeEvent
Ie4a54ee3469ed0b7c88abea946f32f66203da38f
Bug: 239687726
Bug: 262701886
Test: atest VirtualMouseTest
Change-Id: I70ebcb994ebc31327b85303110753ce3d40329be
Merged-In: I70ebcb994ebc31327b85303110753ce3d40329be
(cherry picked from commit dae9dfcf89fb79cdf27353d7f4220a36f83b343d)
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 11 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 53 |
2 files changed, 60 insertions, 4 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 5c47be9be0..3267753712 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -4727,10 +4727,13 @@ void InputDispatcher::setInputWindowsLocked( updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId); const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId); - if (mLastHoverWindowHandle && - std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) == - windowHandles.end()) { - mLastHoverWindowHandle = nullptr; + if (mLastHoverWindowHandle) { + const WindowInfo* lastHoverWindowInfo = mLastHoverWindowHandle->getInfo(); + if (lastHoverWindowInfo->displayId == displayId && + std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) == + windowHandles.end()) { + mLastHoverWindowHandle = nullptr; + } } std::optional<FocusResolver::FocusChanges> changes = diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 58617f7383..fce0f999b5 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -2189,6 +2189,59 @@ TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) { ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */); } +TEST_F(InputDispatcherTest, HoverEnterMoveRemoveWindowsInSecondDisplay) { + std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); + sp<FakeWindowHandle> windowDefaultDisplay = + sp<FakeWindowHandle>::make(application, mDispatcher, "DefaultDisplay", + ADISPLAY_ID_DEFAULT); + windowDefaultDisplay->setFrame(Rect(0, 0, 600, 800)); + sp<FakeWindowHandle> windowSecondDisplay = + sp<FakeWindowHandle>::make(application, mDispatcher, "SecondDisplay", + SECOND_DISPLAY_ID); + windowSecondDisplay->setFrame(Rect(0, 0, 600, 800)); + + mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowDefaultDisplay}}, + {SECOND_DISPLAY_ID, {windowSecondDisplay}}}); + + // Set cursor position in window in default display and check that hover enter and move + // events are generated. + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(mDispatcher, + MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, + AINPUT_SOURCE_MOUSE) + .displayId(ADISPLAY_ID_DEFAULT) + .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE) + .x(300) + .y(600)) + .build())); + windowDefaultDisplay->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER, + ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */); + windowDefaultDisplay->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE, + ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */); + + // Remove all windows in secondary display and check that no event happens on window in + // primary display. + mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}}); + windowDefaultDisplay->assertNoEvents(); + + // Move cursor position in window in default display and check that only hover move + // event is generated and not hover enter event. + mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowDefaultDisplay}}, + {SECOND_DISPLAY_ID, {windowSecondDisplay}}}); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(mDispatcher, + MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, + AINPUT_SOURCE_MOUSE) + .displayId(ADISPLAY_ID_DEFAULT) + .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE) + .x(400) + .y(700)) + .build())); + windowDefaultDisplay->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE, + ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */); + windowDefaultDisplay->assertNoEvents(); +} + TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) { std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); |