Merge "Fix bug 4207704 - Gestures can be lost when Flash is enabled" into honeycomb-mr1
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user