Merge "Fix bug 4207704 - Gestures can be lost when Flash is enabled" into honeycomb-mr1

This commit is contained in:
Adam Powell
2011-04-05 10:45:25 -07:00
committed by Android (Google) Code Review

View File

@@ -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;