public WebViewInputDispatcher(UiCallbacks uiCallbacks, WebKitCallbacks webKitCallbacks) {
    this.mUiCallbacks = uiCallbacks;
    mUiHandler = new UiHandler(uiCallbacks.getUiLooper());

    this.mWebKitCallbacks = webKitCallbacks;
    mWebKitHandler = new WebKitHandler(webKitCallbacks.getWebKitLooper());

    ViewConfiguration config = ViewConfiguration.get(mUiCallbacks.getContext());
    mDoubleTapSlopSquared = config.getScaledDoubleTapSlop();
    mDoubleTapSlopSquared = (mDoubleTapSlopSquared * mDoubleTapSlopSquared);
    mTouchSlopSquared = config.getScaledTouchSlop();
    mTouchSlopSquared = (mTouchSlopSquared * mTouchSlopSquared);
  }
 // Runs on UI thread.
 private void dispatchUiEvent(MotionEvent event, int eventType, int flags) {
   if (DEBUG) {
     Log.d(
         TAG, "dispatchUiEvent: event=" + event + ", eventType=" + eventType + ", flags=" + flags);
   }
   mUiCallbacks.dispatchUiEvent(event, eventType, flags);
 }
 private void enqueueHitTestLocked(MotionEvent event) {
   mUiCallbacks.clearPreviousHitTest();
   MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event);
   DispatchEvent d =
       obtainDispatchEventLocked(
           eventToEnqueue,
           EVENT_TYPE_HIT_TEST,
           0,
           mPostLastWebKitXOffset,
           mPostLastWebKitYOffset,
           mPostLastWebKitScale);
   enqueueEventLocked(d);
 }
 private void postShowTapHighlight(boolean show) {
   synchronized (mLock) {
     if (show) {
       if (!mPostShowTapHighlightScheduled) {
         return;
       }
       mPostShowTapHighlightScheduled = false;
     } else {
       if (!mPostHideTapHighlightScheduled) {
         return;
       }
       mPostHideTapHighlightScheduled = false;
     }
     mUiCallbacks.showTapHighlight(show);
   }
 }
 private void showTapCandidateLocked() {
   unscheduleHideTapHighlightLocked();
   unscheduleShowTapHighlightLocked();
   mUiCallbacks.showTapHighlight(true);
 }
  /**
   * Posts a pointer event to the dispatch queue.
   *
   * @param event The event to post.
   * @param webKitXOffset X offset to apply to events before dispatching them to web kit.
   * @param webKitYOffset Y offset to apply to events before dispatching them to web kit.
   * @param webKitScale The scale factor to apply to translated events before dispatching them to
   *     web kit.
   * @return True if the dispatcher will handle the event, false if the event is unsupported.
   */
  public boolean postPointerEvent(
      MotionEvent event, int webKitXOffset, int webKitYOffset, float webKitScale) {
    if (event == null) {
      throw new IllegalArgumentException("event cannot be null");
    }

    if (DEBUG) {
      Log.d(TAG, "postPointerEvent: " + event);
    }

    final int action = event.getActionMasked();
    final int eventType;
    switch (action) {
      case MotionEvent.ACTION_DOWN:
      case MotionEvent.ACTION_MOVE:
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_POINTER_DOWN:
      case MotionEvent.ACTION_POINTER_UP:
      case MotionEvent.ACTION_CANCEL:
        eventType = EVENT_TYPE_TOUCH;
        break;
      case MotionEvent.ACTION_SCROLL:
        eventType = EVENT_TYPE_SCROLL;
        break;
      case MotionEvent.ACTION_HOVER_ENTER:
      case MotionEvent.ACTION_HOVER_MOVE:
      case MotionEvent.ACTION_HOVER_EXIT:
        eventType = EVENT_TYPE_HOVER;
        break;
      default:
        return false; // currently unsupported event type
    }

    synchronized (mLock) {
      // Ensure that the event is consistent and should be delivered.
      MotionEvent eventToEnqueue = event;
      if (eventType == EVENT_TYPE_TOUCH) {
        eventToEnqueue = mPostTouchStream.update(event);
        if (eventToEnqueue == null) {
          if (DEBUG) {
            Log.d(TAG, "postPointerEvent: dropped event " + event);
          }
          unscheduleLongPressLocked();
          unscheduleClickLocked();
          hideTapCandidateLocked();
          return false;
        }

        if (action == MotionEvent.ACTION_DOWN && mPostSendTouchEventsToWebKit) {
          if (mUiCallbacks.shouldInterceptTouchEvent(eventToEnqueue)) {
            mPostDoNotSendTouchEventsToWebKitUntilNextGesture = true;
          } else if (mPostDoNotSendTouchEventsToWebKitUntilNextGesture) {
            // Recover from a previous web kit timeout.
            mPostDoNotSendTouchEventsToWebKitUntilNextGesture = false;
          }
        }
      }

      // Copy the event because we need to retain ownership.
      if (eventToEnqueue == event) {
        eventToEnqueue = event.copy();
      }

      DispatchEvent d =
          obtainDispatchEventLocked(
              eventToEnqueue, eventType, 0, webKitXOffset, webKitYOffset, webKitScale);
      updateStateTrackersLocked(d, event);
      enqueueEventLocked(d);
    }
    return true;
  }