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

Commit 21e0a209 authored by Nergi Rahardi's avatar Nergi Rahardi Committed by Android (Google) Code Review
Browse files

Merge "[CD Cursor] Apply selection logic to change cursor displayId" into main

parents a7949cee 96df7be3
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -25,6 +25,11 @@ public:
     * override.
     */
    static bool connectedDisplaysCursorEnabled();

    /**
     * Check if both connectedDisplaysCursor and associatedDisplayCursorBugfix is enabled.
     */
    static bool connectedDisplaysCursorAndAssociatedDisplayCursorBugfixEnabled();
};

} // namespace android
+5 −0
Original line number Diff line number Diff line
@@ -39,4 +39,9 @@ bool InputFlags::connectedDisplaysCursorEnabled() {
    return com::android::input::flags::connected_displays_cursor();
}

bool InputFlags::connectedDisplaysCursorAndAssociatedDisplayCursorBugfixEnabled() {
    return connectedDisplaysCursorEnabled() &&
            com::android::input::flags::connected_displays_associated_display_cursor_bugfix();
}

} // namespace android
 No newline at end of file
+20 −8
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ PointerChoreographer::PointerChoreographer(
        }),
        mNextListener(listener),
        mPolicy(policy),
        mDefaultMouseDisplayId(ui::LogicalDisplayId::DEFAULT),
        mCurrentMouseDisplayId(ui::LogicalDisplayId::INVALID),
        mNotifiedPointerDisplayId(ui::LogicalDisplayId::INVALID),
        mShowTouchesEnabled(false),
        mStylusPointerIconEnabled(false),
@@ -361,7 +361,7 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac
        LOG(FATAL) << "A cursor already exists on destination display"
                   << destinationViewport.displayId;
    }
    mDefaultMouseDisplayId = destinationViewport.displayId;
    mCurrentMouseDisplayId = destinationViewport.displayId;
    auto pcNode = mMousePointersByDisplay.extract(sourceDisplayId);
    pcNode.key() = destinationViewport.displayId;
    mMousePointersByDisplay.insert(std::move(pcNode));
