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

Commit fd3de793 authored by Prabir Pradhan's avatar Prabir Pradhan Committed by Android (Google) Code Review
Browse files

Merge "Pointer icon refactor for touchpad" into main

parents ffce10d1 ee6268f0
Loading
Loading
Loading
Loading
+57 −11
Original line number Diff line number Diff line
@@ -31,6 +31,11 @@ bool isFromMouse(const NotifyMotionArgs& args) {
            args.pointerProperties[0].toolType == ToolType::MOUSE;
}

bool isFromTouchpad(const NotifyMotionArgs& args) {
    return isFromSource(args.source, AINPUT_SOURCE_MOUSE) &&
            args.pointerProperties[0].toolType == ToolType::FINGER;
}

bool isHoverAction(int32_t action) {
    return action == AMOTION_EVENT_ACTION_HOVER_ENTER ||
            action == AMOTION_EVENT_ACTION_HOVER_MOVE || action == AMOTION_EVENT_ACTION_HOVER_EXIT;
@@ -83,6 +88,8 @@ NotifyMotionArgs PointerChoreographer::processMotion(const NotifyMotionArgs& arg

    if (isFromMouse(args)) {
        return processMouseEventLocked(args);
    } else if (isFromTouchpad(args)) {
        return processTouchpadEventLocked(args);
    } else if (mStylusPointerIconEnabled && isStylusHoverEvent(args)) {
        processStylusHoverEventLocked(args);
    } else if (isFromSource(args.source, AINPUT_SOURCE_TOUCHSCREEN)) {
@@ -97,30 +104,54 @@ NotifyMotionArgs PointerChoreographer::processMouseEventLocked(const NotifyMotio
                   << args.dump();
    }

    const int32_t displayId = getTargetMouseDisplayLocked(args.displayId);
    auto [displayId, pc] = getDisplayIdAndMouseControllerLocked(args.displayId);

    // Get the mouse pointer controller for the display, or create one if it doesn't exist.
    auto [it, emplaced] =
            mMousePointersByDisplay.try_emplace(displayId,
                                                getMouseControllerConstructor(displayId));
    if (emplaced) {
        notifyPointerDisplayIdChangedLocked();
    const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
    const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
    pc.move(deltaX, deltaY);
    pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);

    const auto [x, y] = pc.getPosition();
    NotifyMotionArgs newArgs(args);
    newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
    newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
    newArgs.xCursorPosition = x;
    newArgs.yCursorPosition = y;
    newArgs.displayId = displayId;
    return newArgs;
}

    PointerControllerInterface& pc = *it->second;
NotifyMotionArgs PointerChoreographer::processTouchpadEventLocked(const NotifyMotionArgs& args) {
    auto [displayId, pc] = getDisplayIdAndMouseControllerLocked(args.displayId);

    NotifyMotionArgs newArgs(args);
    newArgs.displayId = displayId;
    if (args.getPointerCount() == 1 && args.classification == MotionClassification::NONE) {
        // This is a movement of the mouse pointer.
        const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
        const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
        pc.move(deltaX, deltaY);
        pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);

        const auto [x, y] = pc.getPosition();
    NotifyMotionArgs newArgs(args);
        newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
        newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
        newArgs.xCursorPosition = x;
        newArgs.yCursorPosition = y;
    newArgs.displayId = displayId;
    } else {
        // This is a trackpad gesture with fake finger(s) that should not move the mouse pointer.
        pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);

        const auto [x, y] = pc.getPosition();
        for (uint32_t i = 0; i < newArgs.getPointerCount(); i++) {
            newArgs.pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X,
                                                  args.pointerCoords[i].getX() + x);
            newArgs.pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y,
                                                  args.pointerCoords[i].getY() + y);
        }
        newArgs.xCursorPosition = x;
        newArgs.yCursorPosition = y;
    }
    return newArgs;
}

