summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tommy Nordgren <tommy.nordgren@sony.com> 2022-10-13 11:25:57 +0200
committer Siarhei Vishniakou <svv@google.com> 2022-11-23 09:39:34 -0800
commitdae9dfcf89fb79cdf27353d7f4220a36f83b343d (patch)
tree1600dfda47f4f7d5f2a52b9de577a872922b48c2
parent327b9350c57028058cb3aaf95a5bb3200e7bec34 (diff)
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 Test: atest VirtualMouseTest Change-Id: I70ebcb994ebc31327b85303110753ce3d40329be
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp11
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp53
2 files changed, 60 insertions, 4 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 6d300903d2..05f32069f7 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4803,10 +4803,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 7817eca43b..ff064e416d 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2279,6 +2279,59 @@ TEST_F(InputDispatcherTest, MouseHoverAndTouchTap) {
WithSource(AINPUT_SOURCE_TOUCHSCREEN))));
}
+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>();