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

Commit 3c6e366c authored by Biswarup Pal's avatar Biswarup Pal Committed by Android (Google) Code Review
Browse files

Merge "Native support for rotary encoder high-res scroll" into main

parents f961316e ba27d1d9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -196,11 +196,11 @@ static constexpr size_t MAX_POINTERS = 16;
#define MAX_POINTER_ID 31

/*
 * Number of high resolution mouse scroll units for one detent (mouse wheel click), as defined in
 * Number of high resolution scroll units for one detent (scroll wheel click), as defined in
 * evdev. This is relevant when an input device is emitting REL_WHEEL_HI_RES or REL_HWHEEL_HI_RES
 * events.
 */
constexpr int32_t kEvdevMouseHighResScrollUnitsPerDetent = 120;
constexpr int32_t kEvdevHighResScrollUnitsPerDetent = 120;

/*
 * Declare a concrete type for the NDK's input event forward declaration.
+3 −0
Original line number Diff line number Diff line
@@ -129,6 +129,9 @@ public:
    VirtualRotaryEncoder(android::base::unique_fd fd);
    virtual ~VirtualRotaryEncoder() override;
    bool writeScrollEvent(float scrollAmount, std::chrono::nanoseconds eventTime);

private:
    int32_t mAccumulatedHighResScrollAmount;
};

} // namespace android
+39 −11
Original line number Diff line number Diff line
@@ -279,13 +279,17 @@ bool VirtualMouse::writeRelativeEvent(float relativeX, float relativeY,
bool VirtualMouse::writeScrollEvent(float xAxisMovement, float yAxisMovement,
                                    std::chrono::nanoseconds eventTime) {
    if (!vd_flags::high_resolution_scroll()) {
        return writeInputEvent(EV_REL, REL_HWHEEL, xAxisMovement, eventTime) &&
                writeInputEvent(EV_REL, REL_WHEEL, yAxisMovement, eventTime) &&
        return writeInputEvent(EV_REL, REL_HWHEEL, static_cast<int32_t>(xAxisMovement),
                               eventTime) &&
                writeInputEvent(EV_REL, REL_WHEEL, static_cast<int32_t>(yAxisMovement),
                                eventTime) &&
                writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
    }

    const int32_t highResScrollX = xAxisMovement * kEvdevMouseHighResScrollUnitsPerDetent;
    const int32_t highResScrollY = yAxisMovement * kEvdevMouseHighResScrollUnitsPerDetent;
    const auto highResScrollX =
            static_cast<int32_t>(xAxisMovement * kEvdevHighResScrollUnitsPerDetent);
    const auto highResScrollY =
            static_cast<int32_t>(yAxisMovement * kEvdevHighResScrollUnitsPerDetent);
    bool highResScrollResult =
            writeInputEvent(EV_REL, REL_HWHEEL_HI_RES, highResScrollX, eventTime) &&
            writeInputEvent(EV_REL, REL_WHEEL_HI_RES, highResScrollY, eventTime);
@@ -299,19 +303,19 @@ bool VirtualMouse::writeScrollEvent(float xAxisMovement, float yAxisMovement,
    // (single mouse wheel click).
    mAccumulatedHighResScrollX += highResScrollX;
    mAccumulatedHighResScrollY += highResScrollY;
    const int32_t scrollX = mAccumulatedHighResScrollX / kEvdevMouseHighResScrollUnitsPerDetent;
    const int32_t scrollY = mAccumulatedHighResScrollY / kEvdevMouseHighResScrollUnitsPerDetent;
    const int32_t scrollX = mAccumulatedHighResScrollX / kEvdevHighResScrollUnitsPerDetent;
    const int32_t scrollY = mAccumulatedHighResScrollY / kEvdevHighResScrollUnitsPerDetent;
    if (scrollX != 0) {
        if (!writeInputEvent(EV_REL, REL_HWHEEL, scrollX, eventTime)) {
            return false;
        }
        mAccumulatedHighResScrollX %= kEvdevMouseHighResScrollUnitsPerDetent;
        mAccumulatedHighResScrollX %= kEvdevHighResScrollUnitsPerDetent;
    }
    if (scrollY != 0) {
        if (!writeInputEvent(EV_REL, REL_WHEEL, scrollY, eventTime)) {
            return false;
        }
        mAccumulatedHighResScrollY %= kEvdevMouseHighResScrollUnitsPerDetent;
        mAccumulatedHighResScrollY %= kEvdevHighResScrollUnitsPerDetent;
    }

    return writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
@@ -550,14 +554,38 @@ bool VirtualStylus::handleStylusUp(uint16_t tool, std::chrono::nanoseconds event
}

// --- VirtualRotaryEncoder ---
VirtualRotaryEncoder::VirtualRotaryEncoder(unique_fd fd) : VirtualInputDevice(std::move(fd)) {}
VirtualRotaryEncoder::VirtualRotaryEncoder(unique_fd fd)
      : VirtualInputDevice(std::move(fd)), mAccumulatedHighResScrollAmount(0) {}

VirtualRotaryEncoder::~VirtualRotaryEncoder() {}

bool VirtualRotaryEncoder::writeScrollEvent(float scrollAmount,
                                            std::chrono::nanoseconds eventTime) {
    if (!vd_flags::high_resolution_scroll()) {
        return writeInputEvent(EV_REL, REL_WHEEL, static_cast<int32_t>(scrollAmount), eventTime) &&
                writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
    }

    const auto highResScrollAmount =
            static_cast<int32_t>(scrollAmount * kEvdevHighResScrollUnitsPerDetent);
    if (!writeInputEvent(EV_REL, REL_WHEEL_HI_RES, highResScrollAmount, eventTime)) {
        return false;
    }

    // According to evdev spec, a high-resolution scroll device needs to emit REL_WHEEL / REL_HWHEEL
    // events in addition to high-res scroll events. Regular scroll events can approximate high-res
    // scroll events, so we send a regular scroll event when the accumulated scroll motion reaches a
    // detent (single wheel click).
    mAccumulatedHighResScrollAmount += highResScrollAmount;
    const int32_t scroll = mAccumulatedHighResScrollAmount / kEvdevHighResScrollUnitsPerDetent;
    if (scroll != 0) {
        if (!writeInputEvent(EV_REL, REL_WHEEL, scroll, eventTime)) {
            return false;
        }
        mAccumulatedHighResScrollAmount %= kEvdevHighResScrollUnitsPerDetent;
    }

    return writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
}

} // namespace android
+9 −5
Original line number Diff line number Diff line
@@ -27,11 +27,14 @@

namespace android {

constexpr float kDefaultScaleFactor = 1.0f;

RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDeviceContext& deviceContext,
                                                   const InputReaderConfiguration& readerConfig)
      : InputMapper(deviceContext, readerConfig), mOrientation(ui::ROTATION_0) {
    mSource = AINPUT_SOURCE_ROTARY_ENCODER;
}
      : InputMapper(deviceContext, readerConfig),
        mSource(AINPUT_SOURCE_ROTARY_ENCODER),
        mScalingFactor(kDefaultScaleFactor),
        mOrientation(ui::ROTATION_0) {}

RotaryEncoderInputMapper::~RotaryEncoderInputMapper() {}

@@ -51,9 +54,10 @@ void RotaryEncoderInputMapper::populateDeviceInfo(InputDeviceInfo& info) {
        std::optional<float> scalingFactor = config.getFloat("device.scalingFactor");
        if (!scalingFactor.has_value()) {
            ALOGW("Rotary Encoder device configuration file didn't specify scaling factor,"
                  "default to 1.0!\n");
                  "default to %f!\n",
                  kDefaultScaleFactor);
        }
        mScalingFactor = scalingFactor.value_or(1.0f);
        mScalingFactor = scalingFactor.value_or(kDefaultScaleFactor);
        info.addMotionRange(AMOTION_EVENT_AXIS_SCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
                            res.value_or(0.0f) * mScalingFactor);
    }
+4 −4
Original line number Diff line number Diff line
@@ -55,14 +55,14 @@ void CursorScrollAccumulator::process(const RawEvent& rawEvent) {
        switch (rawEvent.code) {
            case REL_WHEEL_HI_RES:
                if (mHaveRelWheelHighRes) {
                    mRelWheel = rawEvent.value /
                            static_cast<float>(kEvdevMouseHighResScrollUnitsPerDetent);
                    mRelWheel =
                            rawEvent.value / static_cast<float>(kEvdevHighResScrollUnitsPerDetent);
                }
                break;
            case REL_HWHEEL_HI_RES:
                if (mHaveRelHWheelHighRes) {
                    mRelHWheel = rawEvent.value /
                            static_cast<float>(kEvdevMouseHighResScrollUnitsPerDetent);
                    mRelHWheel =
                            rawEvent.value / static_cast<float>(kEvdevHighResScrollUnitsPerDetent);
                }
                break;
            case REL_WHEEL:
Loading