diff options
| author | 2023-10-10 00:50:51 +0000 | |
|---|---|---|
| committer | 2023-10-10 00:50:51 +0000 | |
| commit | 66cb582f250251b00af4b84380df5624f40a9257 (patch) | |
| tree | 4b089920d610d0f38cf22cf520a6e06e092d2e10 | |
| parent | 0b15142d1b1e991d6610df767ffcab357cb87505 (diff) | |
| parent | 462dc34a6f2ffbd206980b12ce13b0813894619c (diff) | |
Merge "Dispatch cancel event to the correct target display" into main am: 478532c0aa am: 6a101212e9 am: 462dc34a6f
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2747373
Change-Id: If5fc264205144a6e64481e219337ec1c86eb2a9d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 9 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 55 |
2 files changed, 62 insertions, 2 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 5c524d3104..66052e4908 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -3924,8 +3924,13 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS; InputTarget target; - sp<WindowInfoHandle> windowHandle = - getWindowHandleLocked(connection->inputChannel->getConnectionToken()); + sp<WindowInfoHandle> windowHandle; + if (options.displayId) { + windowHandle = getWindowHandleLocked(connection->inputChannel->getConnectionToken(), + options.displayId.value()); + } else { + windowHandle = getWindowHandleLocked(connection->inputChannel->getConnectionToken()); + } if (windowHandle != nullptr) { const WindowInfo* windowInfo = windowHandle->getInfo(); target.setDefaultPointerTransform(windowInfo->transform); diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 6ff420d951..ddb419b3ff 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -4153,6 +4153,61 @@ TEST_F(InputDispatcherTest, TouchpadThreeFingerSwipeNotSentToSingleWindow) { } /** + * When there are multiple screens, such as screen projection to TV or screen recording, if the + * cancel event occurs, the coordinates of the cancel event should be sent to the target screen, and + * its coordinates should be converted by the transform of the windows of target screen. + */ +TEST_F(InputDispatcherTest, WhenMultiDisplayWindowSameToken_DispatchCancelToTargetDisplay) { + // This case will create a window and a spy window on the default display and mirror + // window on the second display. cancel event is sent through spy window pilferPointers + std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); + + sp<FakeWindowHandle> spyWindowDefaultDisplay = + sp<FakeWindowHandle>::make(application, mDispatcher, "Spy", ADISPLAY_ID_DEFAULT); + spyWindowDefaultDisplay->setTrustedOverlay(true); + spyWindowDefaultDisplay->setSpy(true); + + sp<FakeWindowHandle> windowDefaultDisplay = + sp<FakeWindowHandle>::make(application, mDispatcher, "DefaultDisplay", + ADISPLAY_ID_DEFAULT); + windowDefaultDisplay->setWindowTransform(1, 0, 0, 1); + + sp<FakeWindowHandle> windowSecondDisplay = + windowDefaultDisplay->clone(application, mDispatcher, SECOND_DISPLAY_ID); + windowSecondDisplay->setWindowTransform(2, 0, 0, 2); + + // Add the windows to the dispatcher + mDispatcher->onWindowInfosChanged( + {{*spyWindowDefaultDisplay->getInfo(), *windowDefaultDisplay->getInfo(), + *windowSecondDisplay->getInfo()}, + {}, + 0, + 0}); + + // Send down to ADISPLAY_ID_DEFAULT + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, + {100, 100})) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + + spyWindowDefaultDisplay->consumeMotionDown(); + windowDefaultDisplay->consumeMotionDown(); + + EXPECT_EQ(OK, mDispatcher->pilferPointers(spyWindowDefaultDisplay->getToken())); + + // windowDefaultDisplay gets cancel + MotionEvent* event = windowDefaultDisplay->consumeMotion(); + EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, event->getAction()); + + // The cancel event is sent to windowDefaultDisplay of the ADISPLAY_ID_DEFAULT display, so the + // coordinates of the cancel are converted by windowDefaultDisplay's transform, the x and y + // coordinates are both 100, otherwise if the cancel event is sent to windowSecondDisplay of + // SECOND_DISPLAY_ID, the x and y coordinates are 200 + EXPECT_EQ(100, event->getX(0)); + EXPECT_EQ(100, event->getY(0)); +} + +/** * Ensure the correct coordinate spaces are used by InputDispatcher. * * InputDispatcher works in the display space, so its coordinate system is relative to the display |