diff options
author | Adam Powell <adamp@google.com> | 2011-03-10 17:06:11 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-03-10 17:06:11 -0800 |
commit | cf63b66cfd49dda473806a3b001db72fca48af5a (patch) | |
tree | 39aaccad57f7a38b8d5e7190c797610a1c0cab86 /core | |
parent | dc8b70cabc23316e349aaf2fe03bcc830dd66e6c (diff) | |
parent | 80615b0075aaa6ee9fdd2a0300190aa00a35f5b1 (diff) | |
download | frameworks_base-cf63b66cfd49dda473806a3b001db72fca48af5a.zip frameworks_base-cf63b66cfd49dda473806a3b001db72fca48af5a.tar.gz frameworks_base-cf63b66cfd49dda473806a3b001db72fca48af5a.tar.bz2 |
Merge "Fix bug 4080407 - Browser stuck after scrolling- page stops responding" into honeycomb-mr1
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/webkit/WebView.java | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 7bf61ab..a667ec3 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -6019,6 +6019,7 @@ public class WebView extends AbsoluteLayout if (shouldForwardTouchEvent()) { if (removeEvents) { mWebViewCore.removeMessages(EventHub.TOUCH_EVENT); + mTouchEventQueue.ignoreCurrentlyMissingEvents(); } TouchEventData ted = new TouchEventData(); ted.mIds = new int[1]; @@ -7157,11 +7158,15 @@ public class WebView extends AbsoluteLayout private class TouchEventQueue { private long mNextTouchSequence = Long.MIN_VALUE + 1; private long mLastHandledTouchSequence = Long.MIN_VALUE; + private long mIgnoreUntilSequence = Long.MIN_VALUE; private QueuedTouch mTouchEventQueue; private QueuedTouch mQueuedTouchRecycleBin; private int mQueuedTouchRecycleCount; private static final int MAX_RECYCLED_QUEUED_TOUCH = 15; + // milliseconds until we abandon hope of getting all of a previous gesture + private static final int QUEUED_GESTURE_TIMEOUT = 2000; + private QueuedTouch obtainQueuedTouch() { if (mQueuedTouchRecycleBin != null) { QueuedTouch result = mQueuedTouchRecycleBin; @@ -7172,6 +7177,13 @@ public class WebView extends AbsoluteLayout return new QueuedTouch(); } + /** + * Allow events with any currently missing sequence numbers to be skipped in processing. + */ + public void ignoreCurrentlyMissingEvents() { + mIgnoreUntilSequence = mNextTouchSequence; + } + private void recycleQueuedTouch(QueuedTouch qd) { if (mQueuedTouchRecycleCount < MAX_RECYCLED_QUEUED_TOUCH) { qd.mNext = mQueuedTouchRecycleBin; @@ -7187,6 +7199,7 @@ public class WebView extends AbsoluteLayout public void reset() { mNextTouchSequence = Long.MIN_VALUE + 1; mLastHandledTouchSequence = Long.MIN_VALUE; + mIgnoreUntilSequence = Long.MIN_VALUE; while (mTouchEventQueue != null) { QueuedTouch recycleMe = mTouchEventQueue; mTouchEventQueue = mTouchEventQueue.mNext; @@ -7213,6 +7226,15 @@ public class WebView extends AbsoluteLayout * @param ted Touch data to be processed in order. */ public void enqueueTouchEvent(TouchEventData ted) { + if (ted.mSequence < mLastHandledTouchSequence) { + // Stale event and we already moved on; drop it. (Should not be common.) + Log.w(LOGTAG, "Stale touch event " + MotionEvent.actionToString(ted.mAction) + + " received from webcore; ignoring"); + return; + } + + dropStaleGestures(ted.mMotionEvent, ted.mSequence); + if (mLastHandledTouchSequence + 1 == ted.mSequence) { handleQueuedTouchEventData(ted); @@ -7245,6 +7267,9 @@ public class WebView extends AbsoluteLayout */ public void enqueueTouchEvent(MotionEvent ev) { final long sequence = nextTouchSequence(); + + dropStaleGestures(ev, sequence); + if (mLastHandledTouchSequence + 1 == sequence) { handleQueuedMotionEvent(ev); @@ -7266,6 +7291,40 @@ public class WebView extends AbsoluteLayout } } + private void dropStaleGestures(MotionEvent ev, long sequence) { + if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN && + mTouchEventQueue != null) { + long eventTime = ev.getEventTime(); + long nextQueueTime = mTouchEventQueue.mTed != null ? + mTouchEventQueue.mTed.mMotionEvent.getEventTime() : + mTouchEventQueue.mEvent.getEventTime(); + if (eventTime > nextQueueTime + QUEUED_GESTURE_TIMEOUT) { + Log.w(LOGTAG, "Got ACTION_DOWN but still waiting on stale event. " + + "Ignoring previous queued events."); + QueuedTouch qd = mTouchEventQueue; + while (qd != null && qd.mSequence < sequence) { + QueuedTouch recycleMe = qd; + qd = qd.mNext; + recycleQueuedTouch(recycleMe); + } + mTouchEventQueue = qd; + mLastHandledTouchSequence = sequence - 1; + } + } + + if (mIgnoreUntilSequence > mLastHandledTouchSequence) { + QueuedTouch qd = mTouchEventQueue; + while (qd != null && qd.mSequence < mIgnoreUntilSequence && + qd.mSequence < sequence) { + mLastHandledTouchSequence = qd.mSequence; + QueuedTouch recycleMe = qd; + qd = qd.mNext; + recycleQueuedTouch(recycleMe); + } + mTouchEventQueue = qd; + } + } + private void handleQueuedTouch(QueuedTouch qt) { if (qt.mTed != null) { handleQueuedTouchEventData(qt.mTed); |