summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2023-10-10 00:50:51 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2023-10-10 00:50:51 +0000
commit66cb582f250251b00af4b84380df5624f40a9257 (patch)
tree4b089920d610d0f38cf22cf520a6e06e092d2e10
parent0b15142d1b1e991d6610df767ffcab357cb87505 (diff)
parent462dc34a6f2ffbd206980b12ce13b0813894619c (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.cpp9
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp55
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