Loading services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -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); } } Loading services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java +23 −0 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(), Loading Loading @@ -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 { Loading Loading
services/accessibility/java/com/android/server/accessibility/MotionEventInjector.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -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); } } Loading
services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java +23 −0 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(), Loading Loading @@ -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 { Loading