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

Commit e95df8ae authored by Jackal Guo's avatar Jackal Guo
Browse files

Don't cancel injected event when mouse event arrives

Currently, MotionEventInjector would cancel any injected gesture when
any MotionEvent arrives. For user using an external device to control
the pointer movement, it's almost impossible to perform the gestures.
Any slightly unintended movement results in the cancellation of the
gesture.

However, if MotionEventInjector keeps sending mouse movement events
when gesture is performing, dispatch logic would be confused and it
causes the gesture malfunction. Therefore, ignore movement events
from mouse when there is an ongoing gesture since click event from
mouse should be intended.

Bug: 116459737
Test: add a new test case in MotionEventInjectorTest
Test: a11y CTS & unit tests
Change-Id: I2c2be8cf565ba15d1a9cd6bc8c45b695c1309b56
parent 4d4c558f
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -111,6 +111,15 @@ public class MotionEventInjector extends BaseEventStreamTransformation implement


    @Override
    @Override
    public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
    public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        // MotionEventInjector would cancel any injected gesture when any MotionEvent arrives.
        // For user using an external device to control the pointer movement, it's almost
        // impossible to perform the gestures. Any slightly unintended movement results in the
        // cancellation of the gesture.
        if ((event.isFromSource(InputDevice.SOURCE_MOUSE)
                && event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE)
                && mOpenGesturesInProgress.get(EVENT_SOURCE, false)) {
            return;
        }
        cancelAnyPendingInjectedEvents();
        cancelAnyPendingInjectedEvents();
        sendMotionEventToNext(event, rawEvent, policyFlags);
        sendMotionEventToNext(event, rawEvent, policyFlags);
    }
    }
+23 −0
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.accessibility;
package com.android.server.accessibility;


import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_HOVER_MOVE;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.WindowManagerPolicyConstants.FLAG_PASS_TO_USER;
import static android.view.WindowManagerPolicyConstants.FLAG_PASS_TO_USER;


@@ -116,6 +117,7 @@ public class MotionEventInjectorTest {


    MotionEvent mClickDownEvent;
    MotionEvent mClickDownEvent;
    MotionEvent mClickUpEvent;
    MotionEvent mClickUpEvent;
    MotionEvent mHoverMoveEvent;


    ArgumentCaptor<MotionEvent> mCaptor1 = ArgumentCaptor.forClass(MotionEvent.class);
    ArgumentCaptor<MotionEvent> mCaptor1 = ArgumentCaptor.forClass(MotionEvent.class);
    ArgumentCaptor<MotionEvent> mCaptor2 = ArgumentCaptor.forClass(MotionEvent.class);
    ArgumentCaptor<MotionEvent> mCaptor2 = ArgumentCaptor.forClass(MotionEvent.class);
@@ -152,6 +154,10 @@ public class MotionEventInjectorTest {
                CLICK_POINT.y, 0);
                CLICK_POINT.y, 0);
        mClickUpEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
        mClickUpEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);


        mHoverMoveEvent = MotionEvent.obtain(0, 0, ACTION_HOVER_MOVE, CLICK_POINT.x, CLICK_POINT.y,
                0);
        mHoverMoveEvent.setSource(InputDevice.SOURCE_MOUSE);

        mIsLineStart = allOf(IS_ACTION_DOWN, isAtPoint(LINE_START), hasStandardInitialization(),
        mIsLineStart = allOf(IS_ACTION_DOWN, isAtPoint(LINE_START), hasStandardInitialization(),
                hasTimeFromDown(0));
                hasTimeFromDown(0));
        mIsLineMiddle = allOf(IS_ACTION_MOVE, isAtPoint(LINE_END), hasStandardInitialization(),
        mIsLineMiddle = allOf(IS_ACTION_MOVE, isAtPoint(LINE_END), hasStandardInitialization(),
@@ -300,6 +306,23 @@ public class MotionEventInjectorTest {
        verify(mServiceInterface).onPerformGestureResult(LINE_SEQUENCE, false);
        verify(mServiceInterface).onPerformGestureResult(LINE_SEQUENCE, false);
    }
    }


    @Test
    public void
            testOnMotionEvents_fromMouseWithInjectedGestureInProgress_shouldNotCancelAndPassReal()
            throws RemoteException {
        EventStreamTransformation next = attachMockNext(mMotionEventInjector);
        injectEventsSync(mLineList, mServiceInterface, LINE_SEQUENCE);
        mMessageCapturingHandler.sendOneMessage(); // Send a motion event
        mMotionEventInjector.onMotionEvent(mHoverMoveEvent, mHoverMoveEvent, 0);
        mMessageCapturingHandler.sendAllMessages();

        verify(next, times(3)).onMotionEvent(mCaptor1.capture(), mCaptor2.capture(), anyInt());
        assertThat(mCaptor1.getAllValues().get(0), mIsLineStart);
        assertThat(mCaptor1.getAllValues().get(1), mIsLineMiddle);
        assertThat(mCaptor1.getAllValues().get(2), mIsLineEnd);
        verify(mServiceInterface).onPerformGestureResult(LINE_SEQUENCE, true);
    }

    @Test
    @Test
    public void testOnMotionEvents_closedInjectedGestureInProgress_shouldOnlyNotifyAndPassReal()
    public void testOnMotionEvents_closedInjectedGestureInProgress_shouldOnlyNotifyAndPassReal()
            throws RemoteException {
            throws RemoteException {