Loading services/accessibility/accessibility.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,16 @@ flag { bug: "355487062" } flag { name: "event_dispatcher_raw_event" namespace: "accessibility" description: "Fixes EventDispatcher#sendMotionEvent callers to properly provide raw event" bug: "385812366" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "fix_drag_pointer_when_ending_drag" namespace: "accessibility" Loading services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java +9 −4 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.view.accessibility.AccessibilityManager; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accessibility.EventStreamTransformation; import com.android.server.accessibility.Flags; import com.android.server.policy.WindowManagerPolicy; /** Loading Loading @@ -297,6 +298,7 @@ class EventDispatcher { sendMotionEvent( prototype, action, Flags.eventDispatcherRawEvent() ? mState.getLastReceivedRawEvent() : mState.getLastReceivedEvent(), pointerIdBits, policyFlags); Loading Loading @@ -327,6 +329,7 @@ class EventDispatcher { sendMotionEvent( event, action, Flags.eventDispatcherRawEvent() ? mState.getLastReceivedRawEvent() : mState.getLastReceivedEvent(), pointerIdBits, policyFlags); Loading Loading @@ -394,8 +397,10 @@ class EventDispatcher { continue; } final int action = computeInjectionAction(MotionEvent.ACTION_POINTER_UP, i); sendMotionEvent( prototype, action, mState.getLastReceivedEvent(), pointerIdBits, policyFlags); sendMotionEvent(prototype, action, Flags.eventDispatcherRawEvent() ? mState.getLastReceivedRawEvent() : mState.getLastReceivedEvent(), pointerIdBits, policyFlags); pointerIdBits &= ~(1 << pointerId); } } Loading services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java +9 −5 Original line number Diff line number Diff line Loading @@ -497,13 +497,14 @@ public class TouchExplorer extends BaseEventStreamTransformation // We have just decided that the user is touch, // exploring so start sending events. mSendHoverEnterAndMoveDelayed.addEvent(event, mState.getLastReceivedEvent()); mSendHoverEnterAndMoveDelayed.addEvent(event, Flags.eventDispatcherRawEvent() ? rawEvent : mState.getLastReceivedEvent()); mSendHoverEnterAndMoveDelayed.forceSendAndRemove(); mSendHoverExitDelayed.cancel(); mDispatcher.sendMotionEvent( event, ACTION_HOVER_MOVE, event, Flags.eventDispatcherRawEvent() ? rawEvent : event, pointerIdBits, policyFlags); return true; Loading Loading @@ -1099,7 +1100,8 @@ public class TouchExplorer extends BaseEventStreamTransformation * * @param policyFlags The policy flags associated with the event. */ private void sendHoverExitAndTouchExplorationGestureEndIfNeeded(int policyFlags) { @VisibleForTesting void sendHoverExitAndTouchExplorationGestureEndIfNeeded(int policyFlags) { MotionEvent event = mState.getLastInjectedHoverEvent(); if (event != null && event.getActionMasked() != ACTION_HOVER_EXIT) { final int pointerIdBits = event.getPointerIdBits(); Loading @@ -1109,6 +1111,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDispatcher.sendMotionEvent( event, ACTION_HOVER_EXIT, Flags.eventDispatcherRawEvent() ? mState.getLastReceivedRawEvent() : mState.getLastReceivedEvent(), pointerIdBits, policyFlags); Loading @@ -1131,6 +1134,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDispatcher.sendMotionEvent( event, ACTION_HOVER_ENTER, Flags.eventDispatcherRawEvent() ? mState.getLastReceivedRawEvent() : mState.getLastReceivedEvent(), pointerIdBits, policyFlags); Loading services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java +61 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ import static com.android.server.accessibility.gestures.TouchState.STATE_DRAGGIN import static com.android.server.accessibility.gestures.TouchState.STATE_GESTURE_DETECTING; import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_EXPLORING; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; Loading Loading @@ -132,10 +134,12 @@ public class TouchExplorerTest { */ private class EventCaptor implements EventStreamTransformation { List<MotionEvent> mEvents = new ArrayList<>(); List<MotionEvent> mRawEvents = new ArrayList<>(); @Override public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { mEvents.add(0, event.copy()); mRawEvents.add(0, rawEvent.copy()); } @Override Loading Loading @@ -461,6 +465,45 @@ public class TouchExplorerTest { AccessibilityService.GESTURE_3_FINGER_SWIPE_DOWN); } @Test public void testSendHoverExitIfNeeded_lastSentHoverExit_noActionNeeded() { // Prep TouchState so that the last injected hover event was a HOVER_EXIT mTouchExplorer.getState().onInjectedMotionEvent(hoverExitEvent()); mTouchExplorer.sendHoverExitAndTouchExplorationGestureEndIfNeeded(/*policyFlags=*/0); assertNoCapturedEvents(); } @Test @EnableFlags(Flags.FLAG_EVENT_DISPATCHER_RAW_EVENT) public void testSendHoverExitIfNeeded_lastSentHoverEnter_sendsHoverExit_withCorrectRawEvent() { final MotionEvent rawEvent = downEvent(); final MotionEvent modifiedEvent = hoverEnterEvent(); // Use different display IDs just so that we can differentiate between the raw event and // the modified event later during test assertions. final int rawDisplayId = 123; final int modifiedDisplayId = 456; rawEvent.setDisplayId(rawDisplayId); modifiedEvent.setDisplayId(modifiedDisplayId); // Prep TouchState to track the last received modified and raw events mTouchExplorer.getState().onReceivedMotionEvent(modifiedEvent, rawEvent, /*policyFlags=*/0); // Prep TouchState so that the last injected hover event was not a HOVER_EXIT mTouchExplorer.getState().onInjectedMotionEvent(modifiedEvent); mTouchExplorer.sendHoverExitAndTouchExplorationGestureEndIfNeeded(/*policyFlags=*/0); assertThat(getCapturedEvents().size()).isEqualTo(1); assertThat(getCapturedRawEvents().size()).isEqualTo(1); MotionEvent sentEvent = getCapturedEvents().get(0); MotionEvent sentRawEvent = getCapturedRawEvents().get(0); // TouchExplorer should send ACTION_HOVER_EXIT built from the last injected hover event assertThat(sentEvent.getAction()).isEqualTo(ACTION_HOVER_EXIT); assertThat(sentEvent.getDisplayId()).isEqualTo(modifiedDisplayId); // ... while passing along the original raw (unmodified) event assertThat(sentRawEvent.getDisplayId()).isEqualTo(rawDisplayId); } /** * Used to play back event data of a gesture by parsing the log into MotionEvents and sending * them to TouchExplorer. Loading Loading @@ -630,6 +673,10 @@ public class TouchExplorerTest { return ((EventCaptor) mCaptor).mEvents; } private List<MotionEvent> getCapturedRawEvents() { return ((EventCaptor) mCaptor).mRawEvents; } private MotionEvent cancelEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( Loading Loading @@ -688,6 +735,20 @@ public class TouchExplorerTest { return event; } private MotionEvent hoverEnterEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( MotionEvent.obtain( mLastDownTime, mLastDownTime, ACTION_HOVER_ENTER, DEFAULT_X, DEFAULT_Y, 0)); } private MotionEvent hoverExitEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( MotionEvent.obtain( mLastDownTime, mLastDownTime, ACTION_HOVER_EXIT, DEFAULT_X, DEFAULT_Y, 0)); } private void moveEachPointers(MotionEvent event, PointF... points) { final float[] x = new float[points.length]; final float[] y = new float[points.length]; Loading Loading
services/accessibility/accessibility.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,16 @@ flag { bug: "355487062" } flag { name: "event_dispatcher_raw_event" namespace: "accessibility" description: "Fixes EventDispatcher#sendMotionEvent callers to properly provide raw event" bug: "385812366" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "fix_drag_pointer_when_ending_drag" namespace: "accessibility" Loading
services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java +9 −4 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.view.accessibility.AccessibilityManager; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accessibility.EventStreamTransformation; import com.android.server.accessibility.Flags; import com.android.server.policy.WindowManagerPolicy; /** Loading Loading @@ -297,6 +298,7 @@ class EventDispatcher { sendMotionEvent( prototype, action, Flags.eventDispatcherRawEvent() ? mState.getLastReceivedRawEvent() : mState.getLastReceivedEvent(), pointerIdBits, policyFlags); Loading Loading @@ -327,6 +329,7 @@ class EventDispatcher { sendMotionEvent( event, action, Flags.eventDispatcherRawEvent() ? mState.getLastReceivedRawEvent() : mState.getLastReceivedEvent(), pointerIdBits, policyFlags); Loading Loading @@ -394,8 +397,10 @@ class EventDispatcher { continue; } final int action = computeInjectionAction(MotionEvent.ACTION_POINTER_UP, i); sendMotionEvent( prototype, action, mState.getLastReceivedEvent(), pointerIdBits, policyFlags); sendMotionEvent(prototype, action, Flags.eventDispatcherRawEvent() ? mState.getLastReceivedRawEvent() : mState.getLastReceivedEvent(), pointerIdBits, policyFlags); pointerIdBits &= ~(1 << pointerId); } } Loading
services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java +9 −5 Original line number Diff line number Diff line Loading @@ -497,13 +497,14 @@ public class TouchExplorer extends BaseEventStreamTransformation // We have just decided that the user is touch, // exploring so start sending events. mSendHoverEnterAndMoveDelayed.addEvent(event, mState.getLastReceivedEvent()); mSendHoverEnterAndMoveDelayed.addEvent(event, Flags.eventDispatcherRawEvent() ? rawEvent : mState.getLastReceivedEvent()); mSendHoverEnterAndMoveDelayed.forceSendAndRemove(); mSendHoverExitDelayed.cancel(); mDispatcher.sendMotionEvent( event, ACTION_HOVER_MOVE, event, Flags.eventDispatcherRawEvent() ? rawEvent : event, pointerIdBits, policyFlags); return true; Loading Loading @@ -1099,7 +1100,8 @@ public class TouchExplorer extends BaseEventStreamTransformation * * @param policyFlags The policy flags associated with the event. */ private void sendHoverExitAndTouchExplorationGestureEndIfNeeded(int policyFlags) { @VisibleForTesting void sendHoverExitAndTouchExplorationGestureEndIfNeeded(int policyFlags) { MotionEvent event = mState.getLastInjectedHoverEvent(); if (event != null && event.getActionMasked() != ACTION_HOVER_EXIT) { final int pointerIdBits = event.getPointerIdBits(); Loading @@ -1109,6 +1111,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDispatcher.sendMotionEvent( event, ACTION_HOVER_EXIT, Flags.eventDispatcherRawEvent() ? mState.getLastReceivedRawEvent() : mState.getLastReceivedEvent(), pointerIdBits, policyFlags); Loading @@ -1131,6 +1134,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDispatcher.sendMotionEvent( event, ACTION_HOVER_ENTER, Flags.eventDispatcherRawEvent() ? mState.getLastReceivedRawEvent() : mState.getLastReceivedEvent(), pointerIdBits, policyFlags); Loading
services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java +61 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ import static com.android.server.accessibility.gestures.TouchState.STATE_DRAGGIN import static com.android.server.accessibility.gestures.TouchState.STATE_GESTURE_DETECTING; import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_EXPLORING; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; Loading Loading @@ -132,10 +134,12 @@ public class TouchExplorerTest { */ private class EventCaptor implements EventStreamTransformation { List<MotionEvent> mEvents = new ArrayList<>(); List<MotionEvent> mRawEvents = new ArrayList<>(); @Override public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { mEvents.add(0, event.copy()); mRawEvents.add(0, rawEvent.copy()); } @Override Loading Loading @@ -461,6 +465,45 @@ public class TouchExplorerTest { AccessibilityService.GESTURE_3_FINGER_SWIPE_DOWN); } @Test public void testSendHoverExitIfNeeded_lastSentHoverExit_noActionNeeded() { // Prep TouchState so that the last injected hover event was a HOVER_EXIT mTouchExplorer.getState().onInjectedMotionEvent(hoverExitEvent()); mTouchExplorer.sendHoverExitAndTouchExplorationGestureEndIfNeeded(/*policyFlags=*/0); assertNoCapturedEvents(); } @Test @EnableFlags(Flags.FLAG_EVENT_DISPATCHER_RAW_EVENT) public void testSendHoverExitIfNeeded_lastSentHoverEnter_sendsHoverExit_withCorrectRawEvent() { final MotionEvent rawEvent = downEvent(); final MotionEvent modifiedEvent = hoverEnterEvent(); // Use different display IDs just so that we can differentiate between the raw event and // the modified event later during test assertions. final int rawDisplayId = 123; final int modifiedDisplayId = 456; rawEvent.setDisplayId(rawDisplayId); modifiedEvent.setDisplayId(modifiedDisplayId); // Prep TouchState to track the last received modified and raw events mTouchExplorer.getState().onReceivedMotionEvent(modifiedEvent, rawEvent, /*policyFlags=*/0); // Prep TouchState so that the last injected hover event was not a HOVER_EXIT mTouchExplorer.getState().onInjectedMotionEvent(modifiedEvent); mTouchExplorer.sendHoverExitAndTouchExplorationGestureEndIfNeeded(/*policyFlags=*/0); assertThat(getCapturedEvents().size()).isEqualTo(1); assertThat(getCapturedRawEvents().size()).isEqualTo(1); MotionEvent sentEvent = getCapturedEvents().get(0); MotionEvent sentRawEvent = getCapturedRawEvents().get(0); // TouchExplorer should send ACTION_HOVER_EXIT built from the last injected hover event assertThat(sentEvent.getAction()).isEqualTo(ACTION_HOVER_EXIT); assertThat(sentEvent.getDisplayId()).isEqualTo(modifiedDisplayId); // ... while passing along the original raw (unmodified) event assertThat(sentRawEvent.getDisplayId()).isEqualTo(rawDisplayId); } /** * Used to play back event data of a gesture by parsing the log into MotionEvents and sending * them to TouchExplorer. Loading Loading @@ -630,6 +673,10 @@ public class TouchExplorerTest { return ((EventCaptor) mCaptor).mEvents; } private List<MotionEvent> getCapturedRawEvents() { return ((EventCaptor) mCaptor).mRawEvents; } private MotionEvent cancelEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( Loading Loading @@ -688,6 +735,20 @@ public class TouchExplorerTest { return event; } private MotionEvent hoverEnterEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( MotionEvent.obtain( mLastDownTime, mLastDownTime, ACTION_HOVER_ENTER, DEFAULT_X, DEFAULT_Y, 0)); } private MotionEvent hoverExitEvent() { mLastDownTime = SystemClock.uptimeMillis(); return fromTouchscreen( MotionEvent.obtain( mLastDownTime, mLastDownTime, ACTION_HOVER_EXIT, DEFAULT_X, DEFAULT_Y, 0)); } private void moveEachPointers(MotionEvent event, PointF... points) { final float[] x = new float[points.length]; final float[] y = new float[points.length]; Loading