diff options
| author | 2019-09-20 16:07:32 -0700 | |
|---|---|---|
| committer | 2019-10-02 11:39:56 -0700 | |
| commit | 6d70fac912083d323249a19b55f406804bddd788 (patch) | |
| tree | 371dfd7d919d662f9731ae30c903ac32fbba207d | |
| parent | 781630e4b4d67e0371c133ae64923ede1b989250 (diff) | |
TouchExplorer: pass raw events when sending events.
Right now we just send null. This was a todo to be fixed and will mean that the event stream operates consistently.
Bug: 136131815
Test: atest CtsAccessibilityTestCases CtsAccessibilityServiceTestCases
Test: atest FrameworksServicesTests:TouchExplorerTest FrameworksServicesTests:MotionEventInjectorTest
Change-Id: I4578ef4ffe6d3c3e4fc2aa2d06fc0caaa8bb9713
6 files changed, 209 insertions, 111 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java b/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java index dc7a9aaf966d..5ac3b69549c1 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java @@ -72,10 +72,16 @@ class EventDispatcher { * * @param prototype The prototype from which to create the injected events. * @param action The action of the event. + * @param rawEvent The original event prior to magnification or other transformations. * @param pointerIdBits The bits of the pointers to send. * @param policyFlags The policy flags associated with the event. */ - void sendMotionEvent(MotionEvent prototype, int action, int pointerIdBits, int policyFlags) { + void sendMotionEvent( + MotionEvent prototype, + int action, + MotionEvent rawEvent, + int pointerIdBits, + int policyFlags) { prototype.setAction(action); MotionEvent event = null; @@ -105,11 +111,8 @@ class EventDispatcher { // Make sure that the user will see the event. policyFlags |= WindowManagerPolicy.FLAG_PASS_TO_USER; - // TODO: For now pass null for the raw event since the touch - // explorer is the last event transformation and it does - // not care about the raw event. if (mReceiver != null) { - mReceiver.onMotionEvent(event, null, policyFlags); + mReceiver.onMotionEvent(event, rawEvent, policyFlags); } else { Slog.e(LOG_TAG, "Error sending event: no receiver specified."); } @@ -280,7 +283,12 @@ class EventDispatcher { if (!isInjectedPointerDown(pointerId)) { pointerIdBits |= (1 << pointerId); final int action = computeInjectionAction(MotionEvent.ACTION_DOWN, i); - sendMotionEvent(prototype, action, pointerIdBits, policyFlags); + sendMotionEvent( + prototype, + action, + mState.getLastReceivedEvent(), + pointerIdBits, + policyFlags); } } } @@ -303,7 +311,8 @@ class EventDispatcher { } pointerIdBits |= (1 << pointerId); final int action = computeInjectionAction(MotionEvent.ACTION_UP, i); - sendMotionEvent(prototype, action, pointerIdBits, policyFlags); + sendMotionEvent( + prototype, action, mState.getLastReceivedEvent(), pointerIdBits, policyFlags); } } } diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java index f4ac82157d04..c60e35e2cc6d 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java @@ -183,9 +183,9 @@ public class TouchExplorer extends BaseEventStreamTransformation private void clear() { // If we have not received an event then we are in initial // state. Therefore, there is not need to clean anything. - MotionEvent event = mReceivedPointerTracker.getLastReceivedEvent(); + MotionEvent event = mState.getLastReceivedEvent(); if (event != null) { - clear(mReceivedPointerTracker.getLastReceivedEvent(), WindowManagerPolicy.FLAG_TRUSTED); + clear(event, WindowManagerPolicy.FLAG_TRUSTED); } } @@ -229,7 +229,7 @@ public class TouchExplorer extends BaseEventStreamTransformation Slog.d(LOG_TAG, mState.toString()); } - mReceivedPointerTracker.onMotionEvent(rawEvent); + mState.onReceivedMotionEvent(rawEvent); if (mGestureDetector.onMotionEvent(event, rawEvent, policyFlags)) { // Event was handled by the gesture detector. @@ -250,9 +250,9 @@ public class TouchExplorer extends BaseEventStreamTransformation } else if (mState.isTouchExploring()) { handleMotionEventStateTouchExploring(event, rawEvent, policyFlags); } else if (mState.isDragging()) { - handleMotionEventStateDragging(event, policyFlags); + handleMotionEventStateDragging(event, rawEvent, policyFlags); } else if (mState.isDelegating()) { - handleMotionEventStateDelegating(event, policyFlags); + handleMotionEventStateDelegating(event, rawEvent, policyFlags); } else if (mState.isGestureDetecting()) { // Already handled. } else { @@ -292,7 +292,7 @@ public class TouchExplorer extends BaseEventStreamTransformation } // Pointers should not be zero when running this command. - if (mReceivedPointerTracker.getLastReceivedEvent().getPointerCount() == 0) { + if (mState.getLastReceivedEvent().getPointerCount() == 0) { return; } // Try to use the standard accessibility API to long click @@ -368,11 +368,15 @@ public class TouchExplorer extends BaseEventStreamTransformation // We have just decided that the user is touch, // exploring so start sending events. - mSendHoverEnterAndMoveDelayed.addEvent(event); + mSendHoverEnterAndMoveDelayed.addEvent(event, mState.getLastReceivedEvent()); mSendHoverEnterAndMoveDelayed.forceSendAndRemove(); mSendHoverExitDelayed.cancel(); mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); + event, + MotionEvent.ACTION_HOVER_MOVE, + mState.getLastReceivedEvent(), + pointerIdBits, + policyFlags); return true; } } @@ -387,7 +391,7 @@ public class TouchExplorer extends BaseEventStreamTransformation switch (event.getActionMasked()) { // The only way to leave the clear state is for a pointer to go down. case MotionEvent.ACTION_DOWN: - handleActionDown(event, policyFlags); + handleActionDown(event, rawEvent, policyFlags); break; default: // Some other nonsensical event. @@ -399,7 +403,7 @@ public class TouchExplorer extends BaseEventStreamTransformation * Handles ACTION_DOWN while in the clear or touch interacting states. This event represents the * first finger touching the screen. */ - private void handleActionDown(MotionEvent event, int policyFlags) { + private void handleActionDown(MotionEvent event, MotionEvent rawEvent, int policyFlags) { mAms.onTouchInteractionStart(); // If we still have not notified the user for the last @@ -432,10 +436,10 @@ public class TouchExplorer extends BaseEventStreamTransformation // The idea is to avoid getting stuck in STATE_TOUCH_INTERACTING final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); final int pointerIdBits = (1 << pointerId); - mSendHoverEnterAndMoveDelayed.post(event, pointerIdBits, policyFlags); + mSendHoverEnterAndMoveDelayed.post(event, rawEvent, pointerIdBits, policyFlags); } else { // Cache the event until we discern exploration from gesturing. - mSendHoverEnterAndMoveDelayed.addEvent(event); + mSendHoverEnterAndMoveDelayed.addEvent(event, rawEvent); } } } @@ -453,7 +457,7 @@ public class TouchExplorer extends BaseEventStreamTransformation case MotionEvent.ACTION_DOWN: // Continue the previous interaction. mSendTouchInteractionEndDelayed.cancel(); - handleActionDown(event, policyFlags); + handleActionDown(event, rawEvent, policyFlags); break; case MotionEvent.ACTION_POINTER_DOWN: handleActionPointerDown(); @@ -462,7 +466,7 @@ public class TouchExplorer extends BaseEventStreamTransformation handleActionMoveStateTouchInteracting(event, rawEvent, policyFlags); break; case MotionEvent.ACTION_UP: - handleActionUp(event, policyFlags); + handleActionUp(event, rawEvent, policyFlags); break; } } @@ -487,7 +491,7 @@ public class TouchExplorer extends BaseEventStreamTransformation handleActionMoveStateTouchExploring(event, rawEvent, policyFlags); break; case MotionEvent.ACTION_UP: - handleActionUp(event, policyFlags); + handleActionUp(event, rawEvent, policyFlags); break; default: break; @@ -520,7 +524,7 @@ public class TouchExplorer extends BaseEventStreamTransformation // figure out what the user is doing. if (mSendHoverEnterAndMoveDelayed.isPending()) { // Cache the event until we discern exploration from gesturing. - mSendHoverEnterAndMoveDelayed.addEvent(event); + mSendHoverEnterAndMoveDelayed.addEvent(event, rawEvent); } break; case 2: @@ -538,7 +542,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDraggingPointerId = pointerId; event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags()); mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags); + event, MotionEvent.ACTION_DOWN, rawEvent, pointerIdBits, policyFlags); } else { // Two pointers moving arbitrary are delegated to the view hierarchy. mState.startDelegating(); @@ -558,13 +562,13 @@ public class TouchExplorer extends BaseEventStreamTransformation * Handles ACTION_UP while in the touch interacting state. This event represents all fingers * being lifted from the screen. */ - private void handleActionUp(MotionEvent event, int policyFlags) { + private void handleActionUp(MotionEvent event, MotionEvent rawEvent, int policyFlags) { mAms.onTouchInteractionEnd(); final int pointerId = event.getPointerId(event.getActionIndex()); final int pointerIdBits = (1 << pointerId); if (mSendHoverEnterAndMoveDelayed.isPending()) { // If we have not delivered the enter schedule an exit. - mSendHoverExitDelayed.post(event, pointerIdBits, policyFlags); + mSendHoverExitDelayed.post(event, rawEvent, pointerIdBits, policyFlags); } else { // The user is touch exploring so we send events for end. sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); @@ -588,7 +592,7 @@ public class TouchExplorer extends BaseEventStreamTransformation // Touch exploration. sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags); mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); + event, MotionEvent.ACTION_HOVER_MOVE, rawEvent, pointerIdBits, policyFlags); break; case 2: if (mSendHoverEnterAndMoveDelayed.isPending()) { @@ -638,7 +642,8 @@ public class TouchExplorer extends BaseEventStreamTransformation * @param event The event to be handled. * @param policyFlags The policy flags associated with the event. */ - private void handleMotionEventStateDragging(MotionEvent event, int policyFlags) { + private void handleMotionEventStateDragging( + MotionEvent event, MotionEvent rawEvent, int policyFlags) { int pointerIdBits = 0; // Clear the dragging pointer id if it's no longer valid. if (event.findPointerIndex(mDraggingPointerId) == -1) { @@ -662,7 +667,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mState.startDelegating(); if (mDraggingPointerId != INVALID_POINTER_ID) { mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags); + event, MotionEvent.ACTION_UP, rawEvent, pointerIdBits, policyFlags); } mDispatcher.sendDownForAllNotInjectedPointers(event, policyFlags); } break; @@ -681,6 +686,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDispatcher.sendMotionEvent( event, MotionEvent.ACTION_MOVE, + rawEvent, pointerIdBits, policyFlags); } else { @@ -690,7 +696,11 @@ public class TouchExplorer extends BaseEventStreamTransformation // Remove move history before send injected non-move events event = MotionEvent.obtainNoHistory(event); // Send an event to the end of the drag gesture. - mDispatcher.sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, + mDispatcher.sendMotionEvent( + event, + MotionEvent.ACTION_UP, + rawEvent, + pointerIdBits, policyFlags); // Deliver all pointers to the view hierarchy. mDispatcher.sendDownForAllNotInjectedPointers(event, policyFlags); @@ -700,7 +710,11 @@ public class TouchExplorer extends BaseEventStreamTransformation mState.startDelegating(); event = MotionEvent.obtainNoHistory(event); // Send an event to the end of the drag gesture. - mDispatcher.sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, + mDispatcher.sendMotionEvent( + event, + MotionEvent.ACTION_UP, + rawEvent, + pointerIdBits, policyFlags); // Deliver all pointers to the view hierarchy. mDispatcher.sendDownForAllNotInjectedPointers(event, policyFlags); @@ -713,7 +727,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDraggingPointerId = INVALID_POINTER_ID; // Send an event to the end of the drag gesture. mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags); + event, MotionEvent.ACTION_UP, rawEvent, pointerIdBits, policyFlags); } } break; case MotionEvent.ACTION_UP: { @@ -726,7 +740,7 @@ public class TouchExplorer extends BaseEventStreamTransformation mDraggingPointerId = INVALID_POINTER_ID; // Send an event to the end of the drag gesture. mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags); + event, MotionEvent.ACTION_UP, rawEvent, pointerIdBits, policyFlags); } } break; } @@ -738,7 +752,8 @@ public class TouchExplorer extends BaseEventStreamTransformation * @param event The event to be handled. * @param policyFlags The policy flags associated with the event. */ - private void handleMotionEventStateDelegating(MotionEvent event, int policyFlags) { + private void handleMotionEventStateDelegating( + MotionEvent event, MotionEvent rawEvent, int policyFlags) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: { Slog.e(LOG_TAG, "Delegating state can only be reached if " @@ -749,7 +764,7 @@ public class TouchExplorer extends BaseEventStreamTransformation case MotionEvent.ACTION_UP: { // Deliver the event. mDispatcher.sendMotionEvent( - event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags); + event, event.getAction(), rawEvent, ALL_POINTER_ID_BITS, policyFlags); // Announce the end of a the touch interaction. mAms.onTouchInteractionEnd(); @@ -759,7 +774,7 @@ public class TouchExplorer extends BaseEventStreamTransformation default: { // Deliver the event. mDispatcher.sendMotionEvent( - event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags); + event, event.getAction(), rawEvent, ALL_POINTER_ID_BITS, policyFlags); } } } @@ -792,7 +807,11 @@ public class TouchExplorer extends BaseEventStreamTransformation mSendTouchExplorationEndDelayed.post(); } mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags); + event, + MotionEvent.ACTION_HOVER_EXIT, + mState.getLastReceivedEvent(), + pointerIdBits, + policyFlags); } } @@ -807,7 +826,11 @@ public class TouchExplorer extends BaseEventStreamTransformation if (event != null && event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { final int pointerIdBits = event.getPointerIdBits(); mDispatcher.sendMotionEvent( - event, MotionEvent.ACTION_HOVER_ENTER, pointerIdBits, policyFlags); + event, + MotionEvent.ACTION_HOVER_ENTER, + mState.getLastReceivedEvent(), + pointerIdBits, + policyFlags); } } @@ -891,20 +914,23 @@ public class TouchExplorer extends BaseEventStreamTransformation private final String LOG_TAG_SEND_HOVER_DELAYED = "SendHoverEnterAndMoveDelayed"; private final List<MotionEvent> mEvents = new ArrayList<MotionEvent>(); + private final List<MotionEvent> mRawEvents = new ArrayList<MotionEvent>(); private int mPointerIdBits; private int mPolicyFlags; - public void post(MotionEvent event, int pointerIdBits, int policyFlags) { + public void post( + MotionEvent event, MotionEvent rawEvent, int pointerIdBits, int policyFlags) { cancel(); - addEvent(event); + addEvent(event, rawEvent); mPointerIdBits = pointerIdBits; mPolicyFlags = policyFlags; mHandler.postDelayed(this, mDetermineUserIntentTimeout); } - public void addEvent(MotionEvent event) { + public void addEvent(MotionEvent event, MotionEvent rawEvent) { mEvents.add(MotionEvent.obtain(event)); + mRawEvents.add(MotionEvent.obtain(rawEvent)); } public void cancel() { @@ -925,6 +951,10 @@ public class TouchExplorer extends BaseEventStreamTransformation for (int i = eventCount - 1; i >= 0; i--) { mEvents.remove(i).recycle(); } + final int rawEventcount = mRawEvents.size(); + for (int i = rawEventcount - 1; i >= 0; i--) { + mRawEvents.remove(i).recycle(); + } } public void forceSendAndRemove() { @@ -939,10 +969,10 @@ public class TouchExplorer extends BaseEventStreamTransformation mDispatcher.sendAccessibilityEvent( AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START); - if (!mEvents.isEmpty()) { + if (!mEvents.isEmpty() && !mRawEvents.isEmpty()) { // Deliver a down event. mDispatcher.sendMotionEvent(mEvents.get(0), MotionEvent.ACTION_HOVER_ENTER, - mPointerIdBits, mPolicyFlags); + mRawEvents.get(0), mPointerIdBits, mPolicyFlags); if (DEBUG) { Slog.d(LOG_TAG_SEND_HOVER_DELAYED, "Injecting motion event: ACTION_HOVER_ENTER"); @@ -952,7 +982,7 @@ public class TouchExplorer extends BaseEventStreamTransformation final int eventCount = mEvents.size(); for (int i = 1; i < eventCount; i++) { mDispatcher.sendMotionEvent(mEvents.get(i), MotionEvent.ACTION_HOVER_MOVE, - mPointerIdBits, mPolicyFlags); + mRawEvents.get(i), mPointerIdBits, mPolicyFlags); if (DEBUG) { Slog.d(LOG_TAG_SEND_HOVER_DELAYED, "Injecting motion event: ACTION_HOVER_MOVE"); @@ -970,12 +1000,15 @@ public class TouchExplorer extends BaseEventStreamTransformation private final String LOG_TAG_SEND_HOVER_DELAYED = "SendHoverExitDelayed"; private MotionEvent mPrototype; + private MotionEvent mRawEvent; private int mPointerIdBits; private int mPolicyFlags; - public void post(MotionEvent prototype, int pointerIdBits, int policyFlags) { + public void post( + MotionEvent prototype, MotionEvent rawEvent, int pointerIdBits, int policyFlags) { cancel(); mPrototype = MotionEvent.obtain(prototype); + mRawEvent = MotionEvent.obtain(rawEvent); mPointerIdBits = pointerIdBits; mPolicyFlags = policyFlags; mHandler.postDelayed(this, mDetermineUserIntentTimeout); @@ -993,8 +1026,14 @@ public class TouchExplorer extends BaseEventStreamTransformation } private void clear() { - mPrototype.recycle(); + if (mPrototype != null) { + mPrototype.recycle(); + } + if (mRawEvent != null) { + mRawEvent.recycle(); + } mPrototype = null; + mRawEvent = null; mPointerIdBits = -1; mPolicyFlags = 0; } @@ -1011,8 +1050,12 @@ public class TouchExplorer extends BaseEventStreamTransformation Slog.d(LOG_TAG_SEND_HOVER_DELAYED, "Injecting motion event:" + " ACTION_HOVER_EXIT"); } - mDispatcher.sendMotionEvent(mPrototype, MotionEvent.ACTION_HOVER_EXIT, - mPointerIdBits, mPolicyFlags); + mDispatcher.sendMotionEvent( + mPrototype, + MotionEvent.ACTION_HOVER_EXIT, + mRawEvent, + mPointerIdBits, + mPolicyFlags); if (!mSendTouchExplorationEndDelayed.isPending()) { mSendTouchExplorationEndDelayed.cancel(); mSendTouchExplorationEndDelayed.post(); diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java index 49938fa4c6b9..f463260a9d02 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java @@ -71,6 +71,7 @@ public class TouchState { // Helper class to track received pointers. // Todo: collapse or hide this class so multiple classes don't modify it. private final ReceivedPointerTracker mReceivedPointerTracker; + private MotionEvent mLastReceivedEvent; public TouchState() { mReceivedPointerTracker = new ReceivedPointerTracker(); @@ -80,6 +81,10 @@ public class TouchState { public void clear() { setState(STATE_CLEAR); // Reset the pointer trackers. + if (mLastReceivedEvent != null) { + mLastReceivedEvent.recycle(); + mLastReceivedEvent = null; + } mReceivedPointerTracker.clear(); } @@ -89,6 +94,10 @@ public class TouchState { * @param rawEvent The raw touch event. */ public void onReceivedMotionEvent(MotionEvent rawEvent) { + if (mLastReceivedEvent != null) { + mLastReceivedEvent.recycle(); + } + mLastReceivedEvent = MotionEvent.obtain(rawEvent); mReceivedPointerTracker.onMotionEvent(rawEvent); } @@ -216,6 +225,11 @@ public class TouchState { return mReceivedPointerTracker; } + /** @return The last received event. */ + public MotionEvent getLastReceivedEvent() { + return mLastReceivedEvent; + } + /** This class tracks where and when a pointer went down. It does not track its movement. */ class ReceivedPointerTracker { private static final String LOG_TAG_RECEIVED_POINTER_TRACKER = "ReceivedPointerTracker"; @@ -232,8 +246,6 @@ public class TouchState { // or if it goes up the next one that most recently went down. private int mPrimaryPointerId; - // Keep track of the last up pointer data. - private MotionEvent mLastReceivedEvent; ReceivedPointerTracker() { clear(); @@ -254,11 +266,6 @@ public class TouchState { * @param event The event to process. */ public void onMotionEvent(MotionEvent event) { - if (mLastReceivedEvent != null) { - mLastReceivedEvent.recycle(); - } - mLastReceivedEvent = MotionEvent.obtain(event); - final int action = event.getActionMasked(); switch (action) { case MotionEvent.ACTION_DOWN: @@ -279,11 +286,6 @@ public class TouchState { } } - /** @return The last received event. */ - public MotionEvent getLastReceivedEvent() { - return mLastReceivedEvent; - } - /** @return The number of received pointers that are down. */ public int getReceivedPointerDownCount() { return Integer.bitCount(mReceivedPointersDown); diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java index f1142fd2f8f9..36e854ca77cd 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java @@ -46,7 +46,6 @@ import android.graphics.Point; import android.os.Handler; import android.os.Message; import android.os.RemoteException; -import android.util.Log; import android.view.Display; import android.view.InputDevice; import android.view.KeyEvent; @@ -55,6 +54,8 @@ import android.view.accessibility.AccessibilityEvent; import androidx.test.runner.AndroidJUnit4; +import com.android.server.accessibility.utils.MotionEventMatcher; + import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; @@ -761,56 +762,6 @@ public class MotionEventInjectorTest { return next; } - static class MotionEventMatcher extends TypeSafeMatcher<MotionEvent> { - long mDownTime; - long mEventTime; - long mActionMasked; - int mX; - int mY; - - MotionEventMatcher(long downTime, long eventTime, int actionMasked, int x, int y) { - mDownTime = downTime; - mEventTime = eventTime; - mActionMasked = actionMasked; - mX = x; - mY = y; - } - - MotionEventMatcher(MotionEvent event) { - this(event.getDownTime(), event.getEventTime(), event.getActionMasked(), - (int) event.getX(), (int) event.getY()); - } - - void offsetTimesBy(long timeOffset) { - mDownTime += timeOffset; - mEventTime += timeOffset; - } - - @Override - public boolean matchesSafely(MotionEvent event) { - if ((event.getDownTime() == mDownTime) && (event.getEventTime() == mEventTime) - && (event.getActionMasked() == mActionMasked) && ((int) event.getX() == mX) - && ((int) event.getY() == mY)) { - return true; - } - Log.e(LOG_TAG, "MotionEvent match failed"); - Log.e(LOG_TAG, "event.getDownTime() = " + event.getDownTime() - + ", expected " + mDownTime); - Log.e(LOG_TAG, "event.getEventTime() = " + event.getEventTime() - + ", expected " + mEventTime); - Log.e(LOG_TAG, "event.getActionMasked() = " + event.getActionMasked() - + ", expected " + mActionMasked); - Log.e(LOG_TAG, "event.getX() = " + event.getX() + ", expected " + mX); - Log.e(LOG_TAG, "event.getY() = " + event.getY() + ", expected " + mY); - return false; - } - - @Override - public void describeTo(Description description) { - description.appendText("Motion event matcher"); - } - } - private static class MotionEventActionMatcher extends TypeSafeMatcher<MotionEvent> { int mAction; diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java index 104aacb5ef79..4b1ec6fe032b 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java @@ -21,6 +21,7 @@ import static com.android.server.accessibility.gestures.TouchState.STATE_DELEGAT import static com.android.server.accessibility.gestures.TouchState.STATE_DRAGGING; import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_EXPLORING; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; @@ -36,6 +37,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accessibility.EventStreamTransformation; +import com.android.server.accessibility.utils.MotionEventMatcher; import org.junit.Before; import org.junit.Rule; @@ -49,6 +51,7 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class TouchExplorerTest { + private static final String LOG_TAG = "TouchExplorerTest"; private static final int FLAG_1FINGER = 0x8000; private static final int FLAG_2FINGERS = 0x0100; private static final int FLAG_3FINGERS = 0x0200; @@ -86,7 +89,9 @@ public class TouchExplorerTest { @Override public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { + MotionEventMatcher lastEventMatcher = new MotionEventMatcher(mLastEvent); mEvents.add(0, event.copy()); + assertThat(rawEvent, lastEventMatcher); } @Override diff --git a/services/tests/servicestests/src/com/android/server/accessibility/utils/MotionEventMatcher.java b/services/tests/servicestests/src/com/android/server/accessibility/utils/MotionEventMatcher.java new file mode 100644 index 000000000000..2b6d385fed48 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/accessibility/utils/MotionEventMatcher.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.accessibility.utils; + +import android.util.Log; +import android.view.MotionEvent; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + +/** + * This class compares two motion events using a subset of their attributes: actionMasked, downTime, + * eventTime, and location. If two events match they are considered to be effectively equal. + */ +public class MotionEventMatcher extends TypeSafeMatcher<MotionEvent> { + private static final String LOG_TAG = "MotionEventMatcher"; + long mDownTime; + long mEventTime; + long mActionMasked; + int mX; + int mY; + + MotionEventMatcher(long downTime, long eventTime, int actionMasked, int x, int y) { + mDownTime = downTime; + mEventTime = eventTime; + mActionMasked = actionMasked; + mX = x; + mY = y; + } + + public MotionEventMatcher(MotionEvent event) { + this( + event.getDownTime(), + event.getEventTime(), + event.getActionMasked(), + (int) event.getX(), + (int) event.getY()); + } + + void offsetTimesBy(long timeOffset) { + mDownTime += timeOffset; + mEventTime += timeOffset; + } + + @Override + public boolean matchesSafely(MotionEvent event) { + if ((event.getDownTime() == mDownTime) + && (event.getEventTime() == mEventTime) + && (event.getActionMasked() == mActionMasked) + && ((int) event.getX() == mX) + && ((int) event.getY() == mY)) { + return true; + } + Log.e(LOG_TAG, "MotionEvent match failed"); + Log.e(LOG_TAG, "event.getDownTime() = " + event.getDownTime() + ", expected " + mDownTime); + Log.e( + LOG_TAG, + "event.getEventTime() = " + event.getEventTime() + ", expected " + mEventTime); + Log.e( + LOG_TAG, + "event.getActionMasked() = " + + event.getActionMasked() + + ", expected " + + mActionMasked); + Log.e(LOG_TAG, "event.getX() = " + event.getX() + ", expected " + mX); + Log.e(LOG_TAG, "event.getY() = " + event.getY() + ", expected " + mY); + return false; + } + + @Override + public void describeTo(Description description) { + description.appendText("Motion event matcher"); + } +} |