InputDispatcher: Fix multi-display Pointer Capture
There is an existing requirement that a window must both have focus and
be on the focused display to be able to gain Pointer Capture.
This means that focus changes on non-focused displays should not affect
Pointer Capture, and that a window must lose capture if its display
loses focus.
Verify these requirements with a test.
Bug: 342229227
Test: atest inputflinger_tests
Change-Id: I7b1c73b7759d8f20436ee401ba657a5dc8ead7a5
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 8de28c6..780bc13 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -11054,6 +11054,37 @@
mWindow->assertNoEvents();
}
+TEST_F(InputDispatcherPointerCaptureTests, MultiDisplayPointerCapture) {
+ // The default display is the focused display to begin with.
+ requestAndVerifyPointerCapture(mWindow, true);
+
+ // Move the second window to a second display, make it the focused window on that display.
+ mSecondWindow->editInfo()->displayId = SECOND_DISPLAY_ID;
+ mDispatcher->onWindowInfosChanged({{*mWindow->getInfo(), *mSecondWindow->getInfo()}, {}, 0, 0});
+ setFocusedWindow(mSecondWindow);
+ mSecondWindow->consumeFocusEvent(true);
+
+ mWindow->assertNoEvents();
+
+ // The second window cannot gain capture because it is not on the focused display.
+ mDispatcher->requestPointerCapture(mSecondWindow->getToken(), true);
+ mFakePolicy->assertSetPointerCaptureNotCalled();
+ mSecondWindow->assertNoEvents();
+
+ // Make the second display the focused display.
+ mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
+
+ // This causes the first window to lose pointer capture, and it's unable to request capture.
+ mWindow->consumeCaptureEvent(false);
+ mFakePolicy->assertSetPointerCaptureCalled(mWindow, false);
+
+ mDispatcher->requestPointerCapture(mWindow->getToken(), true);
+ mFakePolicy->assertSetPointerCaptureNotCalled();
+
+ // The second window is now able to gain pointer capture successfully.
+ requestAndVerifyPointerCapture(mSecondWindow, true);
+}
+
using InputDispatcherPointerCaptureDeathTest = InputDispatcherPointerCaptureTests;
TEST_F(InputDispatcherPointerCaptureDeathTest,