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

Commit 6d2e24fc authored by Michael Checo's avatar Michael Checo
Browse files

Add support to disable mouse acceleration

Bug: 382276176
Test: atest CursorInputMapperUnitTest
Flag: com.android.hardware.input.pointer_acceleration
Change-Id: I431ac6fa3b918b1d292528f614e06532837c4a82
parent e7f052da
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -46,4 +46,15 @@ struct AccelerationCurveSegment {
std::vector<AccelerationCurveSegment> createAccelerationCurveForPointerSensitivity(
        int32_t sensitivity);

/*
 * Creates a flat acceleration curve for disabling pointer acceleration.
 *
 * This method generates a single AccelerationCurveSegment with specific values
 * to effectively disable acceleration for both mice and touchpads.
 * A flat acceleration curve ensures a constant gain, meaning that the output
 * velocity is directly proportional to the input velocity, resulting in
 * a 1:1 movement ratio between the input device and the on-screen pointer.
 */
std::vector<AccelerationCurveSegment> createFlatAccelerationCurve(int32_t sensitivity);

} // namespace android
+21 −0
Original line number Diff line number Diff line
@@ -40,6 +40,18 @@ static_assert(kSegments.back().maxPointerSpeedMmPerS == std::numeric_limits<doub
constexpr std::array<double, 15> kSensitivityFactors = {1,  2,  4,  6,  7,  8,  9, 10,
                                                        11, 12, 13, 14, 16, 18, 20};

// Calculates the base gain for a given pointer sensitivity value.
//
// The base gain is a scaling factor that is applied to the pointer movement.
// Higher sensitivity values result in larger base gains, which in turn result
// in faster pointer movements.
//
// The base gain is calculated using a linear mapping function that maps the
// sensitivity range [-7, 7] to a base gain range [0.5, 2.0].
double calculateBaseGain(int32_t sensitivity) {
    return 0.5 + (sensitivity + 7) * (2.0 - 0.5) / (7 + 7);
}

} // namespace

std::vector<AccelerationCurveSegment> createAccelerationCurveForPointerSensitivity(
@@ -60,4 +72,13 @@ std::vector<AccelerationCurveSegment> createAccelerationCurveForPointerSensitivi
    return output;
}

std::vector<AccelerationCurveSegment> createFlatAccelerationCurve(int32_t sensitivity) {
    LOG_ALWAYS_FATAL_IF(sensitivity < -7 || sensitivity > 7, "Invalid pointer sensitivity value");
    std::vector<AccelerationCurveSegment> output = {
            AccelerationCurveSegment{std::numeric_limits<double>::infinity(),
                                     calculateBaseGain(sensitivity),
                                     /* reciprocal = */ 0}};
    return output;
}

} // namespace android
 No newline at end of file
+10 −1
Original line number Diff line number Diff line
@@ -139,9 +139,17 @@ struct InputReaderConfiguration {
    // The mouse pointer speed, as a number from -7 (slowest) to 7 (fastest).
    int32_t mousePointerSpeed;

    // Displays on which an acceleration curve shouldn't be applied for pointer movements from mice.
    // Displays on which all pointer scaling, including linear scaling based on the
    // user's pointer speed setting, should be disabled for mice. This differs from
    // disabling acceleration via the 'mousePointerAccelerationEnabled' setting, where
    // the pointer speed setting still influences the scaling factor.
    std::set<ui::LogicalDisplayId> displaysWithMousePointerAccelerationDisabled;

    // True if the connected mouse should exhibit pointer acceleration. If false,
    // a flat acceleration curve (linear scaling) is used, but the user's pointer
    // speed setting still affects the scaling factor.
    bool mousePointerAccelerationEnabled;

    // Velocity control parameters for touchpad pointer movements on the old touchpad stack (based
    // on TouchInputMapper).
    //
@@ -275,6 +283,7 @@ struct InputReaderConfiguration {
            defaultPointerDisplayId(ui::LogicalDisplayId::DEFAULT),
            mousePointerSpeed(0),
            displaysWithMousePointerAccelerationDisabled(),
            mousePointerAccelerationEnabled(true),
            pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f,
                                             static_cast<float>(
                                                     android::os::IInputConstants::
+14 −8
Original line number Diff line number Diff line
@@ -481,16 +481,22 @@ void CursorInputMapper::configureOnChangePointerSpeed(const InputReaderConfigura
        mPointerVelocityControl.setAccelerationEnabled(false);
        mWheelXVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
        mWheelYVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
    } else {
        mPointerVelocityControl.setAccelerationEnabled(
                config.displaysWithMousePointerAccelerationDisabled.count(
                        mDisplayId.value_or(ui::LogicalDisplayId::INVALID)) == 0);
        return;
    }

    bool disableAllScaling = config.displaysWithMousePointerAccelerationDisabled.count(
                                     mDisplayId.value_or(ui::LogicalDisplayId::INVALID)) != 0;

    mPointerVelocityControl.setAccelerationEnabled(!disableAllScaling);

    mPointerVelocityControl.setCurve(
                createAccelerationCurveForPointerSensitivity(config.mousePointerSpeed));
            config.mousePointerAccelerationEnabled
                    ? createAccelerationCurveForPointerSensitivity(config.mousePointerSpeed)
                    : createFlatAccelerationCurve(config.mousePointerSpeed));

    mWheelXVelocityControl.setParameters(config.wheelVelocityControlParameters);
    mWheelYVelocityControl.setParameters(config.wheelVelocityControlParameters);
}
}

void CursorInputMapper::configureOnChangeDisplayInfo(const InputReaderConfiguration& config) {
    const bool isPointer = mParameters.mode == Parameters::Mode::POINTER;
+29 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <com_android_input_flags.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <input/AccelerationCurve.h>
#include <input/DisplayViewport.h>
#include <input/InputEventLabels.h>
#include <linux/input-event-codes.h>
@@ -1028,6 +1029,34 @@ TEST_F(CursorInputMapperUnitTest, ConfigureDisplayIdNoAssociatedViewport) {
                              WithCoords(0.0f, 0.0f)))));
}

TEST_F(CursorInputMapperUnitTest, PointerAccelerationDisabled) {
    mReaderConfiguration.mousePointerAccelerationEnabled = false;
    mReaderConfiguration.mousePointerSpeed = 3;
    mPropertyMap.addProperty("cursor.mode", "pointer");
    createMapper();

    std::list<NotifyArgs> reconfigureArgs;

    reconfigureArgs += mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
                                            InputReaderConfiguration::Change::POINTER_SPEED);

    std::vector<AccelerationCurveSegment> curve =
            createFlatAccelerationCurve(mReaderConfiguration.mousePointerSpeed);
    double baseGain = curve[0].baseGain;

    std::list<NotifyArgs> motionArgs;
    motionArgs += process(ARBITRARY_TIME, EV_REL, REL_X, 10);
    motionArgs += process(ARBITRARY_TIME, EV_REL, REL_Y, 20);
    motionArgs += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);

    const float expectedRelX = 10 * baseGain;
    const float expectedRelY = 20 * baseGain;
    ASSERT_THAT(motionArgs,
                ElementsAre(VariantWith<NotifyMotionArgs>(
                        AllOf(WithMotionAction(HOVER_MOVE),
                              WithRelativeMotion(expectedRelX, expectedRelY)))));
}

TEST_F(CursorInputMapperUnitTest, ConfigureAccelerationWithAssociatedViewport) {
    mPropertyMap.addProperty("cursor.mode", "pointer");
    DisplayViewport primaryViewport = createPrimaryViewport(ui::Rotation::Rotation0);
Loading