Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2bb59637 authored by Adam Powell's avatar Adam Powell Committed by Android Git Automerger
Browse files

am 030b38ff: Merge "Fix bug 4207704 - Gestures can be lost when Flash is...

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

* commit '030b38ff':
  Fix bug 4207704 - Gestures can be lost when Flash is enabled
parents f0d2c1c4 030b38ff
Loading
Loading
Loading
Loading
+136 −21
Original line number Diff line number Diff line
@@ -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,12 +7415,24 @@ 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.
                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);
@@ -7338,10 +7442,6 @@ public class WebView extends AbsoluteLayout
                mLastHandledTouchSequence++;
            }
            mTouchEventQueue = qd;
            } else {
                QueuedTouch qd = obtainQueuedTouch().set(ev, sequence);
                mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
            }
        }

        private boolean dropStaleGestures(MotionEvent ev, long sequence) {
@@ -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;