summaryrefslogtreecommitdiffstats
path: root/services/java
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2012-10-04 12:31:01 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-10-04 12:31:02 -0700
commitd367b70c4ad5d8e6cdbcc0d6d429428413cd39b3 (patch)
tree30b14a48ea5c8c9039bb0ad245fd31f03be9d890 /services/java
parent6ebbe1b97005a40850a1633aa4fc12af0392e986 (diff)
parentf068fed6c4c3fc2003aec19b6e7e892358179b02 (diff)
downloadframeworks_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.java181
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);
}
}