@@ -609,9 +609,9 @@ void PointerChoreographer::setDisplayTopology(const DisplayTopologyGraph& displa

        // make primary display default mouse display, if it was not set or
        // the existing display was removed
        if (mDefaultMouseDisplayId == ui::LogicalDisplayId::INVALID ||
            mTopology.graph.find(mDefaultMouseDisplayId) == mTopology.graph.end()) {
            mDefaultMouseDisplayId = mTopology.primaryDisplayId;
        if (mCurrentMouseDisplayId == ui::LogicalDisplayId::INVALID ||
            mTopology.graph.find(mCurrentMouseDisplayId) == mTopology.graph.end()) {
            mCurrentMouseDisplayId = mTopology.primaryDisplayId;
            pointerDisplayChange = updatePointerControllersLocked();
        }
    } // release lock
@@ -665,7 +665,19 @@ const DisplayViewport* PointerChoreographer::findViewportByIdLocked(

ui::LogicalDisplayId PointerChoreographer::getTargetMouseDisplayLocked(
        ui::LogicalDisplayId associatedDisplayId) const {
    return associatedDisplayId.isValid() ? associatedDisplayId : mDefaultMouseDisplayId;
    if (!InputFlags::connectedDisplaysCursorAndAssociatedDisplayCursorBugfixEnabled()) {
        if (associatedDisplayId.isValid()) {
            return associatedDisplayId;
        }
        return mCurrentMouseDisplayId.isValid() ? mCurrentMouseDisplayId
                                                : ui::LogicalDisplayId::DEFAULT;
    }
    // Associated display is not included in the topology, return this associated display.
    if (associatedDisplayId.isValid() &&
        mTopology.graph.find(associatedDisplayId) == mTopology.graph.end()) {
        return associatedDisplayId;
    }
    return mCurrentMouseDisplayId.isValid() ? mCurrentMouseDisplayId : mTopology.primaryDisplayId;
}

std::pair<ui::LogicalDisplayId, PointerControllerInterface&>
@@ -774,7 +786,7 @@ PointerChoreographer::PointerDisplayChange
PointerChoreographer::calculatePointerDisplayChangeToNotify() {
    ui::LogicalDisplayId displayIdToNotify = ui::LogicalDisplayId::INVALID;
    vec2 cursorPosition = {0, 0};
    if (const auto it = mMousePointersByDisplay.find(mDefaultMouseDisplayId);
    if (const auto it = mMousePointersByDisplay.find(mCurrentMouseDisplayId);
        it != mMousePointersByDisplay.end()) {
        const auto& pointerController = it->second;
        // Use the displayId from the pointerController, because it accurately reflects whether
@@ -800,7 +812,7 @@ void PointerChoreographer::setDefaultMouseDisplayId(ui::LogicalDisplayId display
    { // acquire lock
        std::scoped_lock _l(getLock());

        mDefaultMouseDisplayId = displayId;
        mCurrentMouseDisplayId = displayId;
        pointerDisplayChange = updatePointerControllersLocked();
    } // release lock

+6 −1
Original line number Diff line number Diff line
@@ -231,7 +231,12 @@ private:
    std::map<DeviceId, std::shared_ptr<PointerControllerInterface>> mDrawingTabletPointersByDevice
            GUARDED_BY(getLock());

    ui::LogicalDisplayId mDefaultMouseDisplayId GUARDED_BY(getLock());
    // In connected displays scenario, this tracks the latest display the cursor is at, within the
    // DisplayTopology. By default, this will be set to topology primary display, and updated when
    // mouse crossed to another display.
    // In non-connected displays scenario, this will be treated as the default display cursor
    // will be on, when mouse doesn't have associated display.
    ui::LogicalDisplayId mCurrentMouseDisplayId GUARDED_BY(getLock());
    ui::LogicalDisplayId mNotifiedPointerDisplayId GUARDED_BY(getLock());
    std::vector<InputDeviceInfo> mInputDeviceInfos GUARDED_BY(getLock());
    std::set<DeviceId> mMouseDevices GUARDED_BY(getLock());
+84 −0
Original line number Diff line number Diff line
@@ -3072,6 +3072,90 @@ TEST_F(PointerChoreographerDisplayTopologyDefaultMouseDisplayTests,
    ASSERT_TRUE(pc->isPointerShown());
}

TEST_F(PointerChoreographerDisplayTopologyDefaultMouseDisplayTests,
       UsePrimaryDisplayIfAssociatedDisplayIsInTopology) {
    SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true);
    SCOPED_FLAG_OVERRIDE(connected_displays_associated_display_cursor_bugfix, true);

    // Add two displays
    mChoreographer.setDisplayViewports(
            {createViewport(FIRST_DISPLAY_ID), createViewport(SECOND_DISPLAY_ID)});
    setDisplayTopologyWithDisplays(/*primaryDisplayId=*/SECOND_DISPLAY_ID,
                                   /*adjacentDisplays=*/{FIRST_DISPLAY_ID});

    mChoreographer.notifyInputDevicesChanged(
            {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, FIRST_DISPLAY_ID)}});

    auto pc = assertPointerControllerCreated(ControllerType::MOUSE);
    pc->assertViewportSet(SECOND_DISPLAY_ID);
    ASSERT_TRUE(pc->isPointerShown());
}

TEST_F(PointerChoreographerDisplayTopologyDefaultMouseDisplayTests,
       AllowCrossingDisplayEvenWithAssociatedDisplaySet) {
    SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true);
    SCOPED_FLAG_OVERRIDE(connected_displays_associated_display_cursor_bugfix, true);

    // Add two displays
    mChoreographer.setDisplayViewports(
            {createViewport(FIRST_DISPLAY_ID), createViewport(SECOND_DISPLAY_ID)});
    setDisplayTopologyWithDisplays(/*primaryDisplayId=*/FIRST_DISPLAY_ID,
                                   /*adjacentDisplays=*/{SECOND_DISPLAY_ID});

    mChoreographer.notifyInputDevicesChanged(
            {/*id=*/0,
             {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, SECOND_DISPLAY_ID)}});

    auto pc = assertPointerControllerCreated(ControllerType::MOUSE);
    pc->assertViewportSet(FIRST_DISPLAY_ID);
    ASSERT_TRUE(pc->isPointerShown());

    // Move cursor to the secondary display
    auto pointerBuilder = PointerBuilder(/*id=*/0, ToolType::MOUSE)
                                  .axis(AMOTION_EVENT_AXIS_RELATIVE_X, /*x=*/100)
                                  .axis(AMOTION_EVENT_AXIS_RELATIVE_Y, /*y=*/0);
    mChoreographer.notifyMotion(
            MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE)
                    .pointer(pointerBuilder)
                    .deviceId(DEVICE_ID)
                    .displayId(ui::LogicalDisplayId::INVALID)
                    .build());

    assertPointerControllerNotCreated();
    pc->assertViewportSet(SECOND_DISPLAY_ID);
    ASSERT_TRUE(pc->isPointerShown());
}

TEST_F(PointerChoreographerDisplayTopologyDefaultMouseDisplayTests,
       AddAssociatedDisplayCursorOutsideOfDisplayTopology) {
    SCOPED_FLAG_OVERRIDE(connected_displays_cursor, true);
    SCOPED_FLAG_OVERRIDE(connected_displays_associated_display_cursor_bugfix, true);

    // Add three displays, with only first and second display in DisplayTopolgoy
    mChoreographer.setDisplayViewports({createViewport(FIRST_DISPLAY_ID),
                                        createViewport(SECOND_DISPLAY_ID),
                                        createViewport(THIRD_DISPLAY_ID)});
    setDisplayTopologyWithDisplays(/*primaryDisplayId=*/FIRST_DISPLAY_ID,
                                   /*adjacentDisplays=*/{SECOND_DISPLAY_ID});

    mChoreographer.notifyInputDevicesChanged(
            {/*id=*/0,
             {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE,
                                     ui::LogicalDisplayId::INVALID)}});

    auto pc = assertPointerControllerCreated(ControllerType::MOUSE);
    pc->assertViewportSet(FIRST_DISPLAY_ID);
    ASSERT_TRUE(pc->isPointerShown());

    // Adds a new mouse associated with third display
    mChoreographer.notifyInputDevicesChanged(
            {/*id=*/1, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, THIRD_DISPLAY_ID)}});

    pc = assertPointerControllerCreated(ControllerType::MOUSE);
    pc->assertViewportSet(THIRD_DISPLAY_ID);
    ASSERT_TRUE(pc->isPointerShown());
}

class PointerChoreographerWindowInfoListenerTest : public testing::Test {};

TEST_F_WITH_FLAGS(