diff options
author | Svetoslav Ganov <svetoslavganov@google.com> | 2013-09-03 09:24:48 -0700 |
---|---|---|
committer | Svetoslav Ganov <svetoslavganov@google.com> | 2013-09-03 09:24:52 -0700 |
commit | 38c992841b5f6bc80359dbf60d31aa7b994160fc (patch) | |
tree | c75a25f2e676140d0485d0249f70b0682e816292 /services/java/com/android/server/accessibility | |
parent | 61dda198598e95971ca224e3bcb7393f30e45657 (diff) | |
download | frameworks_base-38c992841b5f6bc80359dbf60d31aa7b994160fc.zip frameworks_base-38c992841b5f6bc80359dbf60d31aa7b994160fc.tar.gz frameworks_base-38c992841b5f6bc80359dbf60d31aa7b994160fc.tar.bz2 |
Crashes in TouchExplorer on two finger swipe.
1. The logic for finding the active pointer was incorrect. The code was
iterating over all pointer ids and taking the minimum, i.e. the pointer
that first went down. The problem was that the down time for pointers
that are not down was also considered (set to zero), thus sometimes we
would consider the first pointer that went down to be a pointer that
is not down at all. Now we are iterating only over the pointers that
are down.
2. The batched events while waiting to see if the user is exploring or
gesturing were added even if we were in touch exploration state at which
point we do not have to batch. As a result we ended up having lefovers
from a previous gesture when handling the delayed events and crash.
bug:10312546
Change-Id: I4728541ac12e4da4577d22e4314101dd169a52fb
Diffstat (limited to 'services/java/com/android/server/accessibility')
-rw-r--r-- | services/java/com/android/server/accessibility/TouchExplorer.java | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java index 8fb3998..1b8876d 100644 --- a/services/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/java/com/android/server/accessibility/TouchExplorer.java @@ -417,9 +417,6 @@ class TouchExplorer implements EventStreamTransformation { mSendTouchInteractionEndDelayed.forceSendAndRemove(); } - // Cache the event until we discern exploration from gesturing. - mSendHoverEnterAndMoveDelayed.addEvent(event); - // If we have the first tap, schedule a long press and break // since we do not want to schedule hover enter because // the delayed callback will kick in before the long click. @@ -432,11 +429,16 @@ class TouchExplorer implements EventStreamTransformation { break; } 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.getPrimaryPointerId(); - final int pointerIdBits = (1 << pointerId); - mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits, policyFlags); + if (!mSendHoverEnterAndMoveDelayed.isPending()) { + // Deliver hover enter with a delay to have a chance + // to detect what the user is trying to do. + final int pointerId = receivedTracker.getPrimaryPointerId(); + final int pointerIdBits = (1 << pointerId); + mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits, + policyFlags); + } + // Cache the event until we discern exploration from gesturing. + mSendHoverEnterAndMoveDelayed.addEvent(event); } } break; case MotionEvent.ACTION_POINTER_DOWN: { @@ -1719,7 +1721,7 @@ class TouchExplorer implements EventStreamTransformation { } break; } if (DEBUG) { - Slog.i(LOG_TAG_RECEIVED_POINTER_TRACKER, "Received pointer: " + toString()); + Slog.i(LOG_TAG_RECEIVED_POINTER_TRACKER, "Received pointer:\n" + toString()); } } @@ -1777,7 +1779,7 @@ class TouchExplorer implements EventStreamTransformation { */ public int getPrimaryPointerId() { if (mPrimaryPointerId == INVALID_POINTER_ID) { - mPrimaryPointerId = findPrimaryPointer(); + mPrimaryPointerId = findPrimaryPointerId(); } return mPrimaryPointerId; } @@ -1861,17 +1863,21 @@ class TouchExplorer implements EventStreamTransformation { } /** - * @return The primary pointer. + * @return The primary pointer id. */ - private int findPrimaryPointer() { + private int findPrimaryPointerId() { int primaryPointerId = INVALID_POINTER_ID; long minDownTime = Long.MAX_VALUE; + // Find the pointer that went down first. - for (int i = 0, count = mReceivedPointerDownTime.length; i < count; i++) { - final long downPointerTime = mReceivedPointerDownTime[i]; + int pointerIdBits = mReceivedPointersDown; + while (pointerIdBits > 0) { + final int pointerId = Integer.numberOfTrailingZeros(pointerIdBits); + pointerIdBits &= ~(1 << pointerId); + final long downPointerTime = mReceivedPointerDownTime[pointerId]; if (downPointerTime < minDownTime) { minDownTime = downPointerTime; - primaryPointerId = i; + primaryPointerId = pointerId; } } return primaryPointerId; |