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

Commit 65406477 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12813595 from def8ff1b to 25Q2-release

Change-Id: Ib81bc61d910e65adceef9ec3045e6182dd45f5db
parents 6b959ebe def8ff1b
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -148,7 +148,10 @@ public:
        OP_BLUETOOTH_ADVERTISE = 114,
        OP_RECORD_INCOMING_PHONE_AUDIO = 115,
        OP_NEARBY_WIFI_DEVICES = 116,
        _NUM_OP = 117
        // 116 - 154 omitted due to lack of use in native
        OP_CONTROL_AUDIO = 154,
        OP_CONTROL_AUDIO_PARTIAL = 155,
        _NUM_OP = 156,
    };

    enum {
+40 −92
Original line number Diff line number Diff line
@@ -98,6 +98,22 @@ std::unordered_set<ui::LogicalDisplayId> getPrivacySensitiveDisplaysFromWindowIn
    return privacySensitiveDisplays;
}

vec2 calculatePositionOnDestinationViewport(const DisplayViewport& destinationViewport,
                                            float pointerOffset,
                                            DisplayTopologyPosition sourceBoundary) {
    // destination is opposite of the source boundary
    switch (sourceBoundary) {
        case DisplayTopologyPosition::RIGHT:
            return {0, pointerOffset}; // left edge
        case DisplayTopologyPosition::TOP:
            return {pointerOffset, destinationViewport.logicalBottom}; // bottom edge
        case DisplayTopologyPosition::LEFT:
            return {destinationViewport.logicalRight, pointerOffset}; // right edge
        case DisplayTopologyPosition::BOTTOM:
            return {pointerOffset, 0}; // top edge
    }
}

} // namespace

// --- PointerChoreographer ---
@@ -327,19 +343,19 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac
    // except sometimes near the corners.
    // In these cases this behaviour is not noticeable. We also do not apply unconsumed delta on
    // the destination display for the same reason.
    DisplayPosition sourceBoundary;
    DisplayTopologyPosition sourceBoundary;
    float cursorOffset = 0.0f;
    if (rotatedUnconsumedDelta.x > 0) {
        sourceBoundary = DisplayPosition::RIGHT;
        sourceBoundary = DisplayTopologyPosition::RIGHT;
        cursorOffset = rotatedCursorPosition.y;
    } else if (rotatedUnconsumedDelta.x < 0) {
        sourceBoundary = DisplayPosition::LEFT;
        sourceBoundary = DisplayTopologyPosition::LEFT;
        cursorOffset = rotatedCursorPosition.y;
    } else if (rotatedUnconsumedDelta.y > 0) {
        sourceBoundary = DisplayPosition::BOTTOM;
        sourceBoundary = DisplayTopologyPosition::BOTTOM;
        cursorOffset = rotatedCursorPosition.x;
    } else {
        sourceBoundary = DisplayPosition::TOP;
        sourceBoundary = DisplayTopologyPosition::TOP;
        cursorOffset = rotatedCursorPosition.x;
    }

