Loading services/java/com/android/server/accessibility/TouchExplorer.java +86 −57 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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); } } } 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(); Loading Loading @@ -518,15 +524,12 @@ 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); } } } break; case 2: { // More than one pointer so the user is not touch exploring Loading @@ -539,15 +542,16 @@ class TouchExplorer implements EventStreamTransformation { mPerformLongPressDelayed.cancel(); } else { mPerformLongPressDelayed.cancel(); 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 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; Loading @@ -556,6 +560,7 @@ class TouchExplorer implements EventStreamTransformation { // end since we transition to another state. sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); } } // We know that a new state transition is to happen and the // new state will not be gesture recognition, so clear the Loading Loading @@ -736,21 +741,35 @@ class TouchExplorer implements EventStreamTransformation { + "there is at least one pointer down!"); } case MotionEvent.ACTION_UP: { mAms.onTouchInteractionEnd(); // Announce the end of a the touch interaction. sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); // 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); 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); } } } private void handleMotionEventGestureDetecting(MotionEvent event, int policyFlags) { switch (event.getActionMasked()) { Loading Loading @@ -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) { Loading @@ -1003,6 +1003,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. Loading Loading @@ -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; Loading @@ -1690,7 +1722,6 @@ class TouchExplorer implements EventStreamTransformation { mReceivedPointersDown = 0; mPrimaryPointerId = 0; mLastReceivedUpPointerDownTime = 0; mLastReceivedUpPointerId = 0; mLastReceivedUpPointerDownX = 0; mLastReceivedUpPointerDownY = 0; } Loading Loading @@ -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; Loading @@ -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]; Loading Loading
services/java/com/android/server/accessibility/TouchExplorer.java +86 −57 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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); } } } 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(); Loading Loading @@ -518,15 +524,12 @@ 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); } } } break; case 2: { // More than one pointer so the user is not touch exploring Loading @@ -539,15 +542,16 @@ class TouchExplorer implements EventStreamTransformation { mPerformLongPressDelayed.cancel(); } else { mPerformLongPressDelayed.cancel(); 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 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; Loading @@ -556,6 +560,7 @@ class TouchExplorer implements EventStreamTransformation { // end since we transition to another state. sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); } } // We know that a new state transition is to happen and the // new state will not be gesture recognition, so clear the Loading Loading @@ -736,21 +741,35 @@ class TouchExplorer implements EventStreamTransformation { + "there is at least one pointer down!"); } case MotionEvent.ACTION_UP: { mAms.onTouchInteractionEnd(); // Announce the end of a the touch interaction. sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); // 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); 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); } } } private void handleMotionEventGestureDetecting(MotionEvent event, int policyFlags) { switch (event.getActionMasked()) { Loading Loading @@ -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) { Loading @@ -1003,6 +1003,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. Loading Loading @@ -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; Loading @@ -1690,7 +1722,6 @@ class TouchExplorer implements EventStreamTransformation { mReceivedPointersDown = 0; mPrimaryPointerId = 0; mLastReceivedUpPointerDownTime = 0; mLastReceivedUpPointerId = 0; mLastReceivedUpPointerDownX = 0; mLastReceivedUpPointerDownY = 0; } Loading Loading @@ -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; Loading @@ -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]; Loading