private void scheduleWebKitDispatchLocked() { if (!mWebKitDispatchScheduled) { mWebKitHandler.sendEmptyMessage(WebKitHandler.MSG_DISPATCH_WEBKIT_EVENTS); mWebKitDispatchScheduled = true; } }
private void dispatchWebKitEvents(boolean calledFromHandler) { for (; ; ) { // Get the next event, but leave it in the queue so we can move it to the UI // queue if a timeout occurs. DispatchEvent d; MotionEvent event; final int eventType; int flags; synchronized (mLock) { if (!ENABLE_EVENT_BATCHING) { drainStaleWebKitEventsLocked(); } d = mWebKitDispatchEventQueue.mHead; if (d == null) { if (mWebKitDispatchScheduled) { mWebKitDispatchScheduled = false; if (!calledFromHandler) { mWebKitHandler.removeMessages(WebKitHandler.MSG_DISPATCH_WEBKIT_EVENTS); } } return; } event = d.mEvent; if (event != null) { event.offsetLocation(d.mWebKitXOffset, d.mWebKitYOffset); event.scale(d.mWebKitScale); d.mFlags |= FLAG_WEBKIT_TRANSFORMED_EVENT; } eventType = d.mEventType; if (eventType == EVENT_TYPE_TOUCH) { event = mWebKitTouchStream.update(event); if (DEBUG && event == null && d.mEvent != null) { Log.d(TAG, "dispatchWebKitEvents: dropped event " + d.mEvent); } } d.mFlags |= FLAG_WEBKIT_IN_PROGRESS; flags = d.mFlags; } // Handle the event. final boolean preventDefault; if (event == null) { preventDefault = false; } else { preventDefault = dispatchWebKitEvent(event, eventType, flags); } synchronized (mLock) { /// M: update last event prevent status. @ { boolean lastPreventDefault = false; if (d.mEventType == EVENT_TYPE_TOUCH) { lastPreventDefault = mWebKitPreventTouchStream.update(event, preventDefault); } /// @ } flags = d.mFlags; d.mFlags = flags & ~FLAG_WEBKIT_IN_PROGRESS; boolean recycleEvent = event != d.mEvent; if ((flags & FLAG_WEBKIT_TIMEOUT) != 0) { // A timeout occurred! recycleDispatchEventLocked(d); } else { // Web kit finished in a timely manner. Dequeue the event. assert mWebKitDispatchEventQueue.mHead == d; mWebKitDispatchEventQueue.dequeue(); updateWebKitTimeoutLocked(); if ((flags & FLAG_PRIVATE) != 0) { // Event was intended for web kit only. All done. recycleDispatchEventLocked(d); } else if (preventDefault) { // Web kit has decided to consume the event! if (d.mEventType == EVENT_TYPE_TOUCH) { /// M: Consider two consistent events is preventDefault. @ { if (lastPreventDefault) { Log.d(TAG, "Webkit prevent current and last event, cancel ui event"); enqueueUiCancelTouchEventIfNeededLocked(); } else { Log.d(TAG, "Webkit prevent current but not last event, enqueue ui event"); /// Only one event is preventDefault, Ui also handle this touch event. enqueueUiEventUnbatchedLocked(d); } unscheduleLongPressLocked(); /// @ } } } else { // Web kit is being friendly. Pass the event to the UI. enqueueUiEventUnbatchedLocked(d); } } if (event != null && recycleEvent) { event.recycle(); } if (eventType == EVENT_TYPE_CLICK) { scheduleHideTapHighlightLocked(); } } } }