diff options
author | Svetoslav Ganov <svetoslavganov@google.com> | 2012-10-04 12:31:01 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-10-04 12:31:02 -0700 |
commit | d367b70c4ad5d8e6cdbcc0d6d429428413cd39b3 (patch) | |
tree | 30b14a48ea5c8c9039bb0ad245fd31f03be9d890 /services/java | |
parent | 6ebbe1b97005a40850a1633aa4fc12af0392e986 (diff) | |
parent | f068fed6c4c3fc2003aec19b6e7e892358179b02 (diff) | |
download | frameworks_base-d367b70c4ad5d8e6cdbcc0d6d429428413cd39b3.zip frameworks_base-d367b70c4ad5d8e6cdbcc0d6d429428413cd39b3.tar.gz frameworks_base-d367b70c4ad5d8e6cdbcc0d6d429428413cd39b3.tar.bz2 |
Merge "Accessibility HOVER_ENTER / EXIT without enclosing EXPLORATION_GESTURE_START / END" into jb-mr1-dev
Diffstat (limited to 'services/java')
-rw-r--r-- | services/java/com/android/server/accessibility/TouchExplorer.java | 181 |
1 files changed, 103 insertions, 78 deletions
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java index 2d81b6c..b3bf6fe 100644 --- a/services/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/java/com/android/server/accessibility/TouchExplorer.java @@ -102,10 +102,6 @@ class TouchExplorer implements EventStreamTransformation { // The timeout after which we are no longer trying to detect a gesture. private static final int EXIT_GESTURE_DETECTION_TIMEOUT = 2000; - // The timeout to send interaction end events in case we did not - // receive the expected hover exit event due to a misbehaving app. - private static final int SEND_INTERACTION_END_EVENTS_TIMEOUT = 200; - // Temporary array for storing pointer IDs. private final int[] mTempPointerIds = new int[MAX_POINTER_COUNT]; @@ -139,8 +135,11 @@ class TouchExplorer implements EventStreamTransformation { // Command for delayed sending of a hover exit event. private final SendHoverDelayed mSendHoverExitDelayed; - // Command for delayed sending of interaction ending events. - private final SendInteractionEndEventsDelayed mSendInteractionEndEventsDelayed; + // Command for delayed sending of touch exploration end events. + private final SendAccessibilityEventDelayed mSendTouchExplorationEndDelayed; + + // Command for delayed sending of touch interaction end events. + private final SendAccessibilityEventDelayed mSendTouchInteractionEndDelayed; // Command for delayed sending of a long press. private final PerformLongPressDelayed mPerformLongPressDelayed; @@ -209,11 +208,8 @@ class TouchExplorer implements EventStreamTransformation { // The id of the last touch explored window. private int mLastTouchedWindowId; - // Whether touch exploration gesture has ended. - private boolean mTouchExplorationGestureEnded; - - // Whether touch interaction has ended. - private boolean mTouchInteractionEnded; + // Whether touch exploration is in progress. + private boolean mTouchExplorationInProgress; /** * Creates a new instance. @@ -240,7 +236,12 @@ class TouchExplorer implements EventStreamTransformation { mGestureLibrary.load(); mSendHoverEnterDelayed = new SendHoverDelayed(MotionEvent.ACTION_HOVER_ENTER, true); mSendHoverExitDelayed = new SendHoverDelayed(MotionEvent.ACTION_HOVER_EXIT, false); - mSendInteractionEndEventsDelayed = new SendInteractionEndEventsDelayed(); + mSendTouchExplorationEndDelayed = new SendAccessibilityEventDelayed( + AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END, + mDetermineUserIntentTimeout); + mSendTouchInteractionEndDelayed = new SendAccessibilityEventDelayed( + AccessibilityEvent.TYPE_TOUCH_INTERACTION_END, + mDetermineUserIntentTimeout); mDoubleTapDetector = new DoubleTapDetector(); final float density = context.getResources().getDisplayMetrics().density; mScaledMinPointerDistanceToUseMiddleLocation = @@ -265,7 +266,7 @@ class TouchExplorer implements EventStreamTransformation { switch (mCurrentState) { case STATE_TOUCH_EXPLORING: { // If a touch exploration gesture is in progress send events for its end. - sendExitEventsIfNeeded(policyFlags); + sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); } break; case STATE_DRAGGING: { mDraggingPointerId = INVALID_POINTER_ID; @@ -286,7 +287,8 @@ class TouchExplorer implements EventStreamTransformation { mSendHoverExitDelayed.remove(); mPerformLongPressDelayed.remove(); mExitGestureDetectionModeDelayed.remove(); - mSendInteractionEndEventsDelayed.remove(); + mSendTouchExplorationEndDelayed.remove(); + mSendTouchInteractionEndDelayed.remove(); // Reset the pointer trackers. mReceivedPointerTracker.clear(); mInjectedPointerTracker.clear(); @@ -301,6 +303,7 @@ class TouchExplorer implements EventStreamTransformation { if (mNext != null) { mNext.clear(); } + mTouchExplorationInProgress = false; } @Override @@ -341,19 +344,17 @@ class TouchExplorer implements EventStreamTransformation { // The event for gesture end should be strictly after the // last hover exit event. - if (mTouchExplorationGestureEnded + if (mSendTouchExplorationEndDelayed.isPending() && eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) { - mSendInteractionEndEventsDelayed.remove(); - mTouchExplorationGestureEnded = false; + mSendTouchExplorationEndDelayed.remove(); sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END); } // The event for touch interaction end should be strictly after the // last hover exit and the touch exploration gesture end events. - if (mTouchInteractionEnded + if (mSendTouchInteractionEndDelayed.isPending() && eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) { - mSendInteractionEndEventsDelayed.remove(); - mTouchInteractionEnded = false; + mSendTouchInteractionEndDelayed.remove(); sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); } @@ -396,15 +397,6 @@ class TouchExplorer implements EventStreamTransformation { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: - // The delayed enter not delivered implies that we have delivered - // TYPE_TOUCH_INTERACTION_START and not TYPE_TOUCH_INTERACTION_END, - // therefore we need to deliver the interaction end event here. - if (mSendHoverEnterDelayed.isPending()) { - sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); - } - // Announce the start of a new touch interaction. - sendAccessibilityEvent( - AccessibilityEvent.TYPE_TOUCH_INTERACTION_START); // Pre-feed the motion events to the gesture detector since we // have a distance slop before getting into gesture detection // mode and not using the points within this slop significantly @@ -426,8 +418,20 @@ class TouchExplorer implements EventStreamTransformation { mSendHoverExitDelayed.remove(); } - if (mSendInteractionEndEventsDelayed.isPending()) { - mSendInteractionEndEventsDelayed.forceSendAndRemove(); + if (mSendTouchExplorationEndDelayed.isPending()) { + mSendTouchExplorationEndDelayed.forceSendAndRemove(); + } + + if (mSendTouchInteractionEndDelayed.isPending()) { + mSendTouchInteractionEndDelayed.forceSendAndRemove(); + } + + // Every pointer that goes down is active until it moves or + // another one goes down. Hence, having more than one pointer + // down we have already send the interaction start event. + if (event.getPointerCount() == 1) { + sendAccessibilityEvent( + AccessibilityEvent.TYPE_TOUCH_INTERACTION_START); } mPerformLongPressDelayed.remove(); @@ -443,11 +447,13 @@ class TouchExplorer implements EventStreamTransformation { mPerformLongPressDelayed.post(event, policyFlags); break; } - // Deliver hover enter with a delay to have a chance - // to detect what the user is trying to do. - final int pointerId = receivedTracker.getPrimaryActivePointerId(); - final int pointerIdBits = (1 << pointerId); - mSendHoverEnterDelayed.post(event, true, pointerIdBits, policyFlags); + if (!mTouchExplorationInProgress) { + // Deliver hover enter with a delay to have a chance + // to detect what the user is trying to do. + final int pointerId = receivedTracker.getPrimaryActivePointerId(); + final int pointerIdBits = (1 << pointerId); + mSendHoverEnterDelayed.post(event, true, pointerIdBits, policyFlags); + } } break; default: { /* do nothing - let the code for ACTION_MOVE decide what to do */ @@ -512,12 +518,27 @@ class TouchExplorer implements EventStreamTransformation { break; } } else { + // Cancel the long press if pending and the user + // moved more than the slop. + if (mPerformLongPressDelayed.isPending()) { + 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); + // The user has moved enough for us to decide. + if (moveDelta > mTouchSlop) { + mPerformLongPressDelayed.remove(); + } + } // The user is wither double tapping or performing long // press so do not send move events yet. if (mDoubleTapDetector.firstTapDetected()) { break; } - sendEnterEventsIfNeeded(policyFlags); + sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags); sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); } @@ -548,7 +569,7 @@ class TouchExplorer implements EventStreamTransformation { } // We are sending events so send exit and gesture // end since we transition to another state. - sendExitEventsIfNeeded(policyFlags); + sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); } // We know that a new state transition is to happen and the @@ -583,7 +604,7 @@ class TouchExplorer implements EventStreamTransformation { mPerformLongPressDelayed.remove(); // We are sending events so send exit and gesture // end since we transition to another state. - sendExitEventsIfNeeded(policyFlags); + sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); } // More than two pointers are delegated to the view hierarchy. @@ -612,11 +633,14 @@ class TouchExplorer implements EventStreamTransformation { // If we have not delivered the enter schedule exit. if (mSendHoverEnterDelayed.isPending()) { - mSendHoverEnterDelayed.mTouchExplorationInProgress = false; mSendHoverExitDelayed.post(event, false, pointerIdBits, policyFlags); } else { // The user is touch exploring so we send events for end. - sendExitEventsIfNeeded(policyFlags); + sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); + } + + if (!mSendTouchInteractionEndDelayed.isPending()) { + mSendTouchInteractionEndDelayed.post(); } } break; } @@ -846,6 +870,14 @@ class TouchExplorer implements EventStreamTransformation { if (accessibilityManager.isEnabled()) { AccessibilityEvent event = AccessibilityEvent.obtain(type); accessibilityManager.sendAccessibilityEvent(event); + switch (type) { + case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START: { + mTouchExplorationInProgress = true; + } break; + case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END: { + mTouchExplorationInProgress = false; + } break; + } } } @@ -893,14 +925,12 @@ class TouchExplorer implements EventStreamTransformation { * * @param policyFlags The policy flags associated with the event. */ - private void sendExitEventsIfNeeded(int policyFlags) { + private void sendHoverExitAndTouchExplorationGestureEndIfNeeded(int policyFlags) { MotionEvent event = mInjectedPointerTracker.getLastInjectedHoverEvent(); if (event != null && event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) { final int pointerIdBits = event.getPointerIdBits(); - mTouchExplorationGestureEnded = true; - mTouchInteractionEnded = true; - if (!mSendInteractionEndEventsDelayed.isPending()) { - mSendInteractionEndEventsDelayed.post(); + if (!mSendTouchExplorationEndDelayed.isPending()) { + mSendTouchExplorationEndDelayed.post(); } sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags); } @@ -912,10 +942,11 @@ class TouchExplorer implements EventStreamTransformation { * * @param policyFlags The policy flags associated with the event. */ - private void sendEnterEventsIfNeeded(int policyFlags) { + private void sendTouchExplorationGestureStartAndHoverEnterIfNeeded(int policyFlags) { MotionEvent event = mInjectedPointerTracker.getLastInjectedHoverEvent(); if (event != null && event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { final int pointerIdBits = event.getPointerIdBits(); + sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START); sendMotionEvent(event, MotionEvent.ACTION_HOVER_ENTER, pointerIdBits, policyFlags); } } @@ -1181,8 +1212,12 @@ class TouchExplorer implements EventStreamTransformation { mSendHoverExitDelayed.remove(); mPerformLongPressDelayed.remove(); - // The touch interaction has ended since we will send a click. - sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); + if (mSendTouchExplorationEndDelayed.isPending()) { + mSendTouchExplorationEndDelayed.forceSendAndRemove(); + } + if (mSendTouchInteractionEndDelayed.isPending()) { + mSendTouchInteractionEndDelayed.forceSendAndRemove(); + } int clickLocationX; int clickLocationY; @@ -1416,7 +1451,7 @@ class TouchExplorer implements EventStreamTransformation { mLongPressingPointerDeltaX = (int) mEvent.getX(pointerIndex) - clickLocationX; mLongPressingPointerDeltaY = (int) mEvent.getY(pointerIndex) - clickLocationY; - sendExitEventsIfNeeded(mPolicyFlags); + sendHoverExitAndTouchExplorationGestureEndIfNeeded(mPolicyFlags); mCurrentState = STATE_DELEGATING; sendDownForAllActiveNotInjectedPointers(mEvent, mPolicyFlags); @@ -1445,7 +1480,6 @@ class TouchExplorer implements EventStreamTransformation { private MotionEvent mPrototype; private int mPointerIdBits; private int mPolicyFlags; - private boolean mTouchExplorationInProgress; public SendHoverDelayed(int hoverAction, boolean gestureStarted) { mHoverAction = hoverAction; @@ -1456,7 +1490,6 @@ class TouchExplorer implements EventStreamTransformation { int pointerIdBits, int policyFlags) { remove(); mPrototype = MotionEvent.obtain(prototype); - mTouchExplorationInProgress = touchExplorationInProgress; mPointerIdBits = pointerIdBits; mPolicyFlags = policyFlags; mHandler.postDelayed(this, mDetermineUserIntentTimeout); @@ -1493,7 +1526,6 @@ class TouchExplorer implements EventStreamTransformation { mPrototype = null; mPointerIdBits = -1; mPolicyFlags = 0; - mTouchExplorationInProgress = false; } public void forceSendAndRemove() { @@ -1510,22 +1542,15 @@ class TouchExplorer implements EventStreamTransformation { Slog.d(LOG_TAG_SEND_HOVER_DELAYED, mGestureStarted ? "touchExplorationGestureStarted" : "touchExplorationGestureEnded"); } - if (mTouchExplorationInProgress) { - if (mGestureStarted) { - sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START); - } else { - mTouchExplorationGestureEnded = true; - mTouchInteractionEnded = true; - if (!mSendInteractionEndEventsDelayed.isPending()) { - mSendInteractionEndEventsDelayed.post(); - } - } + if (mGestureStarted) { + sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START); } else { - if (!mGestureStarted) { - mTouchInteractionEnded = true; - if (!mSendInteractionEndEventsDelayed.isPending()) { - mSendInteractionEndEventsDelayed.post(); - } + if (!mSendTouchExplorationEndDelayed.isPending()) { + mSendTouchExplorationEndDelayed.post(); + } + if (mSendTouchInteractionEndDelayed.isPending()) { + mSendTouchInteractionEndDelayed.remove(); + mSendTouchInteractionEndDelayed.post(); } } sendMotionEvent(mPrototype, mHoverAction, mPointerIdBits, mPolicyFlags); @@ -1533,14 +1558,21 @@ class TouchExplorer implements EventStreamTransformation { } } - private class SendInteractionEndEventsDelayed implements Runnable { + private class SendAccessibilityEventDelayed implements Runnable { + private final int mEventType; + private final int mDelay; + + public SendAccessibilityEventDelayed(int eventType, int delay) { + mEventType = eventType; + mDelay = delay; + } public void remove() { mHandler.removeCallbacks(this); } public void post() { - mHandler.postDelayed(this, SEND_INTERACTION_END_EVENTS_TIMEOUT); + mHandler.postDelayed(this, mDelay); } public boolean isPending() { @@ -1556,14 +1588,7 @@ class TouchExplorer implements EventStreamTransformation { @Override public void run() { - if (mTouchExplorationGestureEnded) { - mTouchExplorationGestureEnded = false; - sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END); - } - if (mTouchInteractionEnded) { - mTouchInteractionEnded = false; - sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); - } + sendAccessibilityEvent(mEventType); } } |