@@ -270,6 +301,21 @@ int32_t PointerChoreographer::getTargetMouseDisplayLocked(int32_t associatedDisp
    return associatedDisplayId == ADISPLAY_ID_NONE ? mDefaultMouseDisplayId : associatedDisplayId;
}

std::pair<int32_t, PointerControllerInterface&>
PointerChoreographer::getDisplayIdAndMouseControllerLocked(int32_t associatedDisplayId) {
    const int32_t displayId = getTargetMouseDisplayLocked(associatedDisplayId);

    // Get the mouse pointer controller for the display, or create one if it doesn't exist.
    auto [it, emplaced] =
            mMousePointersByDisplay.try_emplace(displayId,
                                                getMouseControllerConstructor(displayId));
    if (emplaced) {
        notifyPointerDisplayIdChangedLocked();
    }

    return {displayId, *it->second};
}

InputDeviceInfo* PointerChoreographer::findInputDeviceLocked(DeviceId deviceId) {
    auto it = std::find_if(mInputDeviceInfos.begin(), mInputDeviceInfos.end(),
                           [deviceId](const auto& info) { return info.getId() == deviceId; });
+3 −0
Original line number Diff line number Diff line
@@ -95,10 +95,13 @@ private:
    void notifyPointerDisplayIdChangedLocked() REQUIRES(mLock);
    const DisplayViewport* findViewportByIdLocked(int32_t displayId) const REQUIRES(mLock);
    int32_t getTargetMouseDisplayLocked(int32_t associatedDisplayId) const REQUIRES(mLock);
    std::pair<int32_t, PointerControllerInterface&> getDisplayIdAndMouseControllerLocked(
            int32_t associatedDisplayId) REQUIRES(mLock);
    InputDeviceInfo* findInputDeviceLocked(DeviceId deviceId) REQUIRES(mLock);

    NotifyMotionArgs processMotion(const NotifyMotionArgs& args);
    NotifyMotionArgs processMouseEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
    NotifyMotionArgs processTouchpadEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
    void processTouchscreenAndStylusEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
    void processStylusHoverEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
    void processDeviceReset(const NotifyDeviceResetArgs& args);
+2 −4
Original line number Diff line number Diff line
@@ -527,10 +527,8 @@ void CursorInputMapper::configureOnChangeDisplayInfo(const InputReaderConfigurat
        if (mEnablePointerChoreographer) {
            // Always use DISPLAY_ID_NONE for mouse events.
            // PointerChoreographer will make it target the correct the displayId later.
            const auto pointerViewport =
                    getContext()->getPolicy()->getPointerViewportForAssociatedDisplay();
            mDisplayId = pointerViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt;
            resolvedViewport = pointerViewport;
            resolvedViewport = getContext()->getPolicy()->getPointerViewportForAssociatedDisplay();
            mDisplayId = resolvedViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt;
        } else {
            mDisplayId = mPointerController->getDisplayId();
            if (auto v = config.getDisplayViewportById(*mDisplayId); v) {
+44 −18
Original line number Diff line number Diff line
@@ -246,7 +246,8 @@ TouchpadInputMapper::TouchpadInputMapper(InputDeviceContext& deviceContext,
        mStateConverter(deviceContext, mMotionAccumulator),
        mGestureConverter(*getContext(), deviceContext, getDeviceId()),
        mCapturedEventConverter(*getContext(), deviceContext, mMotionAccumulator, getDeviceId()),
        mMetricsId(metricsIdFromInputDeviceIdentifier(deviceContext.getDeviceIdentifier())) {
        mMetricsId(metricsIdFromInputDeviceIdentifier(deviceContext.getDeviceIdentifier())),
        mEnablePointerChoreographer(input_flags::enable_pointer_choreographer()) {
    RawAbsoluteAxisInfo slotAxisInfo;
    deviceContext.getAbsoluteAxisInfo(ABS_MT_SLOT, &slotAxisInfo);
    if (!slotAxisInfo.valid || slotAxisInfo.maxValue <= 0) {
@@ -331,31 +332,56 @@ std::list<NotifyArgs> TouchpadInputMapper::reconfigure(nsecs_t when,

    if (!changes.any() || changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) {
        mDisplayId = ADISPLAY_ID_NONE;
        if (auto viewport = mDeviceContext.getAssociatedViewport(); viewport) {
        std::optional<DisplayViewport> resolvedViewport;
        std::optional<FloatRect> boundsInLogicalDisplay;
        if (auto assocViewport = mDeviceContext.getAssociatedViewport(); assocViewport) {
            // This InputDevice is associated with a viewport.
            // Only generate events for the associated display.
            mDisplayId = assocViewport->displayId;
            resolvedViewport = *assocViewport;
            if (!mEnablePointerChoreographer) {
                const bool mismatchedPointerDisplay =
                    (viewport->displayId != mPointerController->getDisplayId());
                        (assocViewport->displayId != mPointerController->getDisplayId());
                if (mismatchedPointerDisplay) {
                    ALOGW("Touchpad \"%s\" associated viewport display does not match pointer "
                          "controller",
                          mDeviceContext.getName().c_str());
                    mDisplayId.reset();
                }
            }
            mDisplayId = mismatchedPointerDisplay ? std::nullopt
                                                  : std::make_optional(viewport->displayId);
        } else {
            // The InputDevice is not associated with a viewport, but it controls the mouse pointer.
            if (mEnablePointerChoreographer) {
                // Always use DISPLAY_ID_NONE for touchpad events.
                // PointerChoreographer will make it target the correct the displayId later.
                resolvedViewport =
                        getContext()->getPolicy()->getPointerViewportForAssociatedDisplay();
                mDisplayId = resolvedViewport ? std::make_optional(ADISPLAY_ID_NONE) : std::nullopt;
            } else {
                mDisplayId = mPointerController->getDisplayId();
                if (auto v = config.getDisplayViewportById(*mDisplayId); v) {
                    resolvedViewport = *v;
                }

        ui::Rotation orientation = ui::ROTATION_0;
        if (mDisplayId.has_value()) {
            if (auto viewport = config.getDisplayViewportById(*mDisplayId); viewport) {
                orientation = getInverseRotation(viewport->orientation);
                if (auto bounds = mPointerController->getBounds(); bounds) {
                    boundsInLogicalDisplay = *bounds;
                }
            }
        }

        mGestureConverter.setDisplayId(mDisplayId);
        mGestureConverter.setOrientation(orientation);
        mGestureConverter.setOrientation(resolvedViewport
                                                 ? getInverseRotation(resolvedViewport->orientation)
                                                 : ui::ROTATION_0);

        if (!boundsInLogicalDisplay) {
            boundsInLogicalDisplay = resolvedViewport
                    ? FloatRect{static_cast<float>(resolvedViewport->logicalLeft),
                                static_cast<float>(resolvedViewport->logicalTop),
                                static_cast<float>(resolvedViewport->logicalRight - 1),
                                static_cast<float>(resolvedViewport->logicalBottom - 1)}
                    : FloatRect{0, 0, 0, 0};
        }
        mGestureConverter.setBoundsInLogicalDisplay(*boundsInLogicalDisplay);
    }
    if (!changes.any() || changes.test(InputReaderConfiguration::Change::TOUCHPAD_SETTINGS)) {
        mPropertyProvider.getProperty("Use Custom Touchpad Pointer Accel Curve")
+2 −0
Original line number Diff line number Diff line
@@ -107,6 +107,8 @@ private:
    // Tracking IDs for touches that have at some point been reported as palms by the touchpad.
    std::set<int32_t> mPalmTrackingIds;

    const bool mEnablePointerChoreographer;

    // The display that events generated by this mapper should target. This can be set to
    // ADISPLAY_ID_NONE to target the focused display. If there is no display target (i.e.
    // std::nullopt), all events will be ignored.
Loading