@@ -369,7 +385,8 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac
    pc.fade(PointerControllerInterface::Transition::IMMEDIATE);
    pc.setDisplayViewport(destinationViewport);
    vec2 destinationPosition =
            calculateDestinationPosition(destinationViewport, cursorOffset - destinationOffset,
            calculatePositionOnDestinationViewport(destinationViewport,
                                                   cursorOffset - destinationOffset,
                                                   sourceBoundary);

    // Transform position back to un-rotated coordinate space before sending it to controller
@@ -379,22 +396,6 @@ void PointerChoreographer::handleUnconsumedDeltaLocked(PointerControllerInterfac
    pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
}

vec2 PointerChoreographer::calculateDestinationPosition(const DisplayViewport& destinationViewport,
                                                        float pointerOffset,
                                                        DisplayPosition sourceBoundary) {
    // destination is opposite of the source boundary
    switch (sourceBoundary) {
        case DisplayPosition::RIGHT:
            return {0, pointerOffset}; // left edge
        case DisplayPosition::TOP:
            return {pointerOffset, destinationViewport.logicalBottom}; // bottom edge
        case DisplayPosition::LEFT:
            return {destinationViewport.logicalRight, pointerOffset}; // right edge
        case DisplayPosition::BOTTOM:
            return {pointerOffset, 0}; // top edge
    }
}

void PointerChoreographer::processDrawingTabletEventLocked(const android::NotifyMotionArgs& args) {
    if (args.displayId == ui::LogicalDisplayId::INVALID) {
        return;
@@ -540,8 +541,7 @@ void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args)
}

void PointerChoreographer::onControllerAddedOrRemovedLocked() {
    if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows() &&
        !com::android::input::flags::connected_displays_cursor()) {
    if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows()) {
        return;
    }
    bool requireListener = !mTouchPointersByDevice.empty() || !mMousePointersByDisplay.empty() ||
@@ -607,11 +607,16 @@ void PointerChoreographer::notifyPointerCaptureChanged(
    mNextListener.notify(args);
}

void PointerChoreographer::setDisplayTopology(
        const std::unordered_map<ui::LogicalDisplayId, std::vector<AdjacentDisplay>>&
                displayTopology) {
void PointerChoreographer::setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph) {
    std::scoped_lock _l(getLock());
    mTopology = displayTopology;
    mTopology = displayTopologyGraph;

    // 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;
    }
}

void PointerChoreographer::dump(std::string& dump) {
@@ -985,73 +990,17 @@ PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusContr
    return ConstructorDelegate(std::move(ctor));
}

void PointerChoreographer::populateFakeDisplayTopologyLocked(
        const std::vector<gui::DisplayInfo>& displayInfos) {
    if (!com::android::input::flags::connected_displays_cursor()) {
        return;
    }

    if (displayInfos.size() == mTopology.size()) {
        bool displaysChanged = false;
        for (const auto& displayInfo : displayInfos) {
            if (mTopology.find(displayInfo.displayId) == mTopology.end()) {
                displaysChanged = true;
                break;
            }
        }

        if (!displaysChanged) {
            return;
        }
    }

    // create a fake topology assuming following order
    // default-display (top-edge) -> next-display (right-edge) -> next-display (right-edge) ...
    // This also adds a 100px offset on corresponding edge for better manual testing
    //   ┌────────┐
    //   │ next   ├─────────┐
    // ┌─└───────┐┤ next 2  │ ...
    // │ default │└─────────┘
    // └─────────┘
    mTopology.clear();

    // treat default display as base, in real topology it should be the primary-display
    ui::LogicalDisplayId previousDisplay = ui::LogicalDisplayId::DEFAULT;
    for (const auto& displayInfo : displayInfos) {
        if (displayInfo.displayId == ui::LogicalDisplayId::DEFAULT) {
            continue;
        }
        if (previousDisplay == ui::LogicalDisplayId::DEFAULT) {
            mTopology[previousDisplay].push_back(
                    {displayInfo.displayId, DisplayPosition::TOP, 100});
            mTopology[displayInfo.displayId].push_back(
                    {previousDisplay, DisplayPosition::BOTTOM, -100});
        } else {
            mTopology[previousDisplay].push_back(
                    {displayInfo.displayId, DisplayPosition::RIGHT, 100});
            mTopology[displayInfo.displayId].push_back(
                    {previousDisplay, DisplayPosition::LEFT, -100});
        }
        previousDisplay = displayInfo.displayId;
    }

    // update default pointer display. In real topology it should be the primary-display
    if (mTopology.find(mDefaultMouseDisplayId) == mTopology.end()) {
        mDefaultMouseDisplayId = ui::LogicalDisplayId::DEFAULT;
    }
}

