Bug 1441324 - Extract an APZInputBridge interface from IAPZCTreeManager. r?rhunt draft
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 16 Mar 2018 16:28:18 -0400
changeset 768776 43f836775ef5276fc54a0a0828467c3eb42d2615
parent 768775 c488b8d0e074efb490ebca32db68eb77871bfd2f
child 768777 136a9ab262b8acbee28f606e69565ec0bd1c2117
push id102977
push userkgupta@mozilla.com
push dateFri, 16 Mar 2018 20:28:42 +0000
reviewersrhunt
bugs1441324
milestone61.0a1
Bug 1441324 - Extract an APZInputBridge interface from IAPZCTreeManager. r?rhunt This separates the methods that are used to deliver input events synchronously over IPDL to the compositor; this interface will be remoted over a new APZInputBridge IPDL protocol in future patches. MozReview-Commit-ID: 1f3V9SUKlfW
gfx/layers/apz/public/APZInputBridge.h
gfx/layers/apz/public/IAPZCTreeManager.cpp
gfx/layers/apz/public/IAPZCTreeManager.h
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/apz/src/APZInputBridge.cpp
gfx/layers/ipc/APZCTreeManagerChild.cpp
gfx/layers/ipc/APZCTreeManagerChild.h
gfx/layers/moz.build
widget/android/nsWindow.cpp
widget/cocoa/nsChildView.mm
widget/nsBaseWidget.cpp
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/public/APZInputBridge.h
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_layers_APZInputBridge_h
+#define mozilla_layers_APZInputBridge_h
+
+#include "mozilla/EventForwards.h"      // for WidgetInputEvent, nsEventStatus
+#include "Units.h"                      // for LayoutDeviceIntPoint
+
+namespace mozilla {
+
+class InputData;
+
+namespace layers {
+
+struct ScrollableLayerGuid;
+
+/**
+ * This class lives in the main process, and is accessed via the controller
+ * thread (which is the process main thread for desktop, and the Java UI
+ * thread for Android). This class exposes a synchronous API to deliver
+ * incoming input events to APZ and modify them in-place to unapply the APZ
+ * async transform. If there is a GPU process, then this class does sync IPC
+ * calls over to the GPU process in order to accomplish this. Otherwise,
+ * APZCTreeManager overrides and implements these methods directly.
+ */
+class APZInputBridge {
+public:
+  /**
+   * General handler for incoming input events. Manipulates the frame metrics
+   * based on what type of input it is. For example, a PinchGestureEvent will
+   * cause scaling. This should only be called externally to this class, and
+   * must be called on the controller thread.
+   *
+   * This function transforms |aEvent| to have its coordinates in DOM space.
+   * This is so that the event can be passed through the DOM and content can
+   * handle them. The event may need to be converted to a WidgetInputEvent
+   * by the caller if it wants to do this.
+   *
+   * The following values may be returned by this function:
+   * nsEventStatus_eConsumeNoDefault is returned to indicate the
+   *   APZ is consuming this event and the caller should discard the event with
+   *   extreme prejudice. The exact scenarios under which this is returned is
+   *   implementation-dependent and may vary.
+   * nsEventStatus_eIgnore is returned to indicate that the APZ code didn't
+   *   use this event. This might be because it was directed at a point on
+   *   the screen where there was no APZ, or because the thing the user was
+   *   trying to do was not allowed. (For example, attempting to pan a
+   *   non-pannable document).
+   * nsEventStatus_eConsumeDoDefault is returned to indicate that the APZ
+   *   code may have used this event to do some user-visible thing. Note that
+   *   in some cases CONSUMED is returned even if the event was NOT used. This
+   *   is because we cannot always know at the time of event delivery whether
+   *   the event will be used or not. So we err on the side of sending
+   *   CONSUMED when we are uncertain.
+   *
+   * @param aEvent input event object; is modified in-place
+   * @param aOutTargetGuid returns the guid of the apzc this event was
+   * delivered to. May be null.
+   * @param aOutInputBlockId returns the id of the input block that this event
+   * was added to, if that was the case. May be null.
+   */
+  virtual nsEventStatus ReceiveInputEvent(
+      InputData& aEvent,
+      ScrollableLayerGuid* aOutTargetGuid,
+      uint64_t* aOutInputBlockId) = 0;
+
+  /**
+   * WidgetInputEvent handler. Transforms |aEvent| (which is assumed to be an
+   * already-existing instance of an WidgetInputEvent which may be an
+   * WidgetTouchEvent) to have its coordinates in DOM space. This is so that the
+   * event can be passed through the DOM and content can handle them.
+   *
+   * NOTE: Be careful of invoking the WidgetInputEvent variant. This can only be
+   * called on the main thread. See widget/InputData.h for more information on
+   * why we have InputData and WidgetInputEvent separated. If this function is
+   * used, the controller thread must be the main thread, or undefined behaviour
+   * may occur.
+   * NOTE: On unix, mouse events are treated as touch and are forwarded
+   * to the appropriate apz as such.
+   *
+   * See documentation for other ReceiveInputEvent above.
+   */
+  nsEventStatus ReceiveInputEvent(
+      WidgetInputEvent& aEvent,
+      ScrollableLayerGuid* aOutTargetGuid,
+      uint64_t* aOutInputBlockId);
+
+  // Returns whether or not a wheel event action will be (or was) performed by
+  // APZ. If this returns true, the event must not perform a synchronous
+  // scroll.
+  //
+  // Even if this returns false, all wheel events in APZ-aware widgets must
+  // be sent through APZ so they are transformed correctly for TabParent.
+  static bool WillHandleWheelEvent(WidgetWheelEvent* aEvent);
+
+protected:
+
+  // Methods to help process WidgetInputEvents (or manage conversion to/from InputData)
+
+  virtual void ProcessUnhandledEvent(
+      LayoutDeviceIntPoint* aRefPoint,
+      ScrollableLayerGuid* aOutTargetGuid,
+      uint64_t* aOutFocusSequenceNumber) = 0;
+
+  virtual void UpdateWheelTransaction(
+      LayoutDeviceIntPoint aRefPoint,
+      EventMessage aEventMessage) = 0;
+
+  virtual ~APZInputBridge() { }
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_APZInputBridge_h
--- a/gfx/layers/apz/public/IAPZCTreeManager.h
+++ b/gfx/layers/apz/public/IAPZCTreeManager.h
@@ -5,27 +5,25 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_IAPZCTreeManager_h
 #define mozilla_layers_IAPZCTreeManager_h
 
 #include <stdint.h>                     // for uint64_t, uint32_t
 
 #include "FrameMetrics.h"               // for FrameMetrics, etc
-#include "mozilla/EventForwards.h"      // for WidgetInputEvent, nsEventStatus
-#include "mozilla/layers/LayersTypes.h"    // for TouchBehaviorFlags
+#include "mozilla/layers/LayersTypes.h" // for TouchBehaviorFlags
 #include "nsTArrayForwardDeclare.h"     // for nsTArray, nsTArray_Impl, etc
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
-#include "Units.h"                      // for CSSPoint, CSSRect, etc
+#include "Units.h"                      // for CSSRect, etc
 
 namespace mozilla {
-class InputData;
-
 namespace layers {
 
+class APZInputBridge;
 class KeyboardMap;
 
 enum AllowedTouchBehavior {
   NONE =               0,
   VERTICAL_PAN =       1 << 0,
   HORIZONTAL_PAN =     1 << 1,
   PINCH_ZOOM =         1 << 2,
   DOUBLE_TAP_ZOOM =    1 << 3,
@@ -40,77 +38,16 @@ enum ZoomToRectBehavior : uint32_t {
 };
 
 class AsyncDragMetrics;
 
 class IAPZCTreeManager {
   NS_INLINE_DECL_THREADSAFE_VIRTUAL_REFCOUNTING(IAPZCTreeManager)
 
 public:
-
-  /**
-   * General handler for incoming input events. Manipulates the frame metrics
-   * based on what type of input it is. For example, a PinchGestureEvent will
-   * cause scaling. This should only be called externally to this class, and
-   * must be called on the controller thread.
-   *
-   * This function transforms |aEvent| to have its coordinates in DOM space.
-   * This is so that the event can be passed through the DOM and content can
-   * handle them. The event may need to be converted to a WidgetInputEvent
-   * by the caller if it wants to do this.
-   *
-   * The following values may be returned by this function:
-   * nsEventStatus_eConsumeNoDefault is returned to indicate the
-   *   APZ is consuming this event and the caller should discard the event with
-   *   extreme prejudice. The exact scenarios under which this is returned is
-   *   implementation-dependent and may vary.
-   * nsEventStatus_eIgnore is returned to indicate that the APZ code didn't
-   *   use this event. This might be because it was directed at a point on
-   *   the screen where there was no APZ, or because the thing the user was
-   *   trying to do was not allowed. (For example, attempting to pan a
-   *   non-pannable document).
-   * nsEventStatus_eConsumeDoDefault is returned to indicate that the APZ
-   *   code may have used this event to do some user-visible thing. Note that
-   *   in some cases CONSUMED is returned even if the event was NOT used. This
-   *   is because we cannot always know at the time of event delivery whether
-   *   the event will be used or not. So we err on the side of sending
-   *   CONSUMED when we are uncertain.
-   *
-   * @param aEvent input event object; is modified in-place
-   * @param aOutTargetGuid returns the guid of the apzc this event was
-   * delivered to. May be null.
-   * @param aOutInputBlockId returns the id of the input block that this event
-   * was added to, if that was the case. May be null.
-   */
-  virtual nsEventStatus ReceiveInputEvent(
-      InputData& aEvent,
-      ScrollableLayerGuid* aOutTargetGuid,
-      uint64_t* aOutInputBlockId) = 0;
-
-  /**
-   * WidgetInputEvent handler. Transforms |aEvent| (which is assumed to be an
-   * already-existing instance of an WidgetInputEvent which may be an
-   * WidgetTouchEvent) to have its coordinates in DOM space. This is so that the
-   * event can be passed through the DOM and content can handle them.
-   *
-   * NOTE: Be careful of invoking the WidgetInputEvent variant. This can only be
-   * called on the main thread. See widget/InputData.h for more information on
-   * why we have InputData and WidgetInputEvent separated. If this function is
-   * used, the controller thread must be the main thread, or undefined behaviour
-   * may occur.
-   * NOTE: On unix, mouse events are treated as touch and are forwarded
-   * to the appropriate apz as such.
-   *
-   * See documentation for other ReceiveInputEvent above.
-   */
-  nsEventStatus ReceiveInputEvent(
-      WidgetInputEvent& aEvent,
-      ScrollableLayerGuid* aOutTargetGuid,
-      uint64_t* aOutInputBlockId);
-
   /**
    * Set the keyboard shortcuts to use for translating keyboard events.
    */
   virtual void SetKeyboardMap(const KeyboardMap& aKeyboardMap) = 0;
 
   /**
    * Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
    * in. The actual animation is done on the sampler thread after being set
@@ -185,38 +122,27 @@ public:
   /**
    * Function used to disable LongTap gestures.
    *
    * On slow running tests, drags and touch events can be misinterpreted
    * as a long tap. This allows tests to disable long tap gesture detection.
    */
   virtual void SetLongTapEnabled(bool aTapGestureEnabled) = 0;
 
-
-  // Returns whether or not a wheel event action will be (or was) performed by
-  // APZ. If this returns true, the event must not perform a synchronous
-  // scroll.
-  //
-  // Even if this returns false, all wheel events in APZ-aware widgets must
-  // be sent through APZ so they are transformed correctly for TabParent.
-  static bool WillHandleWheelEvent(WidgetWheelEvent* aEvent);
+  /**
+   * Returns an APZInputBridge interface that can be used to send input
+   * events to APZ in a synchronous manner. This will always be non-null, and
+   * the returned object's lifetime will match the lifetime of this
+   * IAPZCTreeManager implementation.
+   * It is only valid to call this function in the UI process.
+   */
+  virtual APZInputBridge* InputBridge() = 0;
 
 protected:
 
-  // Methods to help process WidgetInputEvents (or manage conversion to/from InputData)
-
-  virtual void ProcessUnhandledEvent(
-      LayoutDeviceIntPoint* aRefPoint,
-      ScrollableLayerGuid* aOutTargetGuid,
-      uint64_t* aOutFocusSequenceNumber) = 0;
-
-  virtual void UpdateWheelTransaction(
-      LayoutDeviceIntPoint aRefPoint,
-      EventMessage aEventMessage) = 0;
-
   // Discourage destruction outside of decref
 
   virtual ~IAPZCTreeManager() { }
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1072,17 +1072,17 @@ template<typename PanGestureOrScrollWhee
 static bool
 WillHandleInput(const PanGestureOrScrollWheelInput& aPanInput)
 {
   if (!XRE_IsParentProcess() || !NS_IsMainThread()) {
     return true;
   }
 
   WidgetWheelEvent wheelEvent = aPanInput.ToWidgetWheelEvent(nullptr);
-  return IAPZCTreeManager::WillHandleWheelEvent(&wheelEvent);
+  return APZInputBridge::WillHandleWheelEvent(&wheelEvent);
 }
 
 void
 APZCTreeManager::FlushApzRepaints(uint64_t aLayersId)
 {
   // Previously, paints were throttled and therefore this method was used to
   // ensure any pending paints were flushed. Now, paints are flushed
   // immediately, so it is safe to simply send a notification now.
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -10,16 +10,17 @@
 #include <unordered_map>                          // for std::unordered_map
 
 #include "FocusState.h"                 // for FocusState
 #include "gfxPoint.h"                   // for gfxPoint
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
 #include "mozilla/gfx/CompositorHitTestInfo.h"
 #include "mozilla/gfx/Logging.h"        // for gfx::TreeLog
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
+#include "mozilla/layers/APZInputBridge.h" // for APZInputBridge
 #include "mozilla/layers/APZTestData.h" // for APZTestData
 #include "mozilla/layers/IAPZCTreeManager.h" // for IAPZCTreeManager
 #include "mozilla/layers/KeyboardMap.h" // for KeyboardMap
 #include "mozilla/RecursiveMutex.h"     // for RecursiveMutex
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/TimeStamp.h"          // for mozilla::TimeStamp
 #include "mozilla/UniquePtr.h"          // for UniquePtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
@@ -94,17 +95,18 @@ struct ScrollThumbData;
  * user input events that drive panning and zooming, changes to the scroll viewport
  * area, and changes to pan/zoom constraints.
  *
  * Note that the ClearTree function MUST be called when this class is no longer needed;
  * see the method documentation for details.
  *
  * Behaviour of APZ is controlled by a number of preferences shown \ref APZCPrefs "here".
  */
-class APZCTreeManager : public IAPZCTreeManager {
+class APZCTreeManager : public IAPZCTreeManager
+                      , public APZInputBridge {
 
   typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior;
   typedef mozilla::layers::AsyncDragMetrics AsyncDragMetrics;
 
   // Helper struct to hold some state while we build the hit-testing tree. The
   // sole purpose of this struct is to shorten the argument list to
   // UpdateHitTestingTree. All the state that we don't need to
   // push on the stack during recursion and pop on unwind is stored here.
@@ -468,16 +470,18 @@ public:
   /**
    * Function used to disable LongTap gestures.
    *
    * On slow running tests, drags and touch events can be misinterpreted
    * as a long tap. This allows tests to disable long tap gesture detection.
    */
   void SetLongTapEnabled(bool aTapGestureEnabled) override;
 
+  APZInputBridge* InputBridge() override { return this; }
+
   // Methods to help process WidgetInputEvents (or manage conversion to/from InputData)
 
   void ProcessUnhandledEvent(
       LayoutDeviceIntPoint* aRefPoint,
       ScrollableLayerGuid*  aOutTargetGuid,
       uint64_t*             aOutFocusSequenceNumber) override;
 
   void UpdateWheelTransaction(
rename from gfx/layers/apz/public/IAPZCTreeManager.cpp
rename to gfx/layers/apz/src/APZInputBridge.cpp
--- a/gfx/layers/apz/public/IAPZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZInputBridge.cpp
@@ -1,19 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/layers/IAPZCTreeManager.h"
+#include "mozilla/layers/APZInputBridge.h"
 
 #include "gfxPrefs.h"                       // for gfxPrefs
-#include "InputData.h"                      // for InputData, etc
-#include "mozilla/EventStateManager.h"      // for WheelPrefs
+#include "InputData.h"                      // for MouseInput, etc
+#include "mozilla/EventStateManager.h"      // for EventStateManager
 #include "mozilla/layers/APZThreadUtils.h"  // for AssertOnControllerThread, etc
 #include "mozilla/MouseEvents.h"            // for WidgetMouseEvent
 #include "mozilla/TextEvents.h"             // for WidgetKeyboardEvent
 #include "mozilla/TouchEvents.h"            // for WidgetTouchEvent
 #include "mozilla/WheelHandlingHelper.h"    // for AutoWheelDeltaAdjuster
 
 namespace mozilla {
 namespace layers {
@@ -24,26 +24,26 @@ WillHandleMouseEvent(const WidgetMouseEv
   return aEvent.mMessage == eMouseMove ||
          aEvent.mMessage == eMouseDown ||
          aEvent.mMessage == eMouseUp ||
          aEvent.mMessage == eDragEnd ||
          (gfxPrefs::TestEventsAsyncEnabled() && aEvent.mMessage == eMouseHitTest);
 }
 
 /* static */ bool
-IAPZCTreeManager::WillHandleWheelEvent(WidgetWheelEvent* aEvent)
+APZInputBridge::WillHandleWheelEvent(WidgetWheelEvent* aEvent)
 {
   return EventStateManager::WheelEventIsScrollAction(aEvent) &&
          (aEvent->mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_LINE ||
           aEvent->mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL ||
           aEvent->mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PAGE);
 }
 
 nsEventStatus
-IAPZCTreeManager::ReceiveInputEvent(
+APZInputBridge::ReceiveInputEvent(
     WidgetInputEvent& aEvent,
     ScrollableLayerGuid* aOutTargetGuid,
     uint64_t* aOutInputBlockId)
 {
   APZThreadUtils::AssertOnControllerThread();
 
   // Initialize aOutInputBlockId to a sane value, and then later we overwrite
   // it if the input event goes into a block.
--- a/gfx/layers/ipc/APZCTreeManagerChild.cpp
+++ b/gfx/layers/ipc/APZCTreeManagerChild.cpp
@@ -235,16 +235,22 @@ void APZCTreeManagerChild::ProcessUnhand
     uint64_t*             aOutFocusSequenceNumber)
 {
   SendProcessUnhandledEvent(*aRefPoint,
                             aRefPoint,
                             aOutTargetGuid,
                             aOutFocusSequenceNumber);
 }
 
+APZInputBridge*
+APZCTreeManagerChild::InputBridge()
+{
+  return this;
+}
+
 mozilla::ipc::IPCResult
 APZCTreeManagerChild::RecvHandleTap(const TapType& aType,
                                     const LayoutDevicePoint& aPoint,
                                     const Modifiers& aModifiers,
                                     const ScrollableLayerGuid& aGuid,
                                     const uint64_t& aInputBlockId)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
--- a/gfx/layers/ipc/APZCTreeManagerChild.h
+++ b/gfx/layers/ipc/APZCTreeManagerChild.h
@@ -2,26 +2,28 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_APZCTreeManagerChild_h
 #define mozilla_layers_APZCTreeManagerChild_h
 
+#include "mozilla/layers/APZInputBridge.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/PAPZCTreeManagerChild.h"
 
 namespace mozilla {
 namespace layers {
 
 class RemoteCompositorSession;
 
 class APZCTreeManagerChild
   : public IAPZCTreeManager
+  , public APZInputBridge
   , public PAPZCTreeManagerChild
 {
 public:
   APZCTreeManagerChild();
 
   void SetCompositorSession(RemoteCompositorSession* aSession);
 
   nsEventStatus
@@ -84,16 +86,19 @@ public:
           ScrollableLayerGuid*  aOutTargetGuid,
           uint64_t*             aOutFocusSequenceNumber) override;
 
   void
   UpdateWheelTransaction(
           LayoutDeviceIntPoint aRefPoint,
           EventMessage aEventMessage) override;
 
+  APZInputBridge*
+  InputBridge() override;
+
 protected:
   mozilla::ipc::IPCResult RecvHandleTap(const TapType& aType,
                                         const LayoutDevicePoint& aPoint,
                                         const Modifiers& aModifiers,
                                         const ScrollableLayerGuid& aGuid,
                                         const uint64_t& aInputBlockId) override;
 
   mozilla::ipc::IPCResult RecvNotifyPinchGesture(const PinchGestureType& aType,
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -87,16 +87,17 @@ EXPORTS.gfxipc += [
 
 EXPORTS.mozilla.dom += [
     'apz/util/CheckerboardReportService.h',
 ]
 
 EXPORTS.mozilla.layers += [
     'AnimationHelper.h',
     'AnimationInfo.h',
+    'apz/public/APZInputBridge.h',
     'apz/public/APZSampler.h',
     'apz/public/CompositorController.h',
     'apz/public/GeckoContentController.h',
     'apz/public/IAPZCTreeManager.h',
     'apz/public/MetricsSharingController.h',
     # exporting things from apz/src is temporary until we extract a
     # proper interface for the code there
     'apz/src/APZUtils.h',
@@ -287,18 +288,18 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'andr
     ]
     EXPORTS.mozilla.layers += [
         'apz/src/AndroidDynamicToolbarAnimator.h',
     ]
 
 UNIFIED_SOURCES += [
     'AnimationHelper.cpp',
     'AnimationInfo.cpp',
-    'apz/public/IAPZCTreeManager.cpp',
     'apz/src/APZCTreeManager.cpp',
+    'apz/src/APZInputBridge.cpp',
     'apz/src/APZSampler.cpp',
     'apz/src/APZUtils.cpp',
     'apz/src/AsyncPanZoomController.cpp',
     'apz/src/AutoscrollAnimation.cpp',
     'apz/src/Axis.cpp',
     'apz/src/CheckerboardEvent.cpp',
     'apz/src/DragTracker.cpp',
     'apz/src/FocusState.cpp',
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -52,16 +52,17 @@ using mozilla::Unused;
 #include "nsGfxCIID.h"
 
 #include "gfxContext.h"
 
 #include "Layers.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/AsyncCompositionManager.h"
 #include "mozilla/layers/APZEventState.h"
+#include "mozilla/layers/APZInputBridge.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "ScopedGLHelpers.h"
 #include "mozilla/layers/CompositorOGL.h"
 #include "AndroidContentController.h"
 
@@ -485,17 +486,17 @@ public:
                                ScrollWheelInput::SCROLLMODE_SMOOTH,
                                ScrollWheelInput::SCROLLDELTA_PIXEL,
                                origin,
                                aHScroll, aVScroll,
                                false);
 
         ScrollableLayerGuid guid;
         uint64_t blockId;
-        nsEventStatus status = controller->ReceiveInputEvent(input, &guid, &blockId);
+        nsEventStatus status = controller->InputBridge()->ReceiveInputEvent(input, &guid, &blockId);
 
         if (status == nsEventStatus_eConsumeNoDefault) {
             return true;
         }
 
         PostInputEvent([input, guid, blockId, status] (nsWindow* window) {
             WidgetWheelEvent wheelEvent = input.ToWidgetWheelEvent(window);
             window->ProcessUntransformedAPZEvent(&wheelEvent, guid,
@@ -599,17 +600,17 @@ public:
         }
 
         ScreenPoint origin = ScreenPoint(aX, aY);
 
         MouseInput input(mouseType, buttonType, nsIDOMMouseEvent::MOZ_SOURCE_MOUSE, ConvertButtons(buttons), origin, aTime, GetEventTimeStamp(aTime), GetModifiers(aMetaState));
 
         ScrollableLayerGuid guid;
         uint64_t blockId;
-        nsEventStatus status = controller->ReceiveInputEvent(input, &guid, &blockId);
+        nsEventStatus status = controller->InputBridge()->ReceiveInputEvent(input, &guid, &blockId);
 
         if (status == nsEventStatus_eConsumeNoDefault) {
             return true;
         }
 
         PostInputEvent([input, guid, blockId, status] (nsWindow* window) {
             WidgetMouseEvent mouseEvent = input.ToWidgetMouseEvent(window);
             window->ProcessUntransformedAPZEvent(&mouseEvent, guid,
@@ -721,17 +722,17 @@ public:
             input.mTouches.AppendElement(SingleTouchData(
                     pointerId[i], ScreenIntPoint::FromUnknownPoint(point),
                     ScreenSize::FromUnknownSize(radius), orien, pressure[i]));
         }
 
         ScrollableLayerGuid guid;
         uint64_t blockId;
         nsEventStatus status =
-            controller->ReceiveInputEvent(input, &guid, &blockId);
+            controller->InputBridge()->ReceiveInputEvent(input, &guid, &blockId);
 
         if (status == nsEventStatus_eConsumeNoDefault) {
             return true;
         }
 
         // Dispatch APZ input event on Gecko thread.
         PostInputEvent([input, guid, blockId, status] (nsWindow* window) {
             WidgetTouchEvent touchEvent = input.ToWidgetTouchEvent(window);
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -60,16 +60,17 @@
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "GfxTexturesReporter.h"
 #include "GLTextureImage.h"
 #include "GLContextProvider.h"
 #include "GLContextCGL.h"
 #include "ScopedGLHelpers.h"
 #include "HeapCopyOfStackArray.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
+#include "mozilla/layers/APZInputBridge.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/GLManager.h"
 #include "mozilla/layers/CompositorOGL.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/BasicCompositor.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/IpcResourceUpdateQueue.h"
 #include "mozilla/layers/WebRenderBridgeChild.h"
@@ -2911,17 +2912,17 @@ nsChildView::DispatchAPZWheelInputEvent(
 
   if (mAPZC) {
     uint64_t inputBlockId = 0;
     ScrollableLayerGuid guid;
     nsEventStatus result = nsEventStatus_eIgnore;
 
     switch (aEvent.mInputType) {
       case PANGESTURE_INPUT: {
-        result = mAPZC->ReceiveInputEvent(aEvent, &guid, &inputBlockId);
+        result = mAPZC->InputBridge()->ReceiveInputEvent(aEvent, &guid, &inputBlockId);
         if (result == nsEventStatus_eConsumeNoDefault) {
           return;
         }
 
         PanGestureInput& panInput = aEvent.AsPanGestureInput();
 
         event = panInput.ToWidgetWheelEvent(this);
         if (aCanTriggerSwipe && panInput.mOverscrollBehaviorAllowsSwipe) {
@@ -2950,22 +2951,22 @@ nsChildView::DispatchAPZWheelInputEvent(
 
         if (mSwipeEventQueue && mSwipeEventQueue->inputBlockId == inputBlockId) {
           mSwipeEventQueue->queuedEvents.AppendElement(panInput);
         }
         break;
       }
       case SCROLLWHEEL_INPUT: {
         // For wheel events on OS X, send it to APZ using the WidgetInputEvent
-        // variant of ReceiveInputEvent, because the IAPZCTreeManager version of
+        // variant of ReceiveInputEvent, because the APZInputBridge version of
         // that function has special handling (for delta multipliers etc.) that
         // we need to run. Using the InputData variant would bypass that and
         // go straight to the APZCTreeManager subclass.
         event = aEvent.AsScrollWheelInput().ToWidgetWheelEvent(this);
-        result = mAPZC->ReceiveInputEvent(event, &guid, &inputBlockId);
+        result = mAPZC->InputBridge()->ReceiveInputEvent(event, &guid, &inputBlockId);
         if (result == nsEventStatus_eConsumeNoDefault) {
           return;
         }
         break;
       };
       default:
         MOZ_CRASH("unsupported event type");
         return;
@@ -5098,67 +5099,67 @@ GetIntegerDeltaForEvent(NSEvent* aEvent)
     // MayBegin and Cancelled are dispatched when the fingers start or stop
     // touching the touchpad before any scrolling has occurred. These events
     // can be used to control scrollbar visibility or interrupt scroll
     // animations. They are only dispatched on 10.8 or later, and only by
     // relatively modern devices.
     if (phase == NSEventPhaseMayBegin) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_MAYSTART, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
       return;
     }
     if (phase == NSEventPhaseCancelled) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_CANCELLED, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
       return;
     }
 
     // Legacy scroll events are dispatched by devices that do not have a
     // concept of a scroll gesture, for example by USB mice with
     // traditional mouse wheels.
     // For these kinds of scrolls, we want to surround every single scroll
     // event with a PANGESTURE_START and a PANGESTURE_END event. The APZC
     // needs to know that the real scroll gesture can end abruptly after any
     // one of these events.
     bool isLegacyScroll = (phase == NSEventPhaseNone &&
       momentumPhase == NSEventPhaseNone && delta != ScreenPoint(0, 0));
 
     if (phase == NSEventPhaseBegan || isLegacyScroll) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_START, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
     if (momentumPhase == NSEventPhaseNone && delta != ScreenPoint(0, 0)) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_PAN, eventTime,
                                eventTimeStamp, location, delta, 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
     if (phase == NSEventPhaseEnded || isLegacyScroll) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_END, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
 
     // Any device that can dispatch momentum events supports all three momentum phases.
     if (momentumPhase == NSEventPhaseBegan) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_MOMENTUMSTART, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
     if (momentumPhase == NSEventPhaseChanged && delta != ScreenPoint(0, 0)) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_MOMENTUMPAN, eventTime,
                                eventTimeStamp, location, delta, 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
     if (momentumPhase == NSEventPhaseEnded) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_MOMENTUMEND, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
   }
 }
 
 -(NSMenu*)menuForEvent:(NSEvent*)theEvent
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -52,16 +52,17 @@
 #include "mozilla/gfx/2D.h"
 #include "mozilla/MouseEvents.h"
 #include "GLConsts.h"
 #include "mozilla/Unused.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/VsyncDispatcher.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/APZEventState.h"
+#include "mozilla/layers/APZInputBridge.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/ChromeProcessController.h"
 #include "mozilla/layers/CompositorOptions.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/TabParent.h"
@@ -1159,17 +1160,17 @@ public:
     , mAPZC(aAPZC)
     , mWidget(aWidget)
     , mInputBlockId(0)
   {
   }
 
   NS_IMETHOD Run() override
   {
-    nsEventStatus result = mAPZC->ReceiveInputEvent(mWheelInput, &mGuid, &mInputBlockId);
+    nsEventStatus result = mAPZC->InputBridge()->ReceiveInputEvent(mWheelInput, &mGuid, &mInputBlockId);
     if (result == nsEventStatus_eConsumeNoDefault) {
       return NS_OK;
     }
     RefPtr<Runnable> r = new DispatchWheelEventOnMainThread(mWheelInput, mWidget, result, mInputBlockId, mGuid);
     mMainMessageLoop->PostTask(r.forget());
     return NS_OK;
   }
 
@@ -1186,17 +1187,17 @@ void
 nsBaseWidget::DispatchTouchInput(MultiTouchInput& aInput)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mAPZC) {
     MOZ_ASSERT(APZThreadUtils::IsControllerThread());
     uint64_t inputBlockId = 0;
     ScrollableLayerGuid guid;
 
-    nsEventStatus result = mAPZC->ReceiveInputEvent(aInput, &guid, &inputBlockId);
+    nsEventStatus result = mAPZC->InputBridge()->ReceiveInputEvent(aInput, &guid, &inputBlockId);
     if (result == nsEventStatus_eConsumeNoDefault) {
       return;
     }
 
     WidgetTouchEvent event = aInput.ToWidgetTouchEvent(this);
     ProcessUntransformedAPZEvent(&event, guid, inputBlockId, result);
   } else {
     WidgetTouchEvent event = aInput.ToWidgetTouchEvent(this);
@@ -1211,17 +1212,17 @@ nsBaseWidget::DispatchInputEvent(WidgetI
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mAPZC) {
     if (APZThreadUtils::IsControllerThread()) {
       uint64_t inputBlockId = 0;
       ScrollableLayerGuid guid;
 
       nsEventStatus result =
-        mAPZC->ReceiveInputEvent(*aEvent, &guid, &inputBlockId);
+        mAPZC->InputBridge()->ReceiveInputEvent(*aEvent, &guid, &inputBlockId);
       if (result == nsEventStatus_eConsumeNoDefault) {
         return result;
       }
       return ProcessUntransformedAPZEvent(aEvent, guid, inputBlockId, result);
     }
     WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent();
     if (wheelEvent) {
       RefPtr<Runnable> r =
@@ -1241,17 +1242,17 @@ nsBaseWidget::DispatchInputEvent(WidgetI
 void
 nsBaseWidget::DispatchEventToAPZOnly(mozilla::WidgetInputEvent* aEvent)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mAPZC) {
     MOZ_ASSERT(APZThreadUtils::IsControllerThread());
     uint64_t inputBlockId = 0;
     ScrollableLayerGuid guid;
-    mAPZC->ReceiveInputEvent(*aEvent, &guid, &inputBlockId);
+    mAPZC->InputBridge()->ReceiveInputEvent(*aEvent, &guid, &inputBlockId);
   }
 }
 
 // static
 bool
 nsBaseWidget::ShowContextMenuAfterMouseUp()
 {
   static bool gContextMenuAfterMouseUp = false;