Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 813c7853 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[5/n CD Cursor] Enable cross-display drag gesture" into main

parents 00ff6287 def7cb17
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -2808,8 +2808,9 @@ void InputDispatcher::finishDragAndDrop(ui::LogicalDisplayId displayId, float x,
}

void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
    if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId ||
        mDragState->deviceId != entry.deviceId) {
    if (!mDragState || mDragState->deviceId != entry.deviceId ||
        !mWindowInfos.areDisplaysConnected(mDragState->dragWindow->getInfo()->displayId,
                                           entry.displayId)) {
        return;
    }

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

bool InputDispatcher::DispatcherWindowInfo::areDisplaysConnected(
        ui::LogicalDisplayId display1, ui::LogicalDisplayId display2) const {
    return display1 == display2 ||
            (mTopology.graph.contains(display1) && mTopology.graph.contains(display2));
}

std::string InputDispatcher::DispatcherWindowInfo::dumpDisplayAndWindowInfo() const {
    std::string dump;
    if (!mWindowHandlesByDisplay.empty()) {
+3 −0
Original line number Diff line number Diff line
@@ -343,6 +343,9 @@ private:
        // same displayId.
        ui::LogicalDisplayId getPrimaryDisplayId(ui::LogicalDisplayId displayId) const;

        bool areDisplaysConnected(ui::LogicalDisplayId display1,
                                  ui::LogicalDisplayId display2) const;

        std::string dumpDisplayAndWindowInfo() const;

    private:
+88 −25
Original line number Diff line number Diff line
@@ -12374,6 +12374,11 @@ protected:
    sp<FakeWindowHandle> mSecondWindow;
    sp<FakeWindowHandle> mDragWindow;
    sp<FakeWindowHandle> mSpyWindow;
    std::vector<gui::DisplayInfo> mDisplayInfos;
    std::shared_ptr<FakeApplicationHandle> mSecondApplication;
    sp<FakeWindowHandle> mWindowOnSecondDisplay;
    // Mouse would force no-split, set the id as non-zero to verify if drag state could track it.
    static constexpr int32_t MOUSE_POINTER_ID = 1;
@@ -12394,10 +12399,17 @@ protected:
        mSpyWindow->setTrustedOverlay(true);
        mSpyWindow->setFrame(Rect(0, 0, 200, 100));
        mSecondApplication = std::make_shared<FakeApplicationHandle>();
        mWindowOnSecondDisplay =
                sp<FakeWindowHandle>::make(mSecondApplication, mDispatcher,
                                           "TestWindowOnSecondDisplay", SECOND_DISPLAY_ID);
        mWindowOnSecondDisplay->setFrame({0, 0, 100, 100});
        mDispatcher->setFocusedApplication(ui::LogicalDisplayId::DEFAULT, mApp);
        mDispatcher->onWindowInfosChanged(
                {{*mSpyWindow->getInfo(), *mWindow->getInfo(), *mSecondWindow->getInfo()},
                 {},
                {{*mSpyWindow->getInfo(), *mWindow->getInfo(), *mSecondWindow->getInfo(),
                  *mWindowOnSecondDisplay->getInfo()},
                 mDisplayInfos,
                 0,
                 0});
    }
@@ -12482,9 +12494,10 @@ protected:
        mDragWindow = sp<FakeWindowHandle>::make(mApp, mDispatcher, "DragWindow",
                                                 ui::LogicalDisplayId::DEFAULT);
        mDragWindow->setTouchableRegion(Region{{0, 0, 0, 0}});
        mDispatcher->onWindowInfosChanged({{*mDragWindow->getInfo(), *mSpyWindow->getInfo(),
                                            *mWindow->getInfo(), *mSecondWindow->getInfo()},
                                           {},
        mDispatcher->onWindowInfosChanged(
                {{*mDragWindow->getInfo(), *mSpyWindow->getInfo(), *mWindow->getInfo(),
                  *mSecondWindow->getInfo(), *mWindowOnSecondDisplay->getInfo()},
                 mDisplayInfos,
                 0,
                 0});
@@ -12499,6 +12512,13 @@ protected:
        }
        return transferred;
    }
    void addDisplay(ui::LogicalDisplayId displayId, ui::Transform transform) {
        gui::DisplayInfo displayInfo;
        displayInfo.displayId = displayId;
        displayInfo.transform = transform;
        mDisplayInfos.push_back(displayInfo);
    }
};
TEST_F(InputDispatcherDragTests, DragEnterAndDragExit) {
@@ -15185,7 +15205,7 @@ TEST_P(TransferOrDontTransferFixture, MouseAndTouchTransferSimultaneousMultiDevi
INSTANTIATE_TEST_SUITE_P(WithAndWithoutTransfer, TransferOrDontTransferFixture, testing::Bool());
class InputDispatcherConnectedDisplayTest : public InputDispatcherTest {
class InputDispatcherConnectedDisplayTest : public InputDispatcherDragTests {
    constexpr static int DENSITY_MEDIUM = 160;
    const DisplayTopologyGraph
@@ -15198,26 +15218,15 @@ class InputDispatcherConnectedDisplayTest : public InputDispatcherTest {
                                          {SECOND_DISPLAY_ID, DENSITY_MEDIUM}}};
protected:
    sp<FakeWindowHandle> mWindow;
    void SetUp() override {
        InputDispatcherTest::SetUp();
        mDispatcher->setDisplayTopology(mTopology);
        mWindow = sp<FakeWindowHandle>::make(std::make_shared<FakeApplicationHandle>(), mDispatcher,
                                             "Window", DISPLAY_ID);
        mWindow->setFrame({0, 0, 100, 100});
        gui::DisplayInfo displayInfo1;
        displayInfo1.displayId = DISPLAY_ID;
        addDisplay(DISPLAY_ID, ui::Transform());
        addDisplay(SECOND_DISPLAY_ID,
                   ui::Transform(ui::Transform::ROT_270, /*logicalDisplayWidth=*/
                                 500, /*logicalDisplayHeight=*/500));
        ui::Transform transform(ui::Transform::ROT_270, /*logicalDisplayWidth=*/500,
                                /*logicalDisplayHeight=*/500);
        gui::DisplayInfo displayInfo2;
        displayInfo2.displayId = SECOND_DISPLAY_ID;
        displayInfo2.transform = transform;
        InputDispatcherDragTests::SetUp();
        mDispatcher->onWindowInfosChanged(
                {{*mWindow->getInfo()}, {displayInfo1, displayInfo2}, 0, 0});
        mDispatcher->setDisplayTopology(mTopology);
    }
};
@@ -15283,4 +15292,58 @@ TEST_F(InputDispatcherConnectedDisplayTest, MultiDisplayMouseGesture) {
    mWindow->consumeMotionUp(SECOND_DISPLAY_ID);
}
TEST_F(InputDispatcherConnectedDisplayTest, MultiDisplayMouseDragAndDrop) {
    SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true);
    startDrag(true, AINPUT_SOURCE_MOUSE);
    // Move on window.
    mDispatcher->notifyMotion(
            MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE)
                    .displayId(DISPLAY_ID)
                    .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
                    .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50))
                    .build());
    mDragWindow->consumeMotionMove(DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE);
    mWindow->consumeDragEvent(false, 50, 50);
    mSecondWindow->assertNoEvents();
    mWindowOnSecondDisplay->assertNoEvents();
    // Move to another window.
    mDispatcher->notifyMotion(
            MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE)
                    .displayId(DISPLAY_ID)
                    .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
                    .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(150).y(50))
                    .build());
    mDragWindow->consumeMotionMove(DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE);
    mWindow->consumeDragEvent(true, 150, 50);
    mSecondWindow->consumeDragEvent(false, 50, 50);
    mWindowOnSecondDisplay->assertNoEvents();
    // Move to window on the second display
    mDispatcher->notifyMotion(
            MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE)
                    .displayId(SECOND_DISPLAY_ID)
                    .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
                    .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50))
                    .build());
    mDragWindow->consumeMotionMove(SECOND_DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE);
    mWindow->assertNoEvents();
    mSecondWindow->consumeDragEvent(true, -50, 50);
    mWindowOnSecondDisplay->consumeDragEvent(false, 50, 50);
    // drop on the second display
    mDispatcher->notifyMotion(
            MotionArgsBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
                    .displayId(SECOND_DISPLAY_ID)
                    .buttonState(0)
                    .pointer(PointerBuilder(MOUSE_POINTER_ID, ToolType::MOUSE).x(50).y(50))
                    .build());
    mDragWindow->consumeMotionUp(SECOND_DISPLAY_ID, AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE);
    mFakePolicy->assertDropTargetEquals(*mDispatcher, mWindowOnSecondDisplay->getToken());
    mWindow->assertNoEvents();
    mSecondWindow->assertNoEvents();
    mWindowOnSecondDisplay->assertNoEvents();
}
} // namespace android::inputdispatcher