@@ -12374,6 +12374,11 @@ class InputDispatcherDragTests : public InputDispatcherTest {
1237412374 sp<FakeWindowHandle> mSecondWindow;
1237512375 sp<FakeWindowHandle> mDragWindow;
1237612376 sp<FakeWindowHandle> mSpyWindow;
12377+
12378+ std::vector<gui::DisplayInfo> mDisplayInfos;
12379+
12380+ std::shared_ptr<FakeApplicationHandle> mSecondApplication;
12381+ sp<FakeWindowHandle> mWindowOnSecondDisplay;
1237712382 // Mouse would force no-split, set the id as non-zero to verify if drag state could track it.
1237812383 static constexpr int32_t MOUSE_POINTER_ID = 1;
1237912384
@@ -12394,10 +12399,17 @@ class InputDispatcherDragTests : public InputDispatcherTest {
1239412399 mSpyWindow->setTrustedOverlay(true);
1239512400 mSpyWindow->setFrame(Rect(0, 0, 200, 100));
1239612401
12402+ mSecondApplication = std::make_shared<FakeApplicationHandle>();
12403+ mWindowOnSecondDisplay =
12404+ sp<FakeWindowHandle>::make(mSecondApplication, mDispatcher,
12405+ "TestWindowOnSecondDisplay", SECOND_DISPLAY_ID);
12406+ mWindowOnSecondDisplay->setFrame({0, 0, 100, 100});
12407+
1239712408 mDispatcher->setFocusedApplication(ui::LogicalDisplayId::DEFAULT, mApp);
1239812409 mDispatcher->onWindowInfosChanged(
12399- {{*mSpyWindow->getInfo(), *mWindow->getInfo(), *mSecondWindow->getInfo()},
12400- {},
12410+ {{*mSpyWindow->getInfo(), *mWindow->getInfo(), *mSecondWindow->getInfo(),
12411+ *mWindowOnSecondDisplay->getInfo()},
12412+ mDisplayInfos,
1240112413 0,
1240212414 0});
1240312415 }
@@ -12482,11 +12494,12 @@ class InputDispatcherDragTests : public InputDispatcherTest {
1248212494 mDragWindow = sp<FakeWindowHandle>::make(mApp, mDispatcher, "DragWindow",
1248312495 ui::LogicalDisplayId::DEFAULT);
1248412496 mDragWindow->setTouchableRegion(Region{{0, 0, 0, 0}});
12485- mDispatcher->onWindowInfosChanged({{*mDragWindow->getInfo(), *mSpyWindow->getInfo(),
12486- *mWindow->getInfo(), *mSecondWindow->getInfo()},
12487- {},
12488- 0,
12489- 0});
12497+ mDispatcher->onWindowInfosChanged(
12498+ {{*mDragWindow->getInfo(), *mSpyWindow->getInfo(), *mWindow->getInfo(),
12499+ *mSecondWindow->getInfo(), *mWindowOnSecondDisplay->getInfo()},
12500+ mDisplayInfos,
12501+ 0,
12502+ 0});
1249012503
1249112504 // Transfer touch focus to the drag window
1249212505 bool transferred =
@@ -12499,6 +12512,13 @@ class InputDispatcherDragTests : public InputDispatcherTest {
1249912512 }
1250012513 return transferred;
1250112514 }
12515+
12516+ void addDisplay(ui::LogicalDisplayId displayId, ui::Transform transform) {
12517+ gui::DisplayInfo displayInfo;
12518+ displayInfo.displayId = displayId;
12519+ displayInfo.transform = transform;
12520+ mDisplayInfos.push_back(displayInfo);
12521+ }
1250212522};
1250312523
1250412524TEST_F(InputDispatcherDragTests, DragEnterAndDragExit) {
@@ -15185,7 +15205,7 @@ TEST_P(TransferOrDontTransferFixture, MouseAndTouchTransferSimultaneousMultiDevi
1518515205
1518615206INSTANTIATE_TEST_SUITE_P(WithAndWithoutTransfer, TransferOrDontTransferFixture, testing::Bool());
1518715207
15188- class InputDispatcherConnectedDisplayTest : public InputDispatcherTest {
15208+ class InputDispatcherConnectedDisplayTest : public InputDispatcherDragTests {
1518915209 constexpr static int DENSITY_MEDIUM = 160;
1519015210
1519115211 const DisplayTopologyGraph
@@ -15198,26 +15218,15 @@ class InputDispatcherConnectedDisplayTest : public InputDispatcherTest {
1519815218 {SECOND_DISPLAY_ID, DENSITY_MEDIUM}}};
1519915219
1520015220protected:
15201- sp<FakeWindowHandle> mWindow;
15202-
1520315221 void SetUp() override {
15204- InputDispatcherTest::SetUp();
15205- mDispatcher->setDisplayTopology(mTopology);
15206- mWindow = sp<FakeWindowHandle>::make(std::make_shared<FakeApplicationHandle>(), mDispatcher,
15207- "Window", DISPLAY_ID);
15208- mWindow->setFrame({0, 0, 100, 100});
15209-
15210- gui::DisplayInfo displayInfo1;
15211- displayInfo1.displayId = DISPLAY_ID;
15222+ addDisplay(DISPLAY_ID, ui::Transform());
15223+ addDisplay(SECOND_DISPLAY_ID,
15224+ ui::Transform(ui::Transform::ROT_270, /*logicalDisplayWidth=*/
15225+ 500, /*logicalDisplayHeight=*/500));
1521215226
15213- ui::Transform transform(ui::Transform::ROT_270, /*logicalDisplayWidth=*/500,
15214- /*logicalDisplayHeight=*/500);
15215- gui::DisplayInfo displayInfo2;
15216- displayInfo2.displayId = SECOND_DISPLAY_ID;
15217- displayInfo2.transform = transform;
15227+ InputDispatcherDragTests::SetUp();
1521815228
15219- mDispatcher->onWindowInfosChanged(
15220- {{*mWindow->getInfo()}, {displayInfo1, displayInfo2}, 0, 0});
15229+ mDispatcher->setDisplayTopology(mTopology);
1522115230 }
1522215231};
1522315232
@@ -15283,4 +15292,58 @@ TEST_F(InputDispatcherConnectedDisplayTest, MultiDisplayMouseGesture) {
1528315292 mWindow->consumeMotionUp(SECOND_DISPLAY_ID);
1528415293}
1528515294
15295+ TEST_F(InputDispatcherConnectedDisplayTest, MultiDisplayMouseDragAndDrop) {
15296+ SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true);
15297+
15298+ startDrag(true, AINPUT_SOURCE_MOUSE);
15299+ // Move on window.
15300+ mDispatcher->notifyMotion(
15301+ MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE)
15302+ .displayId(DISPLAY_ID)
15303+ .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
15304+ .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50))
15305+ .build());
15306+ mDragWindow->consumeMotionMove(DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE);
15307+ mWindow->consumeDragEvent(false, 50, 50);
15308+ mSecondWindow->assertNoEvents();
15309+ mWindowOnSecondDisplay->assertNoEvents();
15310+
15311+ // Move to another window.
15312+ mDispatcher->notifyMotion(
15313+ MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE)
15314+ .displayId(DISPLAY_ID)
15315+ .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
15316+ .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(150).y(50))
15317+ .build());
15318+ mDragWindow->consumeMotionMove(DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE);
15319+ mWindow->consumeDragEvent(true, 150, 50);
15320+ mSecondWindow->consumeDragEvent(false, 50, 50);
15321+ mWindowOnSecondDisplay->assertNoEvents();
15322+
15323+ // Move to window on the second display
15324+ mDispatcher->notifyMotion(
15325+ MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE)
15326+ .displayId(SECOND_DISPLAY_ID)
15327+ .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
15328+ .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50))
15329+ .build());
15330+ mDragWindow->consumeMotionMove(SECOND_DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE);
15331+ mWindow->assertNoEvents();
15332+ mSecondWindow->consumeDragEvent(true, -50, 50);
15333+ mWindowOnSecondDisplay->consumeDragEvent(false, 50, 50);
15334+
15335+ // drop on the second display
15336+ mDispatcher->notifyMotion(
15337+ MotionArgsBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
15338+ .displayId(SECOND_DISPLAY_ID)
15339+ .buttonState(0)
15340+ .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50))
15341+ .build());
15342+ mDragWindow->consumeMotionUp(SECOND_DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE);
15343+ mFakePolicy->assertDropTargetEquals(*mDispatcher, mWindowOnSecondDisplay->getToken());
15344+ mWindow->assertNoEvents();
15345+ mSecondWindow->assertNoEvents();
15346+ mWindowOnSecondDisplay->assertNoEvents();
15347+ }
15348+
1528615349} // namespace android::inputdispatcher
0 commit comments