Skip to content

Commit 813c785

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "[5/n CD Cursor] Enable cross-display drag gesture" into main
2 parents 00ff628 + def7cb1 commit 813c785

3 files changed

Lines changed: 100 additions & 27 deletions

File tree

services/inputflinger/dispatcher/InputDispatcher.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2808,8 +2808,9 @@ void InputDispatcher::finishDragAndDrop(ui::LogicalDisplayId displayId, float x,
28082808
}
28092809

28102810
void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2811-
if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId ||
2812-
mDragState->deviceId != entry.deviceId) {
2811+
if (!mDragState || mDragState->deviceId != entry.deviceId ||
2812+
!mWindowInfos.areDisplaysConnected(mDragState->dragWindow->getInfo()->displayId,
2813+
entry.displayId)) {
28132814
return;
28142815
}
28152816

@@ -5198,6 +5199,12 @@ ui::LogicalDisplayId InputDispatcher::DispatcherWindowInfo::getPrimaryDisplayId(
51985199
return displayId;
51995200
}
52005201

5202+
bool InputDispatcher::DispatcherWindowInfo::areDisplaysConnected(
5203+
ui::LogicalDisplayId display1, ui::LogicalDisplayId display2) const {
5204+
return display1 == display2 ||
5205+
(mTopology.graph.contains(display1) && mTopology.graph.contains(display2));
5206+
}
5207+
52015208
std::string InputDispatcher::DispatcherWindowInfo::dumpDisplayAndWindowInfo() const {
52025209
std::string dump;
52035210
if (!mWindowHandlesByDisplay.empty()) {

services/inputflinger/dispatcher/InputDispatcher.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ class InputDispatcher : public android::InputDispatcherInterface {
343343
// same displayId.
344344
ui::LogicalDisplayId getPrimaryDisplayId(ui::LogicalDisplayId displayId) const;
345345

346+
bool areDisplaysConnected(ui::LogicalDisplayId display1,
347+
ui::LogicalDisplayId display2) const;
348+
346349
std::string dumpDisplayAndWindowInfo() const;
347350

348351
private:

services/inputflinger/tests/InputDispatcher_test.cpp

Lines changed: 88 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1250412524
TEST_F(InputDispatcherDragTests, DragEnterAndDragExit) {
@@ -15185,7 +15205,7 @@ TEST_P(TransferOrDontTransferFixture, MouseAndTouchTransferSimultaneousMultiDevi
1518515205

1518615206
INSTANTIATE_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

1520015220
protected:
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

Comments
 (0)