summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
authorAdam Powell <adamp@google.com>2011-04-05 11:14:27 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2011-04-05 11:14:27 -0700
commit2bb59637caa71d7e05f7c94d3da425fbfd425ea7 (patch)
tree6d7d7a522e8bf828568c4b75675341122c84936a /core/java/android
parentf0d2c1c4eb613130e34a4f377d8f82f935170873 (diff)
parent030b38ffc21ef3962b31d5bac5170531293b6046 (diff)
downloadframeworks_base-2bb59637caa71d7e05f7c94d3da425fbfd425ea7.zip
frameworks_base-2bb59637caa71d7e05f7c94d3da425fbfd425ea7.tar.gz
frameworks_base-2bb59637caa71d7e05f7c94d3da425fbfd425ea7.tar.bz2
am 030b38ff: Merge "Fix bug 4207704 - Gestures can be lost when Flash is enabled" into honeycomb-mr1
* commit '030b38ffc21ef3962b31d5bac5170531293b6046': Fix bug 4207704 - Gestures can be lost when Flash is enabled
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/webkit/WebView.java157
1 files changed, 136 insertions, 21 deletions
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index a3ced9e..57d6108 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -5584,6 +5584,7 @@ public class WebView extends AbsoluteLayout
ted.mNativeLayer = nativeScrollableLayer(
contentX, contentY, ted.mNativeLayerRect, null);
ted.mSequence = mTouchEventQueue.nextTouchSequence();
+ mTouchEventQueue.preQueueTouchEventData(ted);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
if (mDeferTouchProcess) {
// still needs to set them for compute deltaX/Y
@@ -5633,6 +5634,7 @@ public class WebView extends AbsoluteLayout
ted.mNativeLayer = mScrollingLayer;
ted.mNativeLayerRect.set(mScrollingLayerRect);
ted.mSequence = mTouchEventQueue.nextTouchSequence();
+ mTouchEventQueue.preQueueTouchEventData(ted);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
mLastSentTouchTime = eventTime;
if (mDeferTouchProcess) {
@@ -5817,6 +5819,7 @@ public class WebView extends AbsoluteLayout
ted.mNativeLayer = mScrollingLayer;
ted.mNativeLayerRect.set(mScrollingLayerRect);
ted.mSequence = mTouchEventQueue.nextTouchSequence();
+ mTouchEventQueue.preQueueTouchEventData(ted);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
}
mLastTouchUpTime = eventTime;
@@ -5842,6 +5845,7 @@ public class WebView extends AbsoluteLayout
contentX, contentY,
ted.mNativeLayerRect, null);
ted.mSequence = mTouchEventQueue.nextTouchSequence();
+ mTouchEventQueue.preQueueTouchEventData(ted);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDefault != PREVENT_DEFAULT_YES){
mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
@@ -5988,6 +5992,7 @@ public class WebView extends AbsoluteLayout
ted.mReprocess = true;
ted.mMotionEvent = MotionEvent.obtain(ev);
ted.mSequence = sequence;
+ mTouchEventQueue.preQueueTouchEventData(ted);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
cancelLongPress();
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
@@ -7205,9 +7210,17 @@ public class WebView extends AbsoluteLayout
private long mNextTouchSequence = Long.MIN_VALUE + 1;
private long mLastHandledTouchSequence = Long.MIN_VALUE;
private long mIgnoreUntilSequence = Long.MIN_VALUE + 1;
+
+ // Events waiting to be processed.
private QueuedTouch mTouchEventQueue;
+
+ // Known events that are waiting on a response before being enqueued.
+ private QueuedTouch mPreQueue;
+
+ // Pool of QueuedTouch objects saved for later use.
private QueuedTouch mQueuedTouchRecycleBin;
private int mQueuedTouchRecycleCount;
+
private long mLastEventTime = Long.MAX_VALUE;
private static final int MAX_RECYCLED_QUEUED_TOUCH = 15;
@@ -7229,6 +7242,57 @@ public class WebView extends AbsoluteLayout
*/
public void ignoreCurrentlyMissingEvents() {
mIgnoreUntilSequence = mNextTouchSequence;
+
+ // Run any events we have available and complete, pre-queued or otherwise.
+ runQueuedAndPreQueuedEvents();
+ }
+
+ private void runQueuedAndPreQueuedEvents() {
+ QueuedTouch qd = mPreQueue;
+ boolean fromPreQueue = true;
+ while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
+ handleQueuedTouch(qd);
+ QueuedTouch recycleMe = qd;
+ if (fromPreQueue) {
+ mPreQueue = qd.mNext;
+ } else {
+ mTouchEventQueue = qd.mNext;
+ }
+ recycleQueuedTouch(recycleMe);
+ mLastHandledTouchSequence++;
+
+ long nextPre = mPreQueue != null ? mPreQueue.mSequence : Long.MAX_VALUE;
+ long nextQueued = mTouchEventQueue != null ?
+ mTouchEventQueue.mSequence : Long.MAX_VALUE;
+ fromPreQueue = nextPre < nextQueued;
+ qd = fromPreQueue ? mPreQueue : mTouchEventQueue;
+ }
+ }
+
+ /**
+ * Add a TouchEventData to the pre-queue.
+ *
+ * An event in the pre-queue is an event that we know about that
+ * has been sent to webkit, but that we haven't received back and
+ * enqueued into the normal touch queue yet. If webkit ever times
+ * out and we need to ignore currently missing events, we'll run
+ * events from the pre-queue to patch the holes.
+ *
+ * @param ted TouchEventData to pre-queue
+ */
+ public void preQueueTouchEventData(TouchEventData ted) {
+ QueuedTouch newTouch = obtainQueuedTouch().set(ted);
+ if (mPreQueue == null) {
+ mPreQueue = newTouch;
+ } else {
+ QueuedTouch insertionPoint = mPreQueue;
+ while (insertionPoint.mNext != null &&
+ insertionPoint.mNext.mSequence < newTouch.mSequence) {
+ insertionPoint = insertionPoint.mNext;
+ }
+ newTouch.mNext = insertionPoint.mNext;
+ insertionPoint.mNext = newTouch;
+ }
}
private void recycleQueuedTouch(QueuedTouch qd) {
@@ -7252,6 +7316,11 @@ public class WebView extends AbsoluteLayout
mTouchEventQueue = mTouchEventQueue.mNext;
recycleQueuedTouch(recycleMe);
}
+ while (mPreQueue != null) {
+ QueuedTouch recycleMe = mPreQueue;
+ mPreQueue = mPreQueue.mNext;
+ recycleQueuedTouch(recycleMe);
+ }
}
/**
@@ -7274,6 +7343,28 @@ public class WebView extends AbsoluteLayout
* @return true if the event was processed before returning, false if it was just enqueued.
*/
public boolean enqueueTouchEvent(TouchEventData ted) {
+ // Remove from the pre-queue if present
+ QueuedTouch preQueue = mPreQueue;
+ if (preQueue != null) {
+ // On exiting this block, preQueue is set to the pre-queued QueuedTouch object
+ // if it was present in the pre-queue, and removed from the pre-queue itself.
+ if (preQueue.mSequence == ted.mSequence) {
+ mPreQueue = preQueue.mNext;
+ } else {
+ QueuedTouch prev = preQueue;
+ preQueue = null;
+ while (prev.mNext != null) {
+ if (prev.mNext.mSequence == ted.mSequence) {
+ preQueue = prev.mNext;
+ prev.mNext = preQueue.mNext;
+ break;
+ } else {
+ prev = prev.mNext;
+ }
+ }
+ }
+ }
+
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) +
@@ -7285,23 +7376,24 @@ public class WebView extends AbsoluteLayout
return false;
}
+ // dropStaleGestures above might have fast-forwarded us to
+ // an event we have already.
+ runNextQueuedEvents();
+
if (mLastHandledTouchSequence + 1 == ted.mSequence) {
+ if (preQueue != null) {
+ recycleQueuedTouch(preQueue);
+ preQueue = null;
+ }
handleQueuedTouchEventData(ted);
mLastHandledTouchSequence++;
// Do we have any more? Run them if so.
- QueuedTouch qd = mTouchEventQueue;
- while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
- handleQueuedTouch(qd);
- QueuedTouch recycleMe = qd;
- qd = qd.mNext;
- recycleQueuedTouch(recycleMe);
- mLastHandledTouchSequence++;
- }
- mTouchEventQueue = qd;
+ runNextQueuedEvents();
} else {
- QueuedTouch qd = obtainQueuedTouch().set(ted);
+ // Reuse the pre-queued object if we had it.
+ QueuedTouch qd = preQueue != null ? preQueue : obtainQueuedTouch().set(ted);
mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
}
return true;
@@ -7323,27 +7415,35 @@ public class WebView extends AbsoluteLayout
return;
}
+ // dropStaleGestures above might have fast-forwarded us to
+ // an event we have already.
+ runNextQueuedEvents();
+
if (mLastHandledTouchSequence + 1 == sequence) {
handleQueuedMotionEvent(ev);
mLastHandledTouchSequence++;
// Do we have any more? Run them if so.
- QueuedTouch qd = mTouchEventQueue;
- while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
- handleQueuedTouch(qd);
- QueuedTouch recycleMe = qd;
- qd = qd.mNext;
- recycleQueuedTouch(recycleMe);
- mLastHandledTouchSequence++;
- }
- mTouchEventQueue = qd;
+ runNextQueuedEvents();
} else {
QueuedTouch qd = obtainQueuedTouch().set(ev, sequence);
mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
}
}
+ private void runNextQueuedEvents() {
+ QueuedTouch qd = mTouchEventQueue;
+ while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
+ handleQueuedTouch(qd);
+ QueuedTouch recycleMe = qd;
+ qd = qd.mNext;
+ recycleQueuedTouch(recycleMe);
+ mLastHandledTouchSequence++;
+ }
+ mTouchEventQueue = qd;
+ }
+
private boolean dropStaleGestures(MotionEvent ev, long sequence) {
if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && !mConfirmMove) {
// This is to make sure that we don't attempt to process a tap
@@ -7363,13 +7463,16 @@ public class WebView extends AbsoluteLayout
}
// If we have a new down event and it's been a while since the last event
- // we saw, just reset and keep going.
+ // we saw, catch up as best we can and keep going.
if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN) {
long eventTime = ev.getEventTime();
long lastHandledEventTime = mLastEventTime;
if (eventTime > lastHandledEventTime + QUEUED_GESTURE_TIMEOUT) {
Log.w(LOGTAG, "Got ACTION_DOWN but still waiting on stale event. " +
- "Ignoring previous queued events.");
+ "Catching up.");
+ runQueuedAndPreQueuedEvents();
+
+ // Drop leftovers that we truly don't have.
QueuedTouch qd = mTouchEventQueue;
while (qd != null && qd.mSequence < sequence) {
QueuedTouch recycleMe = qd;
@@ -7392,6 +7495,17 @@ public class WebView extends AbsoluteLayout
mLastHandledTouchSequence = mIgnoreUntilSequence - 1;
}
+ if (mPreQueue != null) {
+ // Drop stale prequeued events
+ QueuedTouch qd = mPreQueue;
+ while (qd != null && qd.mSequence < mIgnoreUntilSequence) {
+ QueuedTouch recycleMe = qd;
+ qd = qd.mNext;
+ recycleQueuedTouch(recycleMe);
+ }
+ mPreQueue = qd;
+ }
+
return sequence <= mLastHandledTouchSequence;
}
@@ -7641,6 +7755,7 @@ public class WebView extends AbsoluteLayout
ted.mPoints[0].x, ted.mPoints[0].y,
ted.mNativeLayerRect, null);
ted.mSequence = mTouchEventQueue.nextTouchSequence();
+ mTouchEventQueue.preQueueTouchEventData(ted);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDefault != PREVENT_DEFAULT_YES) {
mTouchMode = TOUCH_DONE_MODE;