Loading services/accessibility/java/com/android/server/accessibility/TouchExplorer.java +162 −138 Original line number Original line Diff line number Diff line Loading @@ -409,10 +409,29 @@ class TouchExplorer extends BaseEventStreamTransformation * @param rawEvent The raw (unmodified) motion event. * @param rawEvent The raw (unmodified) motion event. * @param policyFlags The policy flags associated with the event. * @param policyFlags The policy flags associated with the event. */ */ private void handleMotionEventStateTouchExploring(MotionEvent event, MotionEvent rawEvent, private void handleMotionEventStateTouchExploring( int policyFlags) { MotionEvent event, MotionEvent rawEvent, int policyFlags) { switch (event.getActionMasked()) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: { case MotionEvent.ACTION_DOWN: handleActionDownStateTouchExploring(event, policyFlags); break; case MotionEvent.ACTION_POINTER_DOWN: handleActionPointerDownStateTouchExploring(); break; case MotionEvent.ACTION_MOVE: handleActionMoveStateTouchExploring(event, rawEvent, policyFlags); break; case MotionEvent.ACTION_UP: handleActionUpStateTouchExploring(event, policyFlags); break; } } /** * Handles ACTION_DOWN while in the default touch exploring state. This event represents the * first finger touching the screen. */ private void handleActionDownStateTouchExploring(MotionEvent event, int policyFlags) { mAms.onTouchInteractionStart(); mAms.onTouchInteractionStart(); // If we still have not notified the user for the last // If we still have not notified the user for the last Loading @@ -426,7 +445,8 @@ class TouchExplorer extends BaseEventStreamTransformation sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); } } // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double tap. // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double // tap. if (!mGestureDetector.firstTapDetected()) { if (!mGestureDetector.firstTapDetected()) { mSendTouchExplorationEndDelayed.forceSendAndRemove(); mSendTouchExplorationEndDelayed.forceSendAndRemove(); mSendTouchInteractionEndDelayed.forceSendAndRemove(); mSendTouchInteractionEndDelayed.forceSendAndRemove(); Loading @@ -436,48 +456,54 @@ class TouchExplorer extends BaseEventStreamTransformation mSendTouchInteractionEndDelayed.cancel(); mSendTouchInteractionEndDelayed.cancel(); } } if (!mGestureDetector.firstTapDetected() if (!mGestureDetector.firstTapDetected() && !mState.isTouchExplorationInProgress()) { && !mState.isTouchExplorationInProgress()) { if (!mSendHoverEnterAndMoveDelayed.isPending()) { if (!mSendHoverEnterAndMoveDelayed.isPending()) { // Deliver hover enter with a delay to have a chance // Deliver hover enter with a delay to have a chance // to detect what the user is trying to do. // to detect what the user is trying to do. final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); final int pointerIdBits = (1 << pointerId); final int pointerIdBits = (1 << pointerId); mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits, mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits, policyFlags); policyFlags); } else { } else { // Cache the event until we discern exploration from gesturing. // Cache the event until we discern exploration from gesturing. mSendHoverEnterAndMoveDelayed.addEvent(event); mSendHoverEnterAndMoveDelayed.addEvent(event); } } } } } break; } case MotionEvent.ACTION_POINTER_DOWN: { /** * Handles ACTION_POINTER_DOWN when in the touch exploring state. This event represents an * additional finger touching the screen. */ private void handleActionPointerDownStateTouchExploring() { // Another finger down means that if we have not started to deliver // 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 // hover events, we will not have to. The code for ACTION_MOVE will // decide what we will actually do next. // decide what we will actually do next. mSendHoverEnterAndMoveDelayed.cancel(); mSendHoverEnterAndMoveDelayed.cancel(); mSendHoverExitDelayed.cancel(); mSendHoverExitDelayed.cancel(); } break; } case MotionEvent.ACTION_MOVE: { /** * Handles ACTION_MOVE while in the initial touch exploring state. This is where transitions to * delegating and dragging states are handled. */ private void handleActionMoveStateTouchExploring( MotionEvent event, MotionEvent rawEvent, int policyFlags) { final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); final int pointerIndex = event.findPointerIndex(pointerId); final int pointerIndex = event.findPointerIndex(pointerId); final int pointerIdBits = (1 << pointerId); final int pointerIdBits = (1 << pointerId); switch (event.getPointerCount()) { switch (event.getPointerCount()) { case 1: { case 1: // We have not started sending events since we try to // We have not started sending events since we try to // figure out what the user is doing. // figure out what the user is doing. if (mSendHoverEnterAndMoveDelayed.isPending()) { if (mSendHoverEnterAndMoveDelayed.isPending()) { // Cache the event until we discern exploration from gesturing. // Cache the event until we discern exploration from gesturing. mSendHoverEnterAndMoveDelayed.addEvent(event); mSendHoverEnterAndMoveDelayed.addEvent(event); } else { } else if (mState.isTouchExplorationInProgress()) { if (mState.isTouchExplorationInProgress()) { sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags); sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags); sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, sendMotionEvent( policyFlags); event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); } } } break; } break; case 2: case 2: { // More than one pointer so the user is not touch exploring // More than one pointer so the user is not touch exploring // and now we have to decide whether to delegate or drag. // and now we have to decide whether to delegate or drag. if (mSendHoverEnterAndMoveDelayed.isPending()) { if (mSendHoverEnterAndMoveDelayed.isPending()) { Loading @@ -485,8 +511,7 @@ class TouchExplorer extends BaseEventStreamTransformation // scheduled sending events. // scheduled sending events. mSendHoverEnterAndMoveDelayed.cancel(); mSendHoverEnterAndMoveDelayed.cancel(); mSendHoverExitDelayed.cancel(); mSendHoverExitDelayed.cancel(); } else { } else if (mState.isTouchExplorationInProgress()) { if (mState.isTouchExplorationInProgress()) { // If the user is touch exploring the second pointer may be // If the user is touch exploring the second pointer may be // performing a double tap to activate an item without need // performing a double tap to activate an item without need // for the user to lift his exploring finger. // for the user to lift his exploring finger. Loading @@ -496,8 +521,8 @@ class TouchExplorer extends BaseEventStreamTransformation mReceivedPointerTracker.getReceivedPointerDownX(pointerId) mReceivedPointerTracker.getReceivedPointerDownX(pointerId) - rawEvent.getX(pointerIndex); - rawEvent.getX(pointerIndex); final float deltaY = final float deltaY = mReceivedPointerTracker.getReceivedPointerDownY( mReceivedPointerTracker.getReceivedPointerDownY(pointerId) pointerId) - rawEvent.getY(pointerIndex); - rawEvent.getY(pointerIndex); final double moveDelta = Math.hypot(deltaX, deltaY); final double moveDelta = Math.hypot(deltaX, deltaY); if (moveDelta < mDoubleTapSlop) { if (moveDelta < mDoubleTapSlop) { break; break; Loading @@ -506,7 +531,6 @@ class TouchExplorer extends BaseEventStreamTransformation // end since we transition to another state. // end since we transition to another state. sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); } } } // Remove move history before send injected non-move events // Remove move history before send injected non-move events event = MotionEvent.obtainNoHistory(event); event = MotionEvent.obtainNoHistory(event); Loading @@ -515,17 +539,15 @@ class TouchExplorer extends BaseEventStreamTransformation // a given distance perform a drag. // a given distance perform a drag. mState.startDragging(); mState.startDragging(); mDraggingPointerId = pointerId; mDraggingPointerId = pointerId; event.setEdgeFlags( event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags()); mReceivedPointerTracker.getLastReceivedDownEdgeFlags()); sendMotionEvent(event, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags); sendMotionEvent(event, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags); } else { } else { // Two pointers moving arbitrary are delegated to the view hierarchy. // Two pointers moving arbitrary are delegated to the view hierarchy. mState.startDelegating(); mState.startDelegating(); sendDownForAllNotInjectedPointers(event, policyFlags); sendDownForAllNotInjectedPointers(event, policyFlags); } } } break; break; default: { default: // More than one pointer so the user is not touch exploring // More than one pointer so the user is not touch exploring // and now we have to decide whether to delegate or drag. // and now we have to decide whether to delegate or drag. if (mSendHoverEnterAndMoveDelayed.isPending()) { if (mSendHoverEnterAndMoveDelayed.isPending()) { Loading @@ -543,10 +565,15 @@ class TouchExplorer extends BaseEventStreamTransformation mState.startDelegating(); mState.startDelegating(); event = MotionEvent.obtainNoHistory(event); event = MotionEvent.obtainNoHistory(event); sendDownForAllNotInjectedPointers(event, policyFlags); sendDownForAllNotInjectedPointers(event, policyFlags); break; } } } } } break; case MotionEvent.ACTION_UP: { /** * Handles ACTION_UP while in the initial touch exploring state. This event represents all * fingers being lifted from the screen. */ private void handleActionUpStateTouchExploring(MotionEvent event, int policyFlags) { mAms.onTouchInteractionEnd(); mAms.onTouchInteractionEnd(); final int pointerId = event.getPointerId(event.getActionIndex()); final int pointerId = event.getPointerId(event.getActionIndex()); final int pointerIdBits = (1 << pointerId); final int pointerIdBits = (1 << pointerId); Loading @@ -562,9 +589,6 @@ class TouchExplorer extends BaseEventStreamTransformation if (!mSendTouchInteractionEndDelayed.isPending()) { if (!mSendTouchInteractionEndDelayed.isPending()) { mSendTouchInteractionEndDelayed.post(); mSendTouchInteractionEndDelayed.post(); } } } break; } } } /** /** Loading Loading
services/accessibility/java/com/android/server/accessibility/TouchExplorer.java +162 −138 Original line number Original line Diff line number Diff line Loading @@ -409,10 +409,29 @@ class TouchExplorer extends BaseEventStreamTransformation * @param rawEvent The raw (unmodified) motion event. * @param rawEvent The raw (unmodified) motion event. * @param policyFlags The policy flags associated with the event. * @param policyFlags The policy flags associated with the event. */ */ private void handleMotionEventStateTouchExploring(MotionEvent event, MotionEvent rawEvent, private void handleMotionEventStateTouchExploring( int policyFlags) { MotionEvent event, MotionEvent rawEvent, int policyFlags) { switch (event.getActionMasked()) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: { case MotionEvent.ACTION_DOWN: handleActionDownStateTouchExploring(event, policyFlags); break; case MotionEvent.ACTION_POINTER_DOWN: handleActionPointerDownStateTouchExploring(); break; case MotionEvent.ACTION_MOVE: handleActionMoveStateTouchExploring(event, rawEvent, policyFlags); break; case MotionEvent.ACTION_UP: handleActionUpStateTouchExploring(event, policyFlags); break; } } /** * Handles ACTION_DOWN while in the default touch exploring state. This event represents the * first finger touching the screen. */ private void handleActionDownStateTouchExploring(MotionEvent event, int policyFlags) { mAms.onTouchInteractionStart(); mAms.onTouchInteractionStart(); // If we still have not notified the user for the last // If we still have not notified the user for the last Loading @@ -426,7 +445,8 @@ class TouchExplorer extends BaseEventStreamTransformation sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); } } // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double tap. // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double // tap. if (!mGestureDetector.firstTapDetected()) { if (!mGestureDetector.firstTapDetected()) { mSendTouchExplorationEndDelayed.forceSendAndRemove(); mSendTouchExplorationEndDelayed.forceSendAndRemove(); mSendTouchInteractionEndDelayed.forceSendAndRemove(); mSendTouchInteractionEndDelayed.forceSendAndRemove(); Loading @@ -436,48 +456,54 @@ class TouchExplorer extends BaseEventStreamTransformation mSendTouchInteractionEndDelayed.cancel(); mSendTouchInteractionEndDelayed.cancel(); } } if (!mGestureDetector.firstTapDetected() if (!mGestureDetector.firstTapDetected() && !mState.isTouchExplorationInProgress()) { && !mState.isTouchExplorationInProgress()) { if (!mSendHoverEnterAndMoveDelayed.isPending()) { if (!mSendHoverEnterAndMoveDelayed.isPending()) { // Deliver hover enter with a delay to have a chance // Deliver hover enter with a delay to have a chance // to detect what the user is trying to do. // to detect what the user is trying to do. final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); final int pointerIdBits = (1 << pointerId); final int pointerIdBits = (1 << pointerId); mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits, mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits, policyFlags); policyFlags); } else { } else { // Cache the event until we discern exploration from gesturing. // Cache the event until we discern exploration from gesturing. mSendHoverEnterAndMoveDelayed.addEvent(event); mSendHoverEnterAndMoveDelayed.addEvent(event); } } } } } break; } case MotionEvent.ACTION_POINTER_DOWN: { /** * Handles ACTION_POINTER_DOWN when in the touch exploring state. This event represents an * additional finger touching the screen. */ private void handleActionPointerDownStateTouchExploring() { // Another finger down means that if we have not started to deliver // 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 // hover events, we will not have to. The code for ACTION_MOVE will // decide what we will actually do next. // decide what we will actually do next. mSendHoverEnterAndMoveDelayed.cancel(); mSendHoverEnterAndMoveDelayed.cancel(); mSendHoverExitDelayed.cancel(); mSendHoverExitDelayed.cancel(); } break; } case MotionEvent.ACTION_MOVE: { /** * Handles ACTION_MOVE while in the initial touch exploring state. This is where transitions to * delegating and dragging states are handled. */ private void handleActionMoveStateTouchExploring( MotionEvent event, MotionEvent rawEvent, int policyFlags) { final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); final int pointerIndex = event.findPointerIndex(pointerId); final int pointerIndex = event.findPointerIndex(pointerId); final int pointerIdBits = (1 << pointerId); final int pointerIdBits = (1 << pointerId); switch (event.getPointerCount()) { switch (event.getPointerCount()) { case 1: { case 1: // We have not started sending events since we try to // We have not started sending events since we try to // figure out what the user is doing. // figure out what the user is doing. if (mSendHoverEnterAndMoveDelayed.isPending()) { if (mSendHoverEnterAndMoveDelayed.isPending()) { // Cache the event until we discern exploration from gesturing. // Cache the event until we discern exploration from gesturing. mSendHoverEnterAndMoveDelayed.addEvent(event); mSendHoverEnterAndMoveDelayed.addEvent(event); } else { } else if (mState.isTouchExplorationInProgress()) { if (mState.isTouchExplorationInProgress()) { sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags); sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags); sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, sendMotionEvent( policyFlags); event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); } } } break; } break; case 2: case 2: { // More than one pointer so the user is not touch exploring // More than one pointer so the user is not touch exploring // and now we have to decide whether to delegate or drag. // and now we have to decide whether to delegate or drag. if (mSendHoverEnterAndMoveDelayed.isPending()) { if (mSendHoverEnterAndMoveDelayed.isPending()) { Loading @@ -485,8 +511,7 @@ class TouchExplorer extends BaseEventStreamTransformation // scheduled sending events. // scheduled sending events. mSendHoverEnterAndMoveDelayed.cancel(); mSendHoverEnterAndMoveDelayed.cancel(); mSendHoverExitDelayed.cancel(); mSendHoverExitDelayed.cancel(); } else { } else if (mState.isTouchExplorationInProgress()) { if (mState.isTouchExplorationInProgress()) { // If the user is touch exploring the second pointer may be // If the user is touch exploring the second pointer may be // performing a double tap to activate an item without need // performing a double tap to activate an item without need // for the user to lift his exploring finger. // for the user to lift his exploring finger. Loading @@ -496,8 +521,8 @@ class TouchExplorer extends BaseEventStreamTransformation mReceivedPointerTracker.getReceivedPointerDownX(pointerId) mReceivedPointerTracker.getReceivedPointerDownX(pointerId) - rawEvent.getX(pointerIndex); - rawEvent.getX(pointerIndex); final float deltaY = final float deltaY = mReceivedPointerTracker.getReceivedPointerDownY( mReceivedPointerTracker.getReceivedPointerDownY(pointerId) pointerId) - rawEvent.getY(pointerIndex); - rawEvent.getY(pointerIndex); final double moveDelta = Math.hypot(deltaX, deltaY); final double moveDelta = Math.hypot(deltaX, deltaY); if (moveDelta < mDoubleTapSlop) { if (moveDelta < mDoubleTapSlop) { break; break; Loading @@ -506,7 +531,6 @@ class TouchExplorer extends BaseEventStreamTransformation // end since we transition to another state. // end since we transition to another state. sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); } } } // Remove move history before send injected non-move events // Remove move history before send injected non-move events event = MotionEvent.obtainNoHistory(event); event = MotionEvent.obtainNoHistory(event); Loading @@ -515,17 +539,15 @@ class TouchExplorer extends BaseEventStreamTransformation // a given distance perform a drag. // a given distance perform a drag. mState.startDragging(); mState.startDragging(); mDraggingPointerId = pointerId; mDraggingPointerId = pointerId; event.setEdgeFlags( event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags()); mReceivedPointerTracker.getLastReceivedDownEdgeFlags()); sendMotionEvent(event, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags); sendMotionEvent(event, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags); } else { } else { // Two pointers moving arbitrary are delegated to the view hierarchy. // Two pointers moving arbitrary are delegated to the view hierarchy. mState.startDelegating(); mState.startDelegating(); sendDownForAllNotInjectedPointers(event, policyFlags); sendDownForAllNotInjectedPointers(event, policyFlags); } } } break; break; default: { default: // More than one pointer so the user is not touch exploring // More than one pointer so the user is not touch exploring // and now we have to decide whether to delegate or drag. // and now we have to decide whether to delegate or drag. if (mSendHoverEnterAndMoveDelayed.isPending()) { if (mSendHoverEnterAndMoveDelayed.isPending()) { Loading @@ -543,10 +565,15 @@ class TouchExplorer extends BaseEventStreamTransformation mState.startDelegating(); mState.startDelegating(); event = MotionEvent.obtainNoHistory(event); event = MotionEvent.obtainNoHistory(event); sendDownForAllNotInjectedPointers(event, policyFlags); sendDownForAllNotInjectedPointers(event, policyFlags); break; } } } } } break; case MotionEvent.ACTION_UP: { /** * Handles ACTION_UP while in the initial touch exploring state. This event represents all * fingers being lifted from the screen. */ private void handleActionUpStateTouchExploring(MotionEvent event, int policyFlags) { mAms.onTouchInteractionEnd(); mAms.onTouchInteractionEnd(); final int pointerId = event.getPointerId(event.getActionIndex()); final int pointerId = event.getPointerId(event.getActionIndex()); final int pointerIdBits = (1 << pointerId); final int pointerIdBits = (1 << pointerId); Loading @@ -562,9 +589,6 @@ class TouchExplorer extends BaseEventStreamTransformation if (!mSendTouchInteractionEndDelayed.isPending()) { if (!mSendTouchInteractionEndDelayed.isPending()) { mSendTouchInteractionEndDelayed.post(); mSendTouchInteractionEndDelayed.post(); } } } break; } } } /** /** Loading