summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTommy Nordgren <tommy.nordgren@sony.com>2022-10-13 11:25:57 +0200
committerPrabir Pradhan <prabirmsp@google.com>2022-12-15 18:50:59 +0000
commitff0c66e855925476c5ce06ad133f9084e725f96a (patch)
treefddd89a6be9572e503a4ef8249c907e14ab54ec3
parent76742845662a10dcd7e9a7dbcfcd8b1b2999ce4f (diff)
downloadnative-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.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 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>();