Start dragging where the fingers initially went down.
This does not apply when transitioning from touch exploration to dragging.
Bug: 162521649
Test: manual
Change-Id: I92022ca0359040a6563e6a48c110face574dc9df
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 b587dd3..44250ff 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -612,12 +612,20 @@
if (isDraggingGesture(event)) {
// Two pointers moving in the same direction within
// a given distance perform a drag.
- mState.startDragging();
computeDraggingPointerIdIfNeeded(event);
pointerIdBits = 1 << mDraggingPointerId;
event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags());
- mDispatcher.sendMotionEvent(
- event, ACTION_DOWN, rawEvent, pointerIdBits, policyFlags);
+ MotionEvent downEvent = computeDownEventForDrag(event);
+ if (downEvent != null) {
+ mDispatcher.sendMotionEvent(
+ downEvent, ACTION_DOWN, rawEvent, pointerIdBits, policyFlags);
+ mDispatcher.sendMotionEvent(
+ event, ACTION_MOVE, rawEvent, pointerIdBits, policyFlags);
+ } else {
+ mDispatcher.sendMotionEvent(
+ event, ACTION_DOWN, rawEvent, pointerIdBits, policyFlags);
+ }
+ mState.startDragging();
} else {
// Two pointers moving arbitrary are delegated to the view hierarchy.
mState.startDelegating();
@@ -1004,6 +1012,49 @@
return distance;
}
+ /**
+ * Creates a down event using the down coordinates of the dragging pointer and other information
+ * from the supplied event. The supplied event's down time is adjusted to reflect the time when
+ * the dragging pointer initially went down.
+ */
+ private MotionEvent computeDownEventForDrag(MotionEvent event) {
+ // Creating a down event only makes sense if we haven't started touch exploring yet.
+ if (mState.isTouchExploring()
+ || mDraggingPointerId == INVALID_POINTER_ID
+ || event == null) {
+ return null;
+ }
+ final float x = mReceivedPointerTracker.getReceivedPointerDownX(mDraggingPointerId);
+ final float y = mReceivedPointerTracker.getReceivedPointerDownY(mDraggingPointerId);
+ final long time = mReceivedPointerTracker.getReceivedPointerDownTime(mDraggingPointerId);
+ MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[1];
+ coords[0] = new MotionEvent.PointerCoords();
+ coords[0].x = x;
+ coords[0].y = y;
+ MotionEvent.PointerProperties[] properties = new MotionEvent.PointerProperties[1];
+ properties[0] = new MotionEvent.PointerProperties();
+ properties[0].id = mDraggingPointerId;
+ properties[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
+ MotionEvent downEvent =
+ MotionEvent.obtain(
+ time,
+ time,
+ ACTION_DOWN,
+ 1,
+ properties,
+ coords,
+ event.getMetaState(),
+ event.getButtonState(),
+ event.getXPrecision(),
+ event.getYPrecision(),
+ event.getDeviceId(),
+ event.getEdgeFlags(),
+ event.getSource(),
+ event.getFlags());
+ event.setDownTime(time);
+ return downEvent;
+ }
+
public TouchState getState() {
return mState;
}
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 763654d..dda81ff 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
@@ -187,7 +187,7 @@
moveEachPointers(mLastEvent, p(10, 10), p(10, 10));
send(mLastEvent);
goToStateClearFrom(STATE_DRAGGING_2FINGERS);
- assertCapturedEvents(ACTION_DOWN, ACTION_MOVE, ACTION_MOVE, ACTION_UP);
+ assertCapturedEvents(ACTION_DOWN, ACTION_MOVE, ACTION_MOVE, ACTION_MOVE, ACTION_UP);
}
@Test
@@ -288,7 +288,7 @@
assertState(STATE_DRAGGING);
goToStateClearFrom(STATE_DRAGGING_2FINGERS);
assertState(STATE_CLEAR);
- assertCapturedEvents(ACTION_DOWN, ACTION_UP);
+ assertCapturedEvents(ACTION_DOWN, ACTION_MOVE, ACTION_UP);
assertCapturedEventsNoHistory();
}
@@ -301,6 +301,7 @@
assertState(STATE_CLEAR);
assertCapturedEvents(
/* goto dragging state */ ACTION_DOWN,
+ ACTION_MOVE,
/* leave dragging state */ ACTION_UP,
ACTION_DOWN,
ACTION_POINTER_DOWN,