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(
|
ted.mNativeLayer = nativeScrollableLayer(
|
||||||
contentX, contentY, ted.mNativeLayerRect, null);
|
contentX, contentY, ted.mNativeLayerRect, null);
|
||||||
ted.mSequence = mTouchEventQueue.nextTouchSequence();
|
ted.mSequence = mTouchEventQueue.nextTouchSequence();
|
||||||
|
mTouchEventQueue.preQueueTouchEventData(ted);
|
||||||
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
||||||
if (mDeferTouchProcess) {
|
if (mDeferTouchProcess) {
|
||||||
// still needs to set them for compute deltaX/Y
|
// still needs to set them for compute deltaX/Y
|
||||||
@@ -5633,6 +5634,7 @@ public class WebView extends AbsoluteLayout
|
|||||||
ted.mNativeLayer = mScrollingLayer;
|
ted.mNativeLayer = mScrollingLayer;
|
||||||
ted.mNativeLayerRect.set(mScrollingLayerRect);
|
ted.mNativeLayerRect.set(mScrollingLayerRect);
|
||||||
ted.mSequence = mTouchEventQueue.nextTouchSequence();
|
ted.mSequence = mTouchEventQueue.nextTouchSequence();
|
||||||
|
mTouchEventQueue.preQueueTouchEventData(ted);
|
||||||
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
||||||
mLastSentTouchTime = eventTime;
|
mLastSentTouchTime = eventTime;
|
||||||
if (mDeferTouchProcess) {
|
if (mDeferTouchProcess) {
|
||||||
@@ -5817,6 +5819,7 @@ public class WebView extends AbsoluteLayout
|
|||||||
ted.mNativeLayer = mScrollingLayer;
|
ted.mNativeLayer = mScrollingLayer;
|
||||||
ted.mNativeLayerRect.set(mScrollingLayerRect);
|
ted.mNativeLayerRect.set(mScrollingLayerRect);
|
||||||
ted.mSequence = mTouchEventQueue.nextTouchSequence();
|
ted.mSequence = mTouchEventQueue.nextTouchSequence();
|
||||||
|
mTouchEventQueue.preQueueTouchEventData(ted);
|
||||||
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
||||||
}
|
}
|
||||||
mLastTouchUpTime = eventTime;
|
mLastTouchUpTime = eventTime;
|
||||||
@@ -5842,6 +5845,7 @@ public class WebView extends AbsoluteLayout
|
|||||||
contentX, contentY,
|
contentX, contentY,
|
||||||
ted.mNativeLayerRect, null);
|
ted.mNativeLayerRect, null);
|
||||||
ted.mSequence = mTouchEventQueue.nextTouchSequence();
|
ted.mSequence = mTouchEventQueue.nextTouchSequence();
|
||||||
|
mTouchEventQueue.preQueueTouchEventData(ted);
|
||||||
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
||||||
} else if (mPreventDefault != PREVENT_DEFAULT_YES){
|
} else if (mPreventDefault != PREVENT_DEFAULT_YES){
|
||||||
mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
|
mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
|
||||||
@@ -5988,6 +5992,7 @@ public class WebView extends AbsoluteLayout
|
|||||||
ted.mReprocess = true;
|
ted.mReprocess = true;
|
||||||
ted.mMotionEvent = MotionEvent.obtain(ev);
|
ted.mMotionEvent = MotionEvent.obtain(ev);
|
||||||
ted.mSequence = sequence;
|
ted.mSequence = sequence;
|
||||||
|
mTouchEventQueue.preQueueTouchEventData(ted);
|
||||||
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
||||||
cancelLongPress();
|
cancelLongPress();
|
||||||
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
|
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
|
||||||
@@ -7205,9 +7210,17 @@ public class WebView extends AbsoluteLayout
|
|||||||
private long mNextTouchSequence = Long.MIN_VALUE + 1;
|
private long mNextTouchSequence = Long.MIN_VALUE + 1;
|
||||||
private long mLastHandledTouchSequence = Long.MIN_VALUE;
|
private long mLastHandledTouchSequence = Long.MIN_VALUE;
|
||||||
private long mIgnoreUntilSequence = Long.MIN_VALUE + 1;
|
private long mIgnoreUntilSequence = Long.MIN_VALUE + 1;
|
||||||
|
|
||||||
|
// Events waiting to be processed.
|
||||||
private QueuedTouch mTouchEventQueue;
|
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 QueuedTouch mQueuedTouchRecycleBin;
|
||||||
private int mQueuedTouchRecycleCount;
|
private int mQueuedTouchRecycleCount;
|
||||||
|
|
||||||
private long mLastEventTime = Long.MAX_VALUE;
|
private long mLastEventTime = Long.MAX_VALUE;
|
||||||
private static final int MAX_RECYCLED_QUEUED_TOUCH = 15;
|
private static final int MAX_RECYCLED_QUEUED_TOUCH = 15;
|
||||||
|
|
||||||
@@ -7229,6 +7242,57 @@ public class WebView extends AbsoluteLayout
|
|||||||
*/
|
*/
|
||||||
public void ignoreCurrentlyMissingEvents() {
|
public void ignoreCurrentlyMissingEvents() {
|
||||||
mIgnoreUntilSequence = mNextTouchSequence;
|
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) {
|
private void recycleQueuedTouch(QueuedTouch qd) {
|
||||||
@@ -7252,6 +7316,11 @@ public class WebView extends AbsoluteLayout
|
|||||||
mTouchEventQueue = mTouchEventQueue.mNext;
|
mTouchEventQueue = mTouchEventQueue.mNext;
|
||||||
recycleQueuedTouch(recycleMe);
|
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.
|
* @return true if the event was processed before returning, false if it was just enqueued.
|
||||||
*/
|
*/
|
||||||
public boolean enqueueTouchEvent(TouchEventData ted) {
|
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) {
|
if (ted.mSequence < mLastHandledTouchSequence) {
|
||||||
// Stale event and we already moved on; drop it. (Should not be common.)
|
// Stale event and we already moved on; drop it. (Should not be common.)
|
||||||
Log.w(LOGTAG, "Stale touch event " + MotionEvent.actionToString(ted.mAction) +
|
Log.w(LOGTAG, "Stale touch event " + MotionEvent.actionToString(ted.mAction) +
|
||||||
@@ -7285,23 +7376,24 @@ public class WebView extends AbsoluteLayout
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dropStaleGestures above might have fast-forwarded us to
|
||||||
|
// an event we have already.
|
||||||
|
runNextQueuedEvents();
|
||||||
|
|
||||||
if (mLastHandledTouchSequence + 1 == ted.mSequence) {
|
if (mLastHandledTouchSequence + 1 == ted.mSequence) {
|
||||||
|
if (preQueue != null) {
|
||||||
|
recycleQueuedTouch(preQueue);
|
||||||
|
preQueue = null;
|
||||||
|
}
|
||||||
handleQueuedTouchEventData(ted);
|
handleQueuedTouchEventData(ted);
|
||||||
|
|
||||||
mLastHandledTouchSequence++;
|
mLastHandledTouchSequence++;
|
||||||
|
|
||||||
// Do we have any more? Run them if so.
|
// Do we have any more? Run them if so.
|
||||||
QueuedTouch qd = mTouchEventQueue;
|
runNextQueuedEvents();
|
||||||
while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
|
|
||||||
handleQueuedTouch(qd);
|
|
||||||
QueuedTouch recycleMe = qd;
|
|
||||||
qd = qd.mNext;
|
|
||||||
recycleQueuedTouch(recycleMe);
|
|
||||||
mLastHandledTouchSequence++;
|
|
||||||
}
|
|
||||||
mTouchEventQueue = qd;
|
|
||||||
} else {
|
} 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);
|
mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -7323,27 +7415,35 @@ public class WebView extends AbsoluteLayout
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dropStaleGestures above might have fast-forwarded us to
|
||||||
|
// an event we have already.
|
||||||
|
runNextQueuedEvents();
|
||||||
|
|
||||||
if (mLastHandledTouchSequence + 1 == sequence) {
|
if (mLastHandledTouchSequence + 1 == sequence) {
|
||||||
handleQueuedMotionEvent(ev);
|
handleQueuedMotionEvent(ev);
|
||||||
|
|
||||||
mLastHandledTouchSequence++;
|
mLastHandledTouchSequence++;
|
||||||
|
|
||||||
// Do we have any more? Run them if so.
|
// Do we have any more? Run them if so.
|
||||||
QueuedTouch qd = mTouchEventQueue;
|
runNextQueuedEvents();
|
||||||
while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
|
|
||||||
handleQueuedTouch(qd);
|
|
||||||
QueuedTouch recycleMe = qd;
|
|
||||||
qd = qd.mNext;
|
|
||||||
recycleQueuedTouch(recycleMe);
|
|
||||||
mLastHandledTouchSequence++;
|
|
||||||
}
|
|
||||||
mTouchEventQueue = qd;
|
|
||||||
} else {
|
} else {
|
||||||
QueuedTouch qd = obtainQueuedTouch().set(ev, sequence);
|
QueuedTouch qd = obtainQueuedTouch().set(ev, sequence);
|
||||||
mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
|
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) {
|
private boolean dropStaleGestures(MotionEvent ev, long sequence) {
|
||||||
if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && !mConfirmMove) {
|
if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && !mConfirmMove) {
|
||||||
// This is to make sure that we don't attempt to process a tap
|
// 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
|
// 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) {
|
if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
long eventTime = ev.getEventTime();
|
long eventTime = ev.getEventTime();
|
||||||
long lastHandledEventTime = mLastEventTime;
|
long lastHandledEventTime = mLastEventTime;
|
||||||
if (eventTime > lastHandledEventTime + QUEUED_GESTURE_TIMEOUT) {
|
if (eventTime > lastHandledEventTime + QUEUED_GESTURE_TIMEOUT) {
|
||||||
Log.w(LOGTAG, "Got ACTION_DOWN but still waiting on stale event. " +
|
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;
|
QueuedTouch qd = mTouchEventQueue;
|
||||||
while (qd != null && qd.mSequence < sequence) {
|
while (qd != null && qd.mSequence < sequence) {
|
||||||
QueuedTouch recycleMe = qd;
|
QueuedTouch recycleMe = qd;
|
||||||
@@ -7392,6 +7495,17 @@ public class WebView extends AbsoluteLayout
|
|||||||
mLastHandledTouchSequence = mIgnoreUntilSequence - 1;
|
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;
|
return sequence <= mLastHandledTouchSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7641,6 +7755,7 @@ public class WebView extends AbsoluteLayout
|
|||||||
ted.mPoints[0].x, ted.mPoints[0].y,
|
ted.mPoints[0].x, ted.mPoints[0].y,
|
||||||
ted.mNativeLayerRect, null);
|
ted.mNativeLayerRect, null);
|
||||||
ted.mSequence = mTouchEventQueue.nextTouchSequence();
|
ted.mSequence = mTouchEventQueue.nextTouchSequence();
|
||||||
|
mTouchEventQueue.preQueueTouchEventData(ted);
|
||||||
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
|
||||||
} else if (mPreventDefault != PREVENT_DEFAULT_YES) {
|
} else if (mPreventDefault != PREVENT_DEFAULT_YES) {
|
||||||
mTouchMode = TOUCH_DONE_MODE;
|
mTouchMode = TOUCH_DONE_MODE;
|
||||||
|
|||||||
Reference in New Issue
Block a user