summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/java/com/android/server/accessibility/TouchExplorer.java143
1 files changed, 86 insertions, 57 deletions
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index a99b58a..43f12eb 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -76,7 +76,7 @@ class TouchExplorer implements EventStreamTransformation {
private static final int STATE_DELEGATING = 0x00000004;
private static final int STATE_GESTURE_DETECTING = 0x00000005;
- // The minimum of the cosine between the vectors of two moving
+ // The maximum of the cosine between the vectors of two moving
// pointers so they can be considered moving in the same direction.
private static final float MAX_DRAGGING_ANGLE_COS = 0.525321989f; // cos(pi/4)
@@ -436,13 +436,19 @@ class TouchExplorer implements EventStreamTransformation {
final int pointerIdBits = (1 << pointerId);
mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits,
policyFlags);
+ } else {
+ // Cache the event until we discern exploration from gesturing.
+ mSendHoverEnterAndMoveDelayed.addEvent(event);
}
- // Cache the event until we discern exploration from gesturing.
- mSendHoverEnterAndMoveDelayed.addEvent(event);
}
} break;
case MotionEvent.ACTION_POINTER_DOWN: {
- /* do nothing - let the code for ACTION_MOVE decide what to do */
+ // Another finger down means that if we have not started to deliver
+ // hover events, we will not have to. The code for ACTION_MOVE will
+ // decide what we will actually do next.
+ mSendHoverEnterAndMoveDelayed.cancel();
+ mSendHoverExitDelayed.cancel();
+ mPerformLongPressDelayed.cancel();
} break;
case MotionEvent.ACTION_MOVE: {
final int pointerId = receivedTracker.getPrimaryPointerId();
@@ -518,14 +524,11 @@ class TouchExplorer implements EventStreamTransformation {
mPerformLongPressDelayed.cancel();
}
}
- // The user is either double tapping or performing a long
- // press, so do not send move events yet.
- if (mDoubleTapDetector.firstTapDetected()) {
- break;
+ if (mTouchExplorationInProgress) {
+ sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags);
+ sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits,
+ policyFlags);
}
- sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags);
- sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits,
- policyFlags);
}
} break;
case 2: {
@@ -539,22 +542,24 @@ class TouchExplorer implements EventStreamTransformation {
mPerformLongPressDelayed.cancel();
} else {
mPerformLongPressDelayed.cancel();
- // If the user is touch exploring the second pointer may be
- // performing a double tap to activate an item without need
- // for the user to lift his exploring finger.
- // It is *important* to use the distance traveled by the pointers
- // on the screen which may or may not be magnified.
- final float deltaX = receivedTracker.getReceivedPointerDownX(pointerId)
- - rawEvent.getX(pointerIndex);
- final float deltaY = receivedTracker.getReceivedPointerDownY(pointerId)
- - rawEvent.getY(pointerIndex);
- final double moveDelta = Math.hypot(deltaX, deltaY);
- if (moveDelta < mDoubleTapSlop) {
- break;
+ if (mTouchExplorationInProgress) {
+ // If the user is touch exploring the second pointer may be
+ // performing a double tap to activate an item without need
+ // for the user to lift his exploring finger.
+ // It is *important* to use the distance traveled by the pointers
+ // on the screen which may or may not be magnified.
+ final float deltaX = receivedTracker.getReceivedPointerDownX(
+ pointerId) - rawEvent.getX(pointerIndex);
+ final float deltaY = receivedTracker.getReceivedPointerDownY(
+ pointerId) - rawEvent.getY(pointerIndex);
+ final double moveDelta = Math.hypot(deltaX, deltaY);
+ if (moveDelta < mDoubleTapSlop) {
+ break;
+ }
+ // We are sending events so send exit and gesture
+ // end since we transition to another state.
+ sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
}
- // We are sending events so send exit and gesture
- // end since we transition to another state.
- sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
}
// We know that a new state transition is to happen and the
@@ -736,20 +741,34 @@ class TouchExplorer implements EventStreamTransformation {
+ "there is at least one pointer down!");
}
case MotionEvent.ACTION_UP: {
- mAms.onTouchInteractionEnd();
+ // Offset the event if we are doing a long press as the
+ // target is not necessarily under the user's finger.
+ if (mLongPressingPointerId >= 0) {
+ event = offsetEvent(event, - mLongPressingPointerDeltaX,
+ - mLongPressingPointerDeltaY);
+ // Clear the long press state.
+ mLongPressingPointerId = -1;
+ mLongPressingPointerDeltaX = 0;
+ mLongPressingPointerDeltaY = 0;
+ }
+
+ // Deliver the event.
+ sendMotionEvent(event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags);
+
// Announce the end of a the touch interaction.
+ mAms.onTouchInteractionEnd();
sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
- mLongPressingPointerId = -1;
- mLongPressingPointerDeltaX = 0;
- mLongPressingPointerDeltaY = 0;
+
mCurrentState = STATE_TOUCH_EXPLORING;
} break;
case MotionEvent.ACTION_CANCEL: {
clear(event, policyFlags);
} break;
+ default: {
+ // Deliver the event.
+ sendMotionEvent(event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags);
+ }
}
- // Deliver the event.
- sendMotionEvent(event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags);
}
private void handleMotionEventGestureDetecting(MotionEvent event, int policyFlags) {
@@ -959,27 +978,8 @@ class TouchExplorer implements EventStreamTransformation {
// long press it, or even worse to avoid the user long pressing
// on the wrong item since click and long press behave differently.
if (mLongPressingPointerId >= 0) {
- final int remappedIndex = event.findPointerIndex(mLongPressingPointerId);
- final int pointerCount = event.getPointerCount();
- PointerProperties[] props = PointerProperties.createArray(pointerCount);
- PointerCoords[] coords = PointerCoords.createArray(pointerCount);
- for (int i = 0; i < pointerCount; i++) {
- event.getPointerProperties(i, props[i]);
- event.getPointerCoords(i, coords[i]);
- if (i == remappedIndex) {
- coords[i].x -= mLongPressingPointerDeltaX;
- coords[i].y -= mLongPressingPointerDeltaY;
- }
- }
- MotionEvent remapped = MotionEvent.obtain(event.getDownTime(),
- event.getEventTime(), event.getAction(), event.getPointerCount(),
- props, coords, event.getMetaState(), event.getButtonState(),
- 1.0f, 1.0f, event.getDeviceId(), event.getEdgeFlags(),
- event.getSource(), event.getFlags());
- if (event != prototype) {
- event.recycle();
- }
- event = remapped;
+ event = offsetEvent(event, - mLongPressingPointerDeltaX,
+ - mLongPressingPointerDeltaY);
}
if (DEBUG) {
@@ -1004,6 +1004,39 @@ class TouchExplorer implements EventStreamTransformation {
}
/**
+ * Offsets all pointers in the given event by adding the specified X and Y
+ * offsets.
+ *
+ * @param event The event to offset.
+ * @param offsetX The X offset.
+ * @param offsetY The Y offset.
+ * @return An event with the offset pointers or the original event if both
+ * offsets are zero.
+ */
+ private MotionEvent offsetEvent(MotionEvent event, int offsetX, int offsetY) {
+ if (offsetX == 0 && offsetY == 0) {
+ return event;
+ }
+ final int remappedIndex = event.findPointerIndex(mLongPressingPointerId);
+ final int pointerCount = event.getPointerCount();
+ PointerProperties[] props = PointerProperties.createArray(pointerCount);
+ PointerCoords[] coords = PointerCoords.createArray(pointerCount);
+ for (int i = 0; i < pointerCount; i++) {
+ event.getPointerProperties(i, props[i]);
+ event.getPointerCoords(i, coords[i]);
+ if (i == remappedIndex) {
+ coords[i].x += offsetX;
+ coords[i].y += offsetY;
+ }
+ }
+ return MotionEvent.obtain(event.getDownTime(),
+ event.getEventTime(), event.getAction(), event.getPointerCount(),
+ props, coords, event.getMetaState(), event.getButtonState(),
+ 1.0f, 1.0f, event.getDeviceId(), event.getEdgeFlags(),
+ event.getSource(), event.getFlags());
+ }
+
+ /**
* Computes the action for an injected event based on a masked action
* and a pointer index.
*
@@ -1674,7 +1707,6 @@ class TouchExplorer implements EventStreamTransformation {
// Keep track of the last up pointer data.
private long mLastReceivedUpPointerDownTime;
- private int mLastReceivedUpPointerId;
private float mLastReceivedUpPointerDownX;
private float mLastReceivedUpPointerDownY;
@@ -1690,7 +1722,6 @@ class TouchExplorer implements EventStreamTransformation {
mReceivedPointersDown = 0;
mPrimaryPointerId = 0;
mLastReceivedUpPointerDownTime = 0;
- mLastReceivedUpPointerId = 0;
mLastReceivedUpPointerDownX = 0;
mLastReceivedUpPointerDownY = 0;
}
@@ -1823,7 +1854,6 @@ class TouchExplorer implements EventStreamTransformation {
final int pointerId = event.getPointerId(pointerIndex);
final int pointerFlag = (1 << pointerId);
- mLastReceivedUpPointerId = 0;
mLastReceivedUpPointerDownTime = 0;
mLastReceivedUpPointerDownX = 0;
mLastReceivedUpPointerDownX = 0;
@@ -1848,7 +1878,6 @@ class TouchExplorer implements EventStreamTransformation {
final int pointerId = event.getPointerId(pointerIndex);
final int pointerFlag = (1 << pointerId);
- mLastReceivedUpPointerId = pointerId;
mLastReceivedUpPointerDownTime = getReceivedPointerDownTime(pointerId);
mLastReceivedUpPointerDownX = mReceivedPointerDownX[pointerId];
mLastReceivedUpPointerDownY = mReceivedPointerDownY[pointerId];