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

Commit 65893ab9 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "CursorInputMapper: fix simultaneous button and move handling" into main

parents e8844d09 a4e9f70a
Loading
Loading
Loading
Loading
+47 −33
Original line number Diff line number Diff line
@@ -272,9 +272,6 @@ std::list<NotifyArgs> CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) {
    pointerProperties.id = 0;
    pointerProperties.toolType = ToolType::MOUSE;

    PointerCoords pointerCoords;
    pointerCoords.clear();

    // A negative value represents inverted scrolling direction.
    // Applies only if the source is a mouse.
    const bool isMouse =
@@ -291,18 +288,6 @@ std::list<NotifyArgs> CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) {

    float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
    float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
    if (mSource == AINPUT_SOURCE_MOUSE) {
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
    } else {
        // Pointer capture and navigation modes
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
    }

    pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);

    // Moving an external trackball or mouse should wake the device.
    // We don't do this for internal cursor devices to prevent them from waking up
@@ -313,23 +298,48 @@ std::list<NotifyArgs> CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) {
        policyFlags |= POLICY_FLAG_WAKE;
    }

    const int32_t metaState = getContext()->getGlobalMetaState();
    // Send an event for the cursor motion.
    // TODO(b/407018146): we currently need to send a zero-delta HOVER_MOVE before scrolls so that
    //  InputDispatcher generates a HOVER_ENTER event if necessary. (The VirtualMouseTest in CTS
    //  depends on this.) Fix this issue then remove `|| scrolled` here.
    if (moved || scrolled) {
        int32_t action = wasDown || mSource != AINPUT_SOURCE_MOUSE
                ? AMOTION_EVENT_ACTION_MOVE
                : AMOTION_EVENT_ACTION_HOVER_MOVE;

        PointerCoords moveCoords;
        moveCoords.clear();
        moveCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
        moveCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
        if (mSource != AINPUT_SOURCE_MOUSE) {
            // Pointer capture and navigation modes
            moveCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
            moveCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
        }

        moveCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, wasDown ? 1.0f : 0.0f);

        out.push_back(NotifyMotionArgs(getContext()->getNextId(), when, readTime, getDeviceId(),
                                       mSource, *mDisplayId, policyFlags, action, 0, 0, metaState,
                                       lastButtonState, MotionClassification::NONE, 1,
                                       &pointerProperties, &moveCoords, mXPrecision, mYPrecision,
                                       xCursorPosition, yCursorPosition, downTime,
                                       /*videoFrames=*/{}));
    }

    // Synthesize key down from buttons if needed.
    out += synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, readTime, getDeviceId(),
                                mSource, *mDisplayId, policyFlags, lastButtonState,
                                currentButtonState);

    // Send motion event.
    if (downChanged || moved || scrolled || buttonsChanged) {
        int32_t metaState = getContext()->getGlobalMetaState();
    // Send motion events for buttons and scrolling.
    if (downChanged || scrolled || buttonsChanged) {
        int32_t buttonState = lastButtonState;
        int32_t motionEventAction;
        if (downChanged) {
            motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
        } else if (down || (mSource != AINPUT_SOURCE_MOUSE)) {
            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
        } else {
            motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
        }

        PointerCoords pointerCoords;
        pointerCoords.clear();
        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);

        if (buttonsReleased) {
            BitSet32 released(buttonsReleased);
@@ -346,12 +356,16 @@ std::list<NotifyArgs> CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) {
            }
        }

        if (downChanged) {
            int32_t action = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
            out.push_back(NotifyMotionArgs(getContext()->getNextId(), when, readTime, getDeviceId(),
                                       mSource, *mDisplayId, policyFlags, motionEventAction, 0, 0,
                                       metaState, currentButtonState, MotionClassification::NONE, 1,
                                       &pointerProperties, &pointerCoords, mXPrecision, mYPrecision,
                                           mSource, *mDisplayId, policyFlags, action, 0, 0,
                                           metaState, currentButtonState,
                                           MotionClassification::NONE, 1, &pointerProperties,
                                           &pointerCoords, mXPrecision, mYPrecision,
                                           xCursorPosition, yCursorPosition, downTime,
                                           /*videoFrames=*/{}));
        }

        if (buttonsPressed) {
            BitSet32 pressed(buttonsPressed);
@@ -371,7 +385,7 @@ std::list<NotifyArgs> CursorInputMapper::sync(nsecs_t when, nsecs_t readTime) {
        ALOG_ASSERT(buttonState == currentButtonState);

        // Send hover move after UP to tell the application that the mouse is hovering now.
        if (motionEventAction == AMOTION_EVENT_ACTION_UP && (mSource == AINPUT_SOURCE_MOUSE)) {
        if (downChanged && !down && (mSource == AINPUT_SOURCE_MOUSE)) {
            out.push_back(NotifyMotionArgs(getContext()->getNextId(), when, readTime, getDeviceId(),
                                           mSource, *mDisplayId, policyFlags,
                                           AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
+67 −18
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@ constexpr auto HOVER_MOVE = AMOTION_EVENT_ACTION_HOVER_MOVE;
constexpr auto INVALID_CURSOR_POSITION = AMOTION_EVENT_INVALID_CURSOR_POSITION;
constexpr auto AXIS_X = AMOTION_EVENT_AXIS_X;
constexpr auto AXIS_Y = AMOTION_EVENT_AXIS_Y;
constexpr auto AXIS_RELATIVE_X = AMOTION_EVENT_AXIS_RELATIVE_X;
constexpr auto AXIS_RELATIVE_Y = AMOTION_EVENT_AXIS_RELATIVE_Y;
constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
constexpr ui::LogicalDisplayId SECONDARY_DISPLAY_ID = ui::LogicalDisplayId{DISPLAY_ID.val() + 1};
constexpr int32_t DISPLAY_WIDTH = 480;
@@ -261,6 +263,59 @@ TEST_F(CursorInputMapperUnitTest, HoverAndLeftButtonPress) {
                            VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE))));
}

TEST_F(CursorInputMapperUnitTest, MoveAndButtonChangeInSameFrame) {
    createMapper();
    std::list<NotifyArgs> args;

    // Move the cursor and press the button
    args += process(EV_REL, REL_X, -10);
    args += process(EV_REL, REL_Y, 20);
    args += process(EV_KEY, BTN_LEFT, 1);
    args += process(EV_SYN, SYN_REPORT, 0);
    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(HOVER_MOVE), WithButtonState(0),
                                          WithNegativeAxis(AXIS_RELATIVE_X),
                                          WithPositiveAxis(AXIS_RELATIVE_Y), WithPressure(0.0f))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(ACTION_DOWN),
                                          WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
                                          WithZeroAxis(AXIS_RELATIVE_X),
                                          WithZeroAxis(AXIS_RELATIVE_Y), WithPressure(1.0f))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_PRESS),
                                          WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
                                          WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
                                          WithZeroAxis(AXIS_RELATIVE_X),
                                          WithZeroAxis(AXIS_RELATIVE_Y), WithPressure(1.0f)))));

    // Move some more and release the button
    args.clear();
    args += process(EV_REL, REL_X, 10);
    args += process(EV_REL, REL_Y, -5);
    args += process(EV_KEY, BTN_LEFT, 0);
    args += process(EV_SYN, SYN_REPORT, 0);
    ASSERT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(ACTION_MOVE),
                                          WithButtonState(AMOTION_EVENT_BUTTON_PRIMARY),
                                          WithPositiveAxis(AXIS_RELATIVE_X),
                                          WithNegativeAxis(AXIS_RELATIVE_Y), WithPressure(1.0f))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_RELEASE),
                                          WithActionButton(AMOTION_EVENT_BUTTON_PRIMARY),
                                          WithButtonState(0), WithZeroAxis(AXIS_RELATIVE_X),
                                          WithZeroAxis(AXIS_RELATIVE_Y), WithPressure(0.0f))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(ACTION_UP), WithButtonState(0),
                                          WithZeroAxis(AXIS_RELATIVE_X),
                                          WithZeroAxis(AXIS_RELATIVE_Y), WithPressure(0.0f))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(HOVER_MOVE), WithButtonState(0),
                                          WithZeroAxis(AXIS_RELATIVE_X),
                                          WithZeroAxis(AXIS_RELATIVE_Y), WithPressure(0.0f)))));
}