std::optional<std::pair<const DisplayViewport*, float /*offset*/>>
PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId sourceDisplayId,
                                                   const DisplayPosition sourceBoundary,
                                                   const DisplayTopologyPosition sourceBoundary,
                                                   float cursorOffset) const {
    const auto& sourceNode = mTopology.find(sourceDisplayId);
    if (sourceNode == mTopology.end()) {
    const auto& sourceNode = mTopology.graph.find(sourceDisplayId);
    if (sourceNode == mTopology.graph.end()) {
        // Topology is likely out of sync with viewport info, wait for it to be updated
        LOG(WARNING) << "Source display missing from topology " << sourceDisplayId;
        return std::nullopt;
    }
    for (const AdjacentDisplay& adjacentDisplay : sourceNode->second) {
    for (const DisplayTopologyAdjacentDisplay& adjacentDisplay : sourceNode->second) {
        if (adjacentDisplay.position != sourceBoundary) {
            continue;
        }
@@ -1064,8 +1013,8 @@ PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId so
            continue;
        }
        // target position must be within target display boundary
        const int32_t edgeSize =
                sourceBoundary == DisplayPosition::TOP || sourceBoundary == DisplayPosition::BOTTOM
        const int32_t edgeSize = sourceBoundary == DisplayTopologyPosition::TOP ||
                        sourceBoundary == DisplayTopologyPosition::BOTTOM
                ? (destinationViewport->logicalRight - destinationViewport->logicalLeft)
                : (destinationViewport->logicalBottom - destinationViewport->logicalTop);
        if (cursorOffset >= adjacentDisplay.offsetPx &&
@@ -1093,7 +1042,6 @@ void PointerChoreographer::PointerChoreographerDisplayInfoListener::onWindowInfo
        mPrivacySensitiveDisplays = std::move(newPrivacySensitiveDisplays);
        mPointerChoreographer->onPrivacySensitiveDisplaysChangedLocked(mPrivacySensitiveDisplays);
    }
    mPointerChoreographer->populateFakeDisplayTopologyLocked(windowInfosUpdate.displayInfos);
}

void PointerChoreographer::PointerChoreographerDisplayInfoListener::setInitialDisplayInfosLocked(
+15 −28
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@

#include <android-base/thread_annotations.h>
#include <gui/WindowInfosListener.h>
#include <input/DisplayTopologyGraph.h>
#include <type_traits>
#include <unordered_set>

@@ -80,6 +81,11 @@ public:
     */
    virtual void setFocusedDisplay(ui::LogicalDisplayId displayId) = 0;

    /*
     * Used by InputManager to notify changes in the DisplayTopology
     */
    virtual void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph) = 0;

    /**
     * This method may be called on any thread (usually by the input manager on a binder thread).
     */
@@ -103,6 +109,7 @@ public:
                        ui::LogicalDisplayId displayId, DeviceId deviceId) override;
    void setPointerIconVisibility(ui::LogicalDisplayId displayId, bool visible) override;
    void setFocusedDisplay(ui::LogicalDisplayId displayId) override;
    void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph);

    void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
    void notifyKey(const NotifyKeyArgs& args) override;
@@ -113,24 +120,6 @@ public:
    void notifyDeviceReset(const NotifyDeviceResetArgs& args) override;
    void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override;

    // TODO(b/362719483) remove these when real topology is available
    enum class DisplayPosition {
        RIGHT,
        TOP,
        LEFT,
        BOTTOM,
        ftl_last = BOTTOM,
    };

    struct AdjacentDisplay {
        ui::LogicalDisplayId displayId;
        DisplayPosition position;
        float offsetPx;
    };
    void setDisplayTopology(
            const std::unordered_map<ui::LogicalDisplayId, std::vector<AdjacentDisplay>>&
                    displayTopology);

    void dump(std::string& dump) override;

private:
@@ -174,18 +163,16 @@ private:
    void handleUnconsumedDeltaLocked(PointerControllerInterface& pc, const vec2& unconsumedDelta)
            REQUIRES(getLock());

    void populateFakeDisplayTopologyLocked(const std::vector<gui::DisplayInfo>& displayInfos)
            REQUIRES(getLock());

    std::optional<std::pair<const DisplayViewport*, float /*offset*/>> findDestinationDisplayLocked(
            const ui::LogicalDisplayId sourceDisplayId, const DisplayPosition sourceBoundary,
            float cursorOffset) const REQUIRES(getLock());

    static vec2 calculateDestinationPosition(const DisplayViewport& destinationViewport,
                                             float pointerOffset, DisplayPosition sourceBoundary);
            const ui::LogicalDisplayId sourceDisplayId,
            const DisplayTopologyPosition sourceBoundary, float cursorOffset) const
            REQUIRES(getLock());

    std::unordered_map<ui::LogicalDisplayId, std::vector<AdjacentDisplay>> mTopology
            GUARDED_BY(getLock());
    /* Topology is initialized with default-constructed value, which is an empty topology. Till we
     * receive setDisplayTopology call.
     * Meanwhile Choreographer will treat every display as independent disconnected display.
     */
    DisplayTopologyGraph mTopology GUARDED_BY(getLock());

    /* This listener keeps tracks of visible privacy sensitive displays and updates the
     * choreographer if there are any changes.
+13 −10
Original line number Diff line number Diff line
@@ -2633,16 +2633,14 @@ protected:
                           ui::ROTATION_0),
    };

    std::unordered_map<ui::LogicalDisplayId, std::vector<PointerChoreographer::AdjacentDisplay>>
            mTopology{
                    {DISPLAY_CENTER_ID,
                     {{DISPLAY_TOP_ID, PointerChoreographer::DisplayPosition::TOP, 10.0f},
                      {DISPLAY_RIGHT_ID, PointerChoreographer::DisplayPosition::RIGHT, 10.0f},
                      {DISPLAY_BOTTOM_ID, PointerChoreographer::DisplayPosition::BOTTOM, 10.0f},
                      {DISPLAY_LEFT_ID, PointerChoreographer::DisplayPosition::LEFT, 10.0f},
                      {DISPLAY_TOP_RIGHT_CORNER_ID, PointerChoreographer::DisplayPosition::RIGHT,
                       -90.0f}}},
            };
    DisplayTopologyGraph mTopology{DISPLAY_CENTER_ID,
                                   {{DISPLAY_CENTER_ID,
                                     {{DISPLAY_TOP_ID, DisplayTopologyPosition::TOP, 10.0f},
                                      {DISPLAY_RIGHT_ID, DisplayTopologyPosition::RIGHT, 10.0f},
                                      {DISPLAY_BOTTOM_ID, DisplayTopologyPosition::BOTTOM, 10.0f},
                                      {DISPLAY_LEFT_ID, DisplayTopologyPosition::LEFT, 10.0f},
                                      {DISPLAY_TOP_RIGHT_CORNER_ID, DisplayTopologyPosition::RIGHT,
                                       -90.0f}}}}};

private:
    DisplayViewport createViewport(ui::LogicalDisplayId displayId, int32_t width, int32_t height,
@@ -2706,6 +2704,11 @@ INSTANTIATE_TEST_SUITE_P(
        testing::Values(
                // Note: Upon viewport transition cursor will be positioned at the boundary of the
                // destination, as we drop any unconsumed delta.
                std::make_tuple("PrimaryDisplayIsDefault", AINPUT_SOURCE_MOUSE,
                                ControllerType::MOUSE, ToolType::MOUSE,
                                vec2(50, 50) /* initial x/y */, vec2(0, 0) /* delta x/y */,
                                PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID,
                                vec2(50, 50) /* destination x/y */),
                std::make_tuple("UnchangedDisplay", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE,
                                ToolType::MOUSE, vec2(50, 50) /* initial x/y */,
                                vec2(25, 25) /* delta x/y */,