/**
 * Test that enabling mouse swap primary button will have the left click result in a
 * `SECONDARY_BUTTON` event and a right click will result in a `PRIMARY_BUTTON` event.
@@ -539,12 +594,15 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldHandleCombinedXYAndButtonUpdates)
    args += process(ARBITRARY_TIME, EV_KEY, BTN_MOUSE, 1);
    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
    EXPECT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_DOWN)),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(BUTTON_PRESS))));
    EXPECT_THAT(args,
                Each(VariantWith<NotifyMotionArgs>(AllOf(WithPositiveAxis(AXIS_X),
                                                         WithNegativeAxis(AXIS_Y),
                                                         WithPressure(1.0f)))));
                ElementsAre(VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(ACTION_MOVE), WithPressure(0.0f),
                                          WithPositiveAxis(AXIS_X), WithNegativeAxis(AXIS_Y))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(ACTION_DOWN), WithPressure(1.0f),
                                          WithZeroAxis(AXIS_X), WithZeroAxis(AXIS_Y))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_PRESS), WithPressure(1.0f),
                                          WithZeroAxis(AXIS_X), WithZeroAxis(AXIS_Y)))));
    args.clear();

    // Move X, Y a bit while pressed.
@@ -780,11 +838,9 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldHandleAllButtonsWithZeroCoords) {
    args += process(ARBITRARY_TIME, EV_KEY, BTN_RIGHT, 0);
    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
    EXPECT_THAT(args,
                ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(BUTTON_RELEASE)),
                            VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_MOVE))));
    EXPECT_THAT(args,
                Each(VariantWith<NotifyMotionArgs>(
                        AllOf(WithButtonState(AMOTION_EVENT_BUTTON_TERTIARY),
                ElementsAre(VariantWith<NotifyMotionArgs>(
                        AllOf(WithMotionAction(BUTTON_RELEASE),
                              WithButtonState(AMOTION_EVENT_BUTTON_TERTIARY),
                              WithCoords(0.0f, 0.0f), WithPressure(1.0f)))));
    args.clear();

@@ -817,10 +873,6 @@ TEST_P(CursorInputMapperButtonKeyTest, ProcessShouldHandleButtonKeyWithZeroCoord
    EXPECT_THAT(args,
                ElementsAre(VariantWith<NotifyKeyArgs>(AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN),
                                                             WithKeyCode(expectedKeyCode))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(HOVER_MOVE),
                                          WithButtonState(expectedButtonState),
                                          WithCoords(0.0f, 0.0f), WithPressure(0.0f))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_PRESS),
                                          WithButtonState(expectedButtonState),
@@ -833,9 +885,6 @@ TEST_P(CursorInputMapperButtonKeyTest, ProcessShouldHandleButtonKeyWithZeroCoord
                ElementsAre(VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(BUTTON_RELEASE), WithButtonState(0),
                                          WithCoords(0.0f, 0.0f), WithPressure(0.0f))),
                            VariantWith<NotifyMotionArgs>(
                                    AllOf(WithMotionAction(HOVER_MOVE), WithButtonState(0),
                                          WithCoords(0.0f, 0.0f), WithPressure(0.0f))),
                            VariantWith<NotifyKeyArgs>(AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP),
                                                             WithKeyCode(expectedKeyCode)))));
}