Bug 1281575 - Extract interface of APZCTreeManager for moving to GPUProcess. r=kats
authorRyan Hunt <rhunt@mozilla.com>
Wed, 20 Jul 2016 13:37:00 +0200
changeset 390707 02f12f2a1fbfadbae78864cd754cf3f721f6abcb
parent 390706 9206985d615dcd3afa039f94a99faa88c7f2d988
child 390708 0055f23a1374324df40c85c27b4ac417de6e2cc2
push id23725
push userbmo:tchiovoloni@mozilla.com
push dateThu, 21 Jul 2016 15:39:58 +0000
reviewerskats
bugs1281575
milestone50.0a1
Bug 1281575 - Extract interface of APZCTreeManager for moving to GPUProcess. r=kats MozReview-Commit-ID: 7tO2kkTNFk2
gfx/ipc/CompositorSession.h
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
gfx/ipc/InProcessCompositorSession.cpp
gfx/ipc/InProcessCompositorSession.h
gfx/ipc/RemoteCompositorSession.cpp
gfx/ipc/RemoteCompositorSession.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/util/ChromeProcessController.cpp
gfx/layers/apz/util/ChromeProcessController.h
gfx/layers/ipc/RemoteContentController.cpp
gfx/layers/ipc/RemoteContentController.h
gfx/layers/moz.build
widget/android/AndroidContentController.cpp
widget/android/AndroidContentController.h
widget/android/nsWindow.cpp
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
widget/nsBaseWidget.cpp
widget/nsBaseWidget.h
--- a/gfx/ipc/CompositorSession.h
+++ b/gfx/ipc/CompositorSession.h
@@ -18,17 +18,17 @@ class CompositorWidgetDelegate;
 } // namespace widget
 namespace gfx {
 class GPUProcessHost;
 class GPUProcessManager;
 } // namespace gfx
 namespace layers {
 
 class GeckoContentController;
-class APZCTreeManager;
+class IAPZCTreeManager;
 class CompositorBridgeParent;
 class CompositorBridgeChild;
 class ClientLayerManager;
 
 // A CompositorSession provides access to a compositor without exposing whether
 // or not it's in-process or out-of-process.
 class CompositorSession
 {
@@ -46,17 +46,17 @@ public:
 
   // This returns a CompositorBridgeParent if the compositor resides in the same process.
   virtual CompositorBridgeParent* GetInProcessBridge() const = 0;
 
   // Set the GeckoContentController for the root of the layer tree.
   virtual void SetContentController(GeckoContentController* aController) = 0;
 
   // Return the Async Pan/Zoom Tree Manager for this compositor.
-  virtual already_AddRefed<APZCTreeManager> GetAPZCTreeManager() const = 0;
+  virtual already_AddRefed<IAPZCTreeManager> GetAPZCTreeManager() const = 0;
 
   // Return the child end of the compositor IPC bridge.
   CompositorBridgeChild* GetCompositorBridgeChild();
 
   // Return the proxy for accessing the compositor's widget.
   CompositorWidgetDelegate* GetCompositorWidgetDelegate() {
     return mCompositorWidgetDelegate;
   }
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -478,17 +478,17 @@ GPUProcessManager::CreateContentVRManage
       return false;
     }
   }
 
   *aOutEndpoint = Move(childPipe);
   return true;
 }
 
-already_AddRefed<APZCTreeManager>
+already_AddRefed<IAPZCTreeManager>
 GPUProcessManager::GetAPZCTreeManagerForLayers(uint64_t aLayersId)
 {
   return CompositorBridgeParent::GetAPZCTreeManager(aLayersId);
 }
 
 uint64_t
 GPUProcessManager::AllocateLayerTreeId()
 {
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -18,17 +18,17 @@
 #include "mozilla/ipc/Transport.h"
 #include "nsIObserverService.h"
 #include "nsThreadUtils.h"
 class nsBaseWidget;
 
 
 namespace mozilla {
 namespace layers {
-class APZCTreeManager;
+class IAPZCTreeManager;
 class CompositorSession;
 class ClientLayerManager;
 class CompositorUpdateObserver;
 class PCompositorBridgeChild;
 class PImageBridgeChild;
 } // namespace layers
 namespace widget {
 class CompositorWidget;
@@ -47,19 +47,19 @@ class VsyncBridgeChild;
 class VsyncIOThreadHolder;
 class PVRManagerChild;
 
 // The GPUProcessManager is a singleton responsible for creating GPU-bound
 // objects that may live in another process. Currently, it provides access
 // to the compositor via CompositorBridgeParent.
 class GPUProcessManager final : public GPUProcessHost::Listener
 {
-  typedef layers::APZCTreeManager APZCTreeManager;
   typedef layers::ClientLayerManager ClientLayerManager;
   typedef layers::CompositorSession CompositorSession;
+  typedef layers::IAPZCTreeManager IAPZCTreeManager;
   typedef layers::CompositorUpdateObserver CompositorUpdateObserver;
   typedef layers::PCompositorBridgeChild PCompositorBridgeChild;
   typedef layers::PImageBridgeChild PImageBridgeChild;
 
 public:
   static void Initialize();
   static void Shutdown();
   static GPUProcessManager* Get();
@@ -86,17 +86,17 @@ public:
                                      ipc::Endpoint<PCompositorBridgeChild>* aOutEndpoint);
   bool CreateContentImageBridge(base::ProcessId aOtherProcess,
                                 ipc::Endpoint<PImageBridgeChild>* aOutEndpoint);
   bool CreateContentVRManager(base::ProcessId aOtherProcess,
                               ipc::Endpoint<PVRManagerChild>* aOutEndpoint);
 
   // This returns a reference to the APZCTreeManager to which
   // pan/zoom-related events can be sent.
-  already_AddRefed<APZCTreeManager> GetAPZCTreeManagerForLayers(uint64_t aLayersId);
+  already_AddRefed<IAPZCTreeManager> GetAPZCTreeManagerForLayers(uint64_t aLayersId);
 
   // Allocate an ID that can be used to refer to a layer tree and
   // associated resources that live only on the compositor thread.
   //
   // Must run on the content main thread.
   uint64_t AllocateLayerTreeId();
 
   // Release compositor-thread resources referred to by |aID|.
--- a/gfx/ipc/InProcessCompositorSession.cpp
+++ b/gfx/ipc/InProcessCompositorSession.cpp
@@ -1,16 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=99: */
 /* 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 "InProcessCompositorSession.h"
 
+// so we can cast an APZCTreeManager to an IAPZCTreeManager
+#include "mozilla/layers/APZCTreeManager.h"
+#include "mozilla/layers/IAPZCTreeManager.h"
+
 namespace mozilla {
 namespace layers {
 
 InProcessCompositorSession::InProcessCompositorSession(widget::CompositorWidget* aWidget,
                                                        CompositorBridgeChild* aChild,
                                                        CompositorBridgeParent* aParent)
  : CompositorSession(aWidget->AsDelegate(), aChild, aParent->RootLayerTreeId()),
    mCompositorBridgeParent(aParent),
@@ -45,17 +49,17 @@ InProcessCompositorSession::GetInProcess
 }
 
 void
 InProcessCompositorSession::SetContentController(GeckoContentController* aController)
 {
   mCompositorBridgeParent->SetControllerForLayerTree(mRootLayerTreeId, aController);
 }
 
-already_AddRefed<APZCTreeManager>
+already_AddRefed<IAPZCTreeManager>
 InProcessCompositorSession::GetAPZCTreeManager() const
 {
   return mCompositorBridgeParent->GetAPZCTreeManager(mRootLayerTreeId);
 }
 
 void
 InProcessCompositorSession::Shutdown()
 {
--- a/gfx/ipc/InProcessCompositorSession.h
+++ b/gfx/ipc/InProcessCompositorSession.h
@@ -24,17 +24,17 @@ public:
     const uint64_t& aRootLayerTreeId,
     CSSToLayoutDeviceScale aScale,
     bool aUseAPZ,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
   CompositorBridgeParent* GetInProcessBridge() const override;
   void SetContentController(GeckoContentController* aController) override;
-  already_AddRefed<APZCTreeManager> GetAPZCTreeManager() const override;
+  already_AddRefed<IAPZCTreeManager> GetAPZCTreeManager() const override;
   void Shutdown() override;
 
 private:
   InProcessCompositorSession(widget::CompositorWidget* aWidget,
                              CompositorBridgeChild* aChild,
                              CompositorBridgeParent* aParent);
 
 private:
--- a/gfx/ipc/RemoteCompositorSession.cpp
+++ b/gfx/ipc/RemoteCompositorSession.cpp
@@ -25,17 +25,17 @@ RemoteCompositorSession::GetInProcessBri
 }
 
 void
 RemoteCompositorSession::SetContentController(GeckoContentController* aController)
 {
   MOZ_CRASH("NYI");
 }
 
-already_AddRefed<APZCTreeManager>
+already_AddRefed<IAPZCTreeManager>
 RemoteCompositorSession::GetAPZCTreeManager() const
 {
   return nullptr;
 }
 
 void
 RemoteCompositorSession::Shutdown()
 {
--- a/gfx/ipc/RemoteCompositorSession.h
+++ b/gfx/ipc/RemoteCompositorSession.h
@@ -17,17 +17,17 @@ class RemoteCompositorSession final : pu
 {
 public:
   RemoteCompositorSession(CompositorBridgeChild* aChild,
                           CompositorWidgetDelegate* aWidgetDelegate,
                           const uint64_t& aRootLayerTreeId);
 
   CompositorBridgeParent* GetInProcessBridge() const override;
   void SetContentController(GeckoContentController* aController) override;
-  already_AddRefed<APZCTreeManager> GetAPZCTreeManager() const override;
+  already_AddRefed<IAPZCTreeManager> GetAPZCTreeManager() const override;
   void Shutdown() override;
 
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // include_mozilla_gfx_ipc_RemoteCompositorSession_h
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/public/IAPZCTreeManager.cpp
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=99: */
+/* 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 "gfxPrefs.h"                       // for gfxPrefs
+#include "InputData.h"                      // for InputData, etc
+#include "mozilla/EventStateManager.h"      // for WheelPrefs
+#include "mozilla/layers/APZThreadUtils.h"  // for AssertOnCompositorThread, etc
+#include "mozilla/MouseEvents.h"            // for WidgetMouseEvent
+#include "mozilla/TouchEvents.h"            // for WidgetTouchEvent
+
+namespace mozilla {
+namespace layers {
+
+static bool
+WillHandleMouseEvent(const WidgetMouseEventBase& aEvent)
+{
+  return aEvent.mMessage == eMouseMove ||
+         aEvent.mMessage == eMouseDown ||
+         aEvent.mMessage == eMouseUp ||
+         aEvent.mMessage == eDragEnd;
+}
+
+// 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)
+{
+  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(
+    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.
+  if (aOutInputBlockId) {
+    *aOutInputBlockId = 0;
+  }
+
+  switch (aEvent.mClass) {
+    case eMouseEventClass:
+    case eDragEventClass: {
+
+      WidgetMouseEvent& mouseEvent = *aEvent.AsMouseEvent();
+
+      // Note, we call this before having transformed the reference point.
+      if (mouseEvent.IsReal()) {
+        UpdateWheelTransaction(mouseEvent.mRefPoint, mouseEvent.mMessage);
+      }
+
+      if (WillHandleMouseEvent(mouseEvent)) {
+
+        MouseInput input(mouseEvent);
+        input.mOrigin = ScreenPoint(mouseEvent.mRefPoint.x, mouseEvent.mRefPoint.y);
+
+        nsEventStatus status = ReceiveInputEvent(input, aOutTargetGuid, aOutInputBlockId);
+
+        mouseEvent.mRefPoint.x = input.mOrigin.x;
+        mouseEvent.mRefPoint.y = input.mOrigin.y;
+        mouseEvent.mFlags.mHandledByAPZ = input.mHandledByAPZ;
+        return status;
+
+      }
+
+      TransformEventRefPoint(&mouseEvent.mRefPoint, aOutTargetGuid);
+      return nsEventStatus_eIgnore;
+    }
+    case eTouchEventClass: {
+
+      WidgetTouchEvent& touchEvent = *aEvent.AsTouchEvent();
+      MultiTouchInput touchInput(touchEvent);
+      nsEventStatus result = ReceiveInputEvent(touchInput, aOutTargetGuid, aOutInputBlockId);
+      // touchInput was modified in-place to possibly remove some
+      // touch points (if we are overscrolled), and the coordinates were
+      // modified using the APZ untransform. We need to copy these changes
+      // back into the WidgetInputEvent.
+      touchEvent.mTouches.Clear();
+      touchEvent.mTouches.SetCapacity(touchInput.mTouches.Length());
+      for (size_t i = 0; i < touchInput.mTouches.Length(); i++) {
+        *touchEvent.mTouches.AppendElement() =
+          touchInput.mTouches[i].ToNewDOMTouch();
+      }
+      touchEvent.mFlags.mHandledByAPZ = touchInput.mHandledByAPZ;
+      return result;
+
+    }
+    case eWheelEventClass: {
+      WidgetWheelEvent& wheelEvent = *aEvent.AsWheelEvent();
+
+      if (WillHandleWheelEvent(&wheelEvent)) {
+
+        ScrollWheelInput::ScrollMode scrollMode = ScrollWheelInput::SCROLLMODE_INSTANT;
+        if (gfxPrefs::SmoothScrollEnabled() &&
+            ((wheelEvent.mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_LINE &&
+              gfxPrefs::WheelSmoothScrollEnabled()) ||
+             (wheelEvent.mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PAGE &&
+              gfxPrefs::PageSmoothScrollEnabled())))
+        {
+          scrollMode = ScrollWheelInput::SCROLLMODE_SMOOTH;
+        }
+
+        ScreenPoint origin(wheelEvent.mRefPoint.x, wheelEvent.mRefPoint.y);
+        ScrollWheelInput input(wheelEvent.mTime, wheelEvent.mTimeStamp, 0,
+                               scrollMode,
+                               ScrollWheelInput::DeltaTypeForDeltaMode(
+                                                   wheelEvent.mDeltaMode),
+                               origin,
+                               wheelEvent.mDeltaX, wheelEvent.mDeltaY,
+                               wheelEvent.mAllowToOverrideSystemScrollSpeed);
+
+        // We add the user multiplier as a separate field, rather than premultiplying
+        // it, because if the input is converted back to a WidgetWheelEvent, then
+        // EventStateManager would apply the delta a second time. We could in theory
+        // work around this by asking ESM to customize the event much sooner, and
+        // then save the "mCustomizedByUserPrefs" bit on ScrollWheelInput - but for
+        // now, this seems easier.
+        EventStateManager::GetUserPrefsForWheelEvent(&wheelEvent,
+          &input.mUserDeltaMultiplierX,
+          &input.mUserDeltaMultiplierY);
+
+        nsEventStatus status = ReceiveInputEvent(input, aOutTargetGuid, aOutInputBlockId);
+        wheelEvent.mRefPoint.x = input.mOrigin.x;
+        wheelEvent.mRefPoint.y = input.mOrigin.y;
+        wheelEvent.mFlags.mHandledByAPZ = input.mHandledByAPZ;
+        return status;
+      }
+
+      UpdateWheelTransaction(aEvent.mRefPoint, aEvent.mMessage);
+      TransformEventRefPoint(&aEvent.mRefPoint, aOutTargetGuid);
+      return nsEventStatus_eIgnore;
+
+    }
+    default: {
+
+      UpdateWheelTransaction(aEvent.mRefPoint, aEvent.mMessage);
+      TransformEventRefPoint(&aEvent.mRefPoint, aOutTargetGuid);
+      return nsEventStatus_eIgnore;
+
+    }
+  }
+
+  MOZ_ASSERT_UNREACHABLE("Invalid WidgetInputEvent type.");
+  return nsEventStatus_eConsumeNoDefault;
+}
+
+} // namespace layers
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/public/IAPZCTreeManager.h
@@ -0,0 +1,223 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=99: */
+/* 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_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/APZUtils.h"    // for HitTestResult
+#include "nsTArrayForwardDeclare.h"     // for nsTArray, nsTArray_Impl, etc
+#include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
+#include "Units.h"                      // for CSSPoint, CSSRect, etc
+
+namespace mozilla {
+class InputData;
+
+namespace layers {
+
+enum AllowedTouchBehavior {
+  NONE =               0,
+  VERTICAL_PAN =       1 << 0,
+  HORIZONTAL_PAN =     1 << 1,
+  PINCH_ZOOM =         1 << 2,
+  DOUBLE_TAP_ZOOM =    1 << 3,
+  UNKNOWN =            1 << 4
+};
+
+enum ZoomToRectBehavior : uint32_t {
+  DEFAULT_BEHAVIOR =   0,
+  DISABLE_ZOOM_OUT =   1 << 0,
+  PAN_INTO_VIEW_ONLY = 1 << 1,
+  ONLY_ZOOM_TO_DEFAULT_SCALE  = 1 << 2
+};
+
+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);
+
+  /**
+   * 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 compositor thread after being set
+   * up. |aRect| must be given in CSS pixels, relative to the document.
+   * |aFlags| is a combination of the ZoomToRectBehavior enum values.
+   */
+  virtual void ZoomToRect(
+      const ScrollableLayerGuid& aGuid,
+      const CSSRect& aRect,
+      const uint32_t aFlags = DEFAULT_BEHAVIOR) = 0;
+
+  /**
+   * If we have touch listeners, this should always be called when we know
+   * definitively whether or not content has preventDefaulted any touch events
+   * that have come in. If |aPreventDefault| is true, any touch events in the
+   * queue will be discarded. This function must be called on the controller
+   * thread.
+   */
+  virtual void ContentReceivedInputBlock(
+      uint64_t aInputBlockId,
+      bool aPreventDefault) = 0;
+
+  /**
+   * When the event regions code is enabled, this function should be invoked to
+   * to confirm the target of the input block. This is only needed in cases
+   * where the initial input event of the block hit a dispatch-to-content region
+   * but is safe to call for all input blocks. This function should always be
+   * invoked on the controller thread.
+   * The different elements in the array of targets correspond to the targets
+   * for the different touch points. In the case where the touch point has no
+   * target, or the target is not a scrollable frame, the target's |mScrollId|
+   * should be set to FrameMetrics::NULL_SCROLL_ID.
+   */
+  virtual void SetTargetAPZC(
+      uint64_t aInputBlockId,
+      const nsTArray<ScrollableLayerGuid>& aTargets) = 0;
+
+  /**
+   * Updates any zoom constraints contained in the <meta name="viewport"> tag.
+   * If the |aConstraints| is Nothing() then previously-provided constraints for
+   * the given |aGuid| are cleared.
+   */
+  virtual void UpdateZoomConstraints(
+      const ScrollableLayerGuid& aGuid,
+      const Maybe<ZoomConstraints>& aConstraints) = 0;
+
+  /**
+   * Cancels any currently running animation. Note that all this does is set the
+   * state of the AsyncPanZoomController back to NOTHING, but it is the
+   * animation's responsibility to check this before advancing.
+   */
+  virtual void CancelAnimation(const ScrollableLayerGuid &aGuid) = 0;
+
+  /**
+   * Adjusts the root APZC to compensate for a shift in the surface. See the
+   * documentation on AsyncPanZoomController::AdjustScrollForSurfaceShift for
+   * some more details. This is only currently needed due to surface shifts
+   * caused by the dynamic toolbar on Android.
+   */
+  virtual void AdjustScrollForSurfaceShift(const ScreenPoint& aShift) = 0;
+
+  virtual void SetDPI(float aDpiValue) = 0;
+
+  /**
+   * Sets allowed touch behavior values for current touch-session for specific
+   * input block (determined by aInputBlock).
+   * Should be invoked by the widget. Each value of the aValues arrays
+   * corresponds to the different touch point that is currently active.
+   * Must be called after receiving the TOUCH_START event that starts the
+   * touch-session.
+   * This must be called on the controller thread.
+   */
+  virtual void SetAllowedTouchBehavior(
+      uint64_t aInputBlockId,
+      const nsTArray<TouchBehaviorFlags>& aValues) = 0;
+
+  virtual void StartScrollbarDrag(
+      const ScrollableLayerGuid& aGuid,
+      const AsyncDragMetrics& aDragMetrics) = 0;
+
+  /**
+   * 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;
+
+  /**
+   * Process touch velocity.
+   * Sometimes the touch move event will have a velocity even though no scrolling
+   * is occurring such as when the toolbar is being hidden/shown in Fennec.
+   * This function can be called to have the y axis' velocity queue updated.
+   */
+  virtual void ProcessTouchVelocity(uint32_t aTimestampMs, float aSpeedY) = 0;
+
+protected:
+
+  // Methods to help process WidgetInputEvents (or manage conversion to/from InputData)
+
+  virtual void TransformEventRefPoint(
+      LayoutDeviceIntPoint* aRefPoint,
+      ScrollableLayerGuid* aOutTargetGuid) = 0;
+
+  virtual void UpdateWheelTransaction(
+      LayoutDeviceIntPoint aRefPoint,
+      EventMessage aEventMessage) = 0;
+
+  // Discourage destruction outside of decref
+
+  virtual ~IAPZCTreeManager() { }
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_IAPZCTreeManager_h
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -600,40 +600,16 @@ APZCTreeManager::UpdateHitTestingTree(Tr
     gfx::TreeAutoIndent indent(mApzcTreeLog);
     next = UpdateHitTestingTree(aState, child, childLayersId,
                                 ancestorTransform, aParent, next);
   }
 
   return node;
 }
 
-// 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)
-{
-  return EventStateManager::WheelEventIsScrollAction(aEvent) &&
-         (aEvent->mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_LINE ||
-          aEvent->mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL ||
-          aEvent->mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PAGE);
-}
-
-static bool
-WillHandleMouseEvent(const WidgetMouseEventBase& aEvent)
-{
-  return aEvent.mMessage == eMouseMove ||
-         aEvent.mMessage == eMouseDown ||
-         aEvent.mMessage == eMouseUp ||
-         aEvent.mMessage == eDragEnd;
-}
-
 template<typename PanGestureOrScrollWheelInput>
 static bool
 WillHandleInput(const PanGestureOrScrollWheelInput& aPanInput)
 {
   if (!NS_IsMainThread()) {
     return true;
   }
 
@@ -1034,17 +1010,17 @@ APZCTreeManager::ProcessTouchInput(Multi
     }
 
     // For computing the event to pass back to Gecko, use up-to-date transforms
     // (i.e. not anything cached in an input block).
     // This ensures that transformToApzc and transformToGecko are in sync.
     ScreenToParentLayerMatrix4x4 transformToApzc = GetScreenToApzcTransform(mApzcForInputBlock);
     ParentLayerToScreenMatrix4x4 transformToGecko = GetApzcToGeckoTransform(mApzcForInputBlock);
     ScreenToScreenMatrix4x4 outTransform = transformToApzc * transformToGecko;
-    
+
     for (size_t i = 0; i < aInput.mTouches.Length(); i++) {
       SingleTouchData& touchData = aInput.mTouches[i];
       Maybe<ScreenIntPoint> untransformedScreenPoint = UntransformBy(
           outTransform, touchData.mScreenPoint);
       if (!untransformedScreenPoint) {
         return nsEventStatus_eIgnore;
       }
       touchData.mScreenPoint = *untransformedScreenPoint;
@@ -1060,42 +1036,41 @@ APZCTreeManager::ProcessTouchInput(Multi
     mHitResultForInputBlock = HitNothing;
     mRetainedTouchIdentifier = -1;
   }
 
   return result;
 }
 
 void
-APZCTreeManager::UpdateWheelTransaction(WidgetInputEvent& aEvent)
+APZCTreeManager::UpdateWheelTransaction(LayoutDeviceIntPoint aRefPoint,
+                                        EventMessage aEventMessage)
 {
   WheelBlockState* txn = mInputQueue->GetCurrentWheelTransaction();
   if (!txn) {
     return;
   }
 
   // If the transaction has simply timed out, we don't need to do anything
   // else.
   if (txn->MaybeTimeout(TimeStamp::Now())) {
     return;
   }
 
-  switch (aEvent.mMessage) {
+  switch (aEventMessage) {
    case eMouseMove:
    case eDragOver: {
-     WidgetMouseEvent* mouseEvent = aEvent.AsMouseEvent();
-     if (!mouseEvent->IsReal()) {
-       return;
-     }
 
-     ScreenIntPoint point =
-       ViewAs<ScreenPixel>(aEvent.mRefPoint,
-         PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent);
-     txn->OnMouseMove(point);
-     return;
+    ScreenIntPoint point =
+     ViewAs<ScreenPixel>(aRefPoint,
+       PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent);
+
+    txn->OnMouseMove(point);
+
+    return;
    }
    case eKeyPress:
    case eKeyUp:
    case eKeyDown:
    case eMouseUp:
    case eMouseDown:
    case eMouseDoubleClick:
    case eMouseClick:
@@ -1103,177 +1078,50 @@ APZCTreeManager::UpdateWheelTransaction(
    case eDrop:
      txn->EndTransaction();
      return;
    default:
      break;
   }
 }
 
-nsEventStatus
-APZCTreeManager::ProcessEvent(WidgetInputEvent& aEvent,
-                              ScrollableLayerGuid* aOutTargetGuid,
-                              uint64_t* aOutInputBlockId)
+void
+APZCTreeManager::TransformEventRefPoint(LayoutDeviceIntPoint* aRefPoint,
+                              ScrollableLayerGuid* aOutTargetGuid)
 {
-  MOZ_ASSERT(NS_IsMainThread());
-  nsEventStatus result = nsEventStatus_eIgnore;
-
-  // Note, we call this before having transformed the reference point.
-  UpdateWheelTransaction(aEvent);
-
-  // Transform the mRefPoint.
+  // Transform the aRefPoint.
   // If the event hits an overscrolled APZC, instruct the caller to ignore it.
   HitTestResult hitResult = HitNothing;
   PixelCastJustification LDIsScreen = PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent;
   ScreenIntPoint refPointAsScreen =
-    ViewAs<ScreenPixel>(aEvent.mRefPoint, LDIsScreen);
+    ViewAs<ScreenPixel>(*aRefPoint, LDIsScreen);
   RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(refPointAsScreen, &hitResult);
   if (apzc) {
     MOZ_ASSERT(hitResult != HitNothing);
     apzc->GetGuid(aOutTargetGuid);
     ScreenToParentLayerMatrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
     ParentLayerToScreenMatrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
     ScreenToScreenMatrix4x4 outTransform = transformToApzc * transformToGecko;
     Maybe<ScreenIntPoint> untransformedRefPoint =
       UntransformBy(outTransform, refPointAsScreen);
     if (untransformedRefPoint) {
-      aEvent.mRefPoint =
+      *aRefPoint =
         ViewAs<LayoutDevicePixel>(*untransformedRefPoint, LDIsScreen);
     }
   }
-  return result;
-}
-
-nsEventStatus
-APZCTreeManager::ProcessMouseEvent(WidgetMouseEventBase& aEvent,
-                                   ScrollableLayerGuid* aOutTargetGuid,
-                                   uint64_t* aOutInputBlockId)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  // Note, we call this before having transformed the reference point.
-  UpdateWheelTransaction(aEvent);
-
-  MouseInput input(aEvent);
-  input.mOrigin = ScreenPoint(aEvent.mRefPoint.x, aEvent.mRefPoint.y);
-
-  nsEventStatus status = ReceiveInputEvent(input, aOutTargetGuid, aOutInputBlockId);
-
-  aEvent.mRefPoint.x = input.mOrigin.x;
-  aEvent.mRefPoint.y = input.mOrigin.y;
-  aEvent.mFlags.mHandledByAPZ = input.mHandledByAPZ;
-  return status;
 }
 
 void
 APZCTreeManager::ProcessTouchVelocity(uint32_t aTimestampMs, float aSpeedY)
 {
   if (mApzcForInputBlock) {
     mApzcForInputBlock->HandleTouchVelocity(aTimestampMs, aSpeedY);
   }
 }
 
-nsEventStatus
-APZCTreeManager::ProcessWheelEvent(WidgetWheelEvent& aEvent,
-                                   ScrollableLayerGuid* aOutTargetGuid,
-                                   uint64_t* aOutInputBlockId)
-{
-  ScrollWheelInput::ScrollMode scrollMode = ScrollWheelInput::SCROLLMODE_INSTANT;
-  if (gfxPrefs::SmoothScrollEnabled() &&
-      ((aEvent.mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_LINE &&
-        gfxPrefs::WheelSmoothScrollEnabled()) ||
-       (aEvent.mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PAGE &&
-        gfxPrefs::PageSmoothScrollEnabled())))
-  {
-    scrollMode = ScrollWheelInput::SCROLLMODE_SMOOTH;
-  }
-
-  ScreenPoint origin(aEvent.mRefPoint.x, aEvent.mRefPoint.y);
-  ScrollWheelInput input(aEvent.mTime, aEvent.mTimeStamp, 0,
-                         scrollMode,
-                         ScrollWheelInput::DeltaTypeForDeltaMode(
-                                             aEvent.mDeltaMode),
-                         origin,
-                         aEvent.mDeltaX, aEvent.mDeltaY,
-                         aEvent.mAllowToOverrideSystemScrollSpeed);
-
-  // We add the user multiplier as a separate field, rather than premultiplying
-  // it, because if the input is converted back to a WidgetWheelEvent, then
-  // EventStateManager would apply the delta a second time. We could in theory
-  // work around this by asking ESM to customize the event much sooner, and
-  // then save the "mCustomizedByUserPrefs" bit on ScrollWheelInput - but for
-  // now, this seems easier.
-  EventStateManager::GetUserPrefsForWheelEvent(&aEvent,
-    &input.mUserDeltaMultiplierX,
-    &input.mUserDeltaMultiplierY);
-
-  nsEventStatus status = ReceiveInputEvent(input, aOutTargetGuid, aOutInputBlockId);
-  aEvent.mRefPoint.x = input.mOrigin.x;
-  aEvent.mRefPoint.y = input.mOrigin.y;
-  aEvent.mFlags.mHandledByAPZ = input.mHandledByAPZ;
-  return status;
-}
-
-nsEventStatus
-APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent,
-                                   ScrollableLayerGuid* aOutTargetGuid,
-                                   uint64_t* aOutInputBlockId)
-{
-  // In general it is preferable to use the version of ReceiveInputEvent
-  // that takes an InputData, as that is usable from off-main-thread. On some
-  // platforms OMT input isn't possible, and there we can use this version.
-
-  MOZ_ASSERT(NS_IsMainThread());
-  APZThreadUtils::AssertOnControllerThread();
-
-  // Initialize aOutInputBlockId to a sane value, and then later we overwrite
-  // it if the input event goes into a block.
-  if (aOutInputBlockId) {
-    *aOutInputBlockId = InputBlockState::NO_BLOCK_ID;
-  }
-
-  switch (aEvent.mClass) {
-    case eMouseEventClass:
-    case eDragEventClass: {
-      WidgetMouseEventBase& mouseEvent = *aEvent.AsMouseEventBase();
-      if (WillHandleMouseEvent(mouseEvent)) {
-        return ProcessMouseEvent(mouseEvent, aOutTargetGuid, aOutInputBlockId);
-      }
-      return ProcessEvent(aEvent, aOutTargetGuid, aOutInputBlockId);
-    }
-    case eTouchEventClass: {
-      WidgetTouchEvent& touchEvent = *aEvent.AsTouchEvent();
-      MultiTouchInput touchInput(touchEvent);
-      nsEventStatus result = ProcessTouchInput(touchInput, aOutTargetGuid, aOutInputBlockId);
-      // touchInput was modified in-place to possibly remove some
-      // touch points (if we are overscrolled), and the coordinates were
-      // modified using the APZ untransform. We need to copy these changes
-      // back into the WidgetInputEvent.
-      touchEvent.mTouches.Clear();
-      touchEvent.mTouches.SetCapacity(touchInput.mTouches.Length());
-      for (size_t i = 0; i < touchInput.mTouches.Length(); i++) {
-        *touchEvent.mTouches.AppendElement() =
-          touchInput.mTouches[i].ToNewDOMTouch();
-      }
-      touchEvent.mFlags.mHandledByAPZ = touchInput.mHandledByAPZ;
-      return result;
-    }
-    case eWheelEventClass: {
-      WidgetWheelEvent& wheelEvent = *aEvent.AsWheelEvent();
-      if (WillHandleWheelEvent(&wheelEvent)) {
-        return ProcessWheelEvent(wheelEvent, aOutTargetGuid, aOutInputBlockId);
-      }
-      return ProcessEvent(aEvent, aOutTargetGuid, aOutInputBlockId);
-    }
-    default: {
-      return ProcessEvent(aEvent, aOutTargetGuid, aOutInputBlockId);
-    }
-  }
-}
-
 void
 APZCTreeManager::ZoomToRect(const ScrollableLayerGuid& aGuid,
                             const CSSRect& aRect,
                             const uint32_t aFlags)
 {
   RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
   if (apzc) {
     apzc->ZoomToRect(aRect, aFlags);
@@ -1757,17 +1605,17 @@ APZCTreeManager::BuildOverscrollHandoffC
   // Print the overscroll chain for debugging.
   for (uint32_t i = 0; i < result->Length(); ++i) {
     APZCTM_LOG("OverscrollHandoffChain[%d] = %p\n", i, result->GetApzcAtIndex(i).get());
   }
 
   return result;
 }
 
-/* static */ void
+void
 APZCTreeManager::SetLongTapEnabled(bool aLongTapEnabled)
 {
   APZThreadUtils::RunOnControllerThread(
     NewRunnableFunction(GestureEventListener::SetLongTapEnabled, aLongTapEnabled));
 }
 
 RefPtr<HitTestingTreeNode>
 APZCTreeManager::FindScrollNode(const AsyncDragMetrics& aDragMetrics)
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -1,59 +1,36 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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_APZCTreeManager_h
 #define mozilla_layers_APZCTreeManager_h
 
-#include <stdint.h>                     // for uint64_t, uint32_t
 #include <map>                          // for std::map
 
-#include "FrameMetrics.h"               // for FrameMetrics, etc
 #include "gfxPoint.h"                   // for gfxPoint
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
-#include "mozilla/EventForwards.h"      // for WidgetInputEvent, nsEventStatus
 #include "mozilla/gfx/Logging.h"        // for gfx::TreeLog
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
-#include "mozilla/layers/APZUtils.h"    // for HitTestResult
 #include "mozilla/layers/TouchCounter.h"// for TouchCounter
+#include "mozilla/layers/IAPZCTreeManager.h" // for IAPZCTreeManager
 #include "mozilla/Mutex.h"              // for Mutex
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/TimeStamp.h"          // for mozilla::TimeStamp
 #include "nsCOMPtr.h"                   // for already_AddRefed
-#include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
-#include "nsTArrayForwardDeclare.h"     // for nsTArray, nsTArray_Impl, etc
-#include "Units.h"                      // for CSSPoint, CSSRect, etc
+
 
 namespace mozilla {
-class InputData;
 class MultiTouchInput;
 
 namespace layers {
 
-enum AllowedTouchBehavior {
-  NONE =               0,
-  VERTICAL_PAN =       1 << 0,
-  HORIZONTAL_PAN =     1 << 1,
-  PINCH_ZOOM =         1 << 2,
-  DOUBLE_TAP_ZOOM =    1 << 3,
-  UNKNOWN =            1 << 4
-};
-
-enum ZoomToRectBehavior : uint32_t {
-  DEFAULT_BEHAVIOR =   0,
-  DISABLE_ZOOM_OUT =   1 << 0,
-  PAN_INTO_VIEW_ONLY = 1 << 1,
-  ONLY_ZOOM_TO_DEFAULT_SCALE  = 1 << 2
-};
-
 class Layer;
-class AsyncDragMetrics;
 class AsyncPanZoomController;
 class CompositorBridgeParent;
 class OverscrollHandoffChain;
 struct OverscrollHandoffState;
 struct FlingHandoffState;
 class LayerMetricsWrapper;
 class InputQueue;
 class GeckoContentController;
@@ -95,18 +72,17 @@ class HitTestingTreeNode;
  * 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 {
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZCTreeManager)
+class APZCTreeManager : public IAPZCTreeManager {
 
   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.
@@ -178,101 +154,87 @@ public:
    *   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.
    */
-  nsEventStatus ReceiveInputEvent(InputData& aEvent,
-                                  ScrollableLayerGuid* aOutTargetGuid,
-                                  uint64_t* aOutInputBlockId);
-
-  /**
-   * 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);
+  nsEventStatus ReceiveInputEvent(
+      InputData& aEvent,
+      ScrollableLayerGuid* aOutTargetGuid,
+      uint64_t* aOutInputBlockId) override;
 
   /**
    * 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 compositor thread after being set
    * up. |aRect| must be given in CSS pixels, relative to the document.
    * |aFlags| is a combination of the ZoomToRectBehavior enum values.
    */
-  void ZoomToRect(const ScrollableLayerGuid& aGuid,
-                  const CSSRect& aRect,
-                  const uint32_t aFlags = DEFAULT_BEHAVIOR);
+  void ZoomToRect(
+      const ScrollableLayerGuid& aGuid,
+      const CSSRect& aRect,
+      const uint32_t aFlags = DEFAULT_BEHAVIOR) override;
 
   /**
    * If we have touch listeners, this should always be called when we know
    * definitively whether or not content has preventDefaulted any touch events
    * that have come in. If |aPreventDefault| is true, any touch events in the
    * queue will be discarded. This function must be called on the controller
    * thread.
    */
-  void ContentReceivedInputBlock(uint64_t aInputBlockId, bool aPreventDefault);
+  void ContentReceivedInputBlock(
+      uint64_t aInputBlockId,
+      bool aPreventDefault) override;
 
   /**
    * When the event regions code is enabled, this function should be invoked to
    * to confirm the target of the input block. This is only needed in cases
    * where the initial input event of the block hit a dispatch-to-content region
    * but is safe to call for all input blocks. This function should always be
    * invoked on the controller thread.
    * The different elements in the array of targets correspond to the targets
    * for the different touch points. In the case where the touch point has no
    * target, or the target is not a scrollable frame, the target's |mScrollId|
    * should be set to FrameMetrics::NULL_SCROLL_ID.
    */
-  void SetTargetAPZC(uint64_t aInputBlockId,
-                     const nsTArray<ScrollableLayerGuid>& aTargets);
+  void SetTargetAPZC(
+      uint64_t aInputBlockId,
+      const nsTArray<ScrollableLayerGuid>& aTargets) override;
 
   /**
    * Helper function for SetTargetAPZC when used with single-target events,
    * such as mouse wheel events.
    */
   void SetTargetAPZC(uint64_t aInputBlockId, const ScrollableLayerGuid& aTarget);
 
   /**
    * Updates any zoom constraints contained in the <meta name="viewport"> tag.
    * If the |aConstraints| is Nothing() then previously-provided constraints for
    * the given |aGuid| are cleared.
    */
-  void UpdateZoomConstraints(const ScrollableLayerGuid& aGuid,
-                             const Maybe<ZoomConstraints>& aConstraints);
+  void UpdateZoomConstraints(
+      const ScrollableLayerGuid& aGuid,
+      const Maybe<ZoomConstraints>& aConstraints) override;
 
   /**
    * Cancels any currently running animation. Note that all this does is set the
    * state of the AsyncPanZoomController back to NOTHING, but it is the
    * animation's responsibility to check this before advancing.
    */
-  void CancelAnimation(const ScrollableLayerGuid &aGuid);
+  void CancelAnimation(const ScrollableLayerGuid &aGuid) override;
 
   /**
    * Adjusts the root APZC to compensate for a shift in the surface. See the
    * documentation on AsyncPanZoomController::AdjustScrollForSurfaceShift for
    * some more details. This is only currently needed due to surface shifts
    * caused by the dynamic toolbar on Android.
    */
-  void AdjustScrollForSurfaceShift(const ScreenPoint& aShift);
+  void AdjustScrollForSurfaceShift(const ScreenPoint& aShift) override;
 
   /**
    * Calls Destroy() on all APZC instances attached to the tree, and resets the
    * tree back to empty. This function may be called multiple times during the
    * lifetime of this APZCTreeManager, but it must always be called at least once
    * when this APZCTreeManager is no longer needed. Failing to call this function
    * may prevent objects from being freed properly.
    */
@@ -288,20 +250,20 @@ public:
    * function simply delegates to that one, so that non-layers code
    * never needs to include AsyncPanZoomController.h
    */
   static const ScreenMargin CalculatePendingDisplayPort(
     const FrameMetrics& aFrameMetrics,
     const ParentLayerPoint& aVelocity);
 
   /**
-   * Set the dpi value used by all AsyncPanZoomControllers.
+   * Sets the dpi value used by all AsyncPanZoomControllers.
    * DPI defaults to 72 if not set using SetDPI() at any point.
    */
-  static void SetDPI(float aDpiValue) { sDPI = aDpiValue; }
+  void SetDPI(float aDpiValue) override { sDPI = aDpiValue; }
 
   /**
    * Returns the current dpi value in use.
    */
   static float GetDPI() { return sDPI; }
 
   /**
    * Find the hit testing node for the scrollbar thumb that matches these
@@ -313,18 +275,19 @@ public:
    * Sets allowed touch behavior values for current touch-session for specific
    * input block (determined by aInputBlock).
    * Should be invoked by the widget. Each value of the aValues arrays
    * corresponds to the different touch point that is currently active.
    * Must be called after receiving the TOUCH_START event that starts the
    * touch-session.
    * This must be called on the controller thread.
    */
-  void SetAllowedTouchBehavior(uint64_t aInputBlockId,
-                               const nsTArray<TouchBehaviorFlags>& aValues);
+  void SetAllowedTouchBehavior(
+      uint64_t aInputBlockId,
+      const nsTArray<TouchBehaviorFlags>& aValues) override;
 
   /**
    * This is a callback for AsyncPanZoomController to call when it wants to
    * scroll in response to a touch-move event, or when it needs to hand off
    * overscroll to the next APZC. Note that because of scroll grabbing, the
    * first APZC to scroll may not be the one that is receiving the touch events.
    *
    * |aAPZC| is the APZC that received the touch events triggering the scroll
@@ -396,36 +359,45 @@ public:
    * aHandoffState.mVelocity will be modified depending on how much of that
    * velocity has been consumed by APZCs in the overscroll hand-off chain.
    * The caller can use this value to determine whether it should consume
    * the excess velocity by going into an overscroll fling.
    */
   void DispatchFling(AsyncPanZoomController* aApzc,
                      FlingHandoffState& aHandoffState);
 
-  void StartScrollbarDrag(const ScrollableLayerGuid& aGuid,
-                          const AsyncDragMetrics& aDragMetrics);
+  void StartScrollbarDrag(
+      const ScrollableLayerGuid& aGuid,
+      const AsyncDragMetrics& aDragMetrics) override;
 
   /*
    * Build the chain of APZCs that will handle overscroll for a pan starting at |aInitialTarget|.
    */
   RefPtr<const OverscrollHandoffChain> BuildOverscrollHandoffChain(const RefPtr<AsyncPanZoomController>& aInitialTarget);
 
   /**
    * 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.
    */
-  static void SetLongTapEnabled(bool aTapGestureEnabled);
+  void SetLongTapEnabled(bool aTapGestureEnabled) override;
 
 protected:
   // Protected destructor, to discourage deletion outside of Release():
   virtual ~APZCTreeManager();
 
+  // Methods to help process WidgetInputEvents (or manage conversion to/from InputData)
+  void TransformEventRefPoint(
+      LayoutDeviceIntPoint* aRefPoint,
+      ScrollableLayerGuid* aOutTargetGuid) override;
+  void UpdateWheelTransaction(
+      LayoutDeviceIntPoint aRefPoint,
+      EventMessage aEventMessage) override;
+
   // Protected hooks for gtests subclass
   virtual AsyncPanZoomController* NewAPZCInstance(uint64_t aLayersId,
                                                   GeckoContentController* aController);
 public:
   // Public hooks for gtests subclass
   virtual TimeStamp GetFrameTime();
 
 public:
@@ -443,17 +415,17 @@ public:
   ParentLayerToScreenMatrix4x4 GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const;
 
   /**
    * Process touch velocity.
    * Sometimes the touch move event will have a velocity even though no scrolling
    * is occurring such as when the toolbar is being hidden/shown in Fennec.
    * This function can be called to have the y axis' velocity queue updated.
    */
-  void ProcessTouchVelocity(uint32_t aTimestampMs, float aSpeedY);
+  void ProcessTouchVelocity(uint32_t aTimestampMs, float aSpeedY) override;
 private:
   typedef bool (*GuidComparator)(const ScrollableLayerGuid&, const ScrollableLayerGuid&);
 
   /* Helpers */
   void AttachNodeToTree(HitTestingTreeNode* aNode,
                         HitTestingTreeNode* aParent,
                         HitTestingTreeNode* aNextSibling);
   already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScrollableLayerGuid& aGuid);
@@ -473,26 +445,16 @@ private:
   already_AddRefed<AsyncPanZoomController> GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
   already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
   already_AddRefed<AsyncPanZoomController> GetTouchInputBlockAPZC(const MultiTouchInput& aEvent,
                                                                   nsTArray<TouchBehaviorFlags>* aOutTouchBehaviors,
                                                                   HitTestResult* aOutHitResult);
   nsEventStatus ProcessTouchInput(MultiTouchInput& aInput,
                                   ScrollableLayerGuid* aOutTargetGuid,
                                   uint64_t* aOutInputBlockId);
-  nsEventStatus ProcessWheelEvent(WidgetWheelEvent& aEvent,
-                                  ScrollableLayerGuid* aOutTargetGuid,
-                                  uint64_t* aOutInputBlockId);
-  nsEventStatus ProcessEvent(WidgetInputEvent& inputEvent,
-                             ScrollableLayerGuid* aOutTargetGuid,
-                             uint64_t* aOutInputBlockId);
-  nsEventStatus ProcessMouseEvent(WidgetMouseEventBase& aInput,
-                                  ScrollableLayerGuid* aOutTargetGuid,
-                                  uint64_t* aOutInputBlockId);
-  void UpdateWheelTransaction(WidgetInputEvent& aEvent);
   void FlushRepaintsToClearScreenToGeckoTransform();
 
   already_AddRefed<HitTestingTreeNode> RecycleOrCreateNode(TreeBuildingState& aState,
                                                            AsyncPanZoomController* aApzc,
                                                            uint64_t aLayersId);
   HitTestingTreeNode* PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
                                           const FrameMetrics& aMetrics,
                                           uint64_t aLayersId,
--- a/gfx/layers/apz/util/ChromeProcessController.cpp
+++ b/gfx/layers/apz/util/ChromeProcessController.cpp
@@ -6,31 +6,31 @@
 #include "ChromeProcessController.h"
 
 #include "MainThreadUtils.h"    // for NS_IsMainThread()
 #include "base/message_loop.h"  // for MessageLoop
 #include "mozilla/dom/Element.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/APZEventState.h"
-#include "mozilla/layers/APZCTreeManager.h"
+#include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/DoubleTapToZoom.h"
 #include "nsIDocument.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIPresShell.h"
 #include "nsLayoutUtils.h"
 #include "nsView.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 
 ChromeProcessController::ChromeProcessController(nsIWidget* aWidget,
                                                  APZEventState* aAPZEventState,
-                                                 APZCTreeManager* aAPZCTreeManager)
+                                                 IAPZCTreeManager* aAPZCTreeManager)
   : mWidget(aWidget)
   , mAPZEventState(aAPZEventState)
   , mAPZCTreeManager(aAPZCTreeManager)
   , mUILoop(MessageLoop::current())
 {
   // Otherwise we're initializing mUILoop incorrectly.
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aAPZEventState);
--- a/gfx/layers/apz/util/ChromeProcessController.h
+++ b/gfx/layers/apz/util/ChromeProcessController.h
@@ -16,29 +16,29 @@ class nsIPresShell;
 class nsIWidget;
 
 class MessageLoop;
 
 namespace mozilla {
 
 namespace layers {
 
-class APZCTreeManager;
+class IAPZCTreeManager;
 class APZEventState;
 
 // A ChromeProcessController is attached to the root of a compositor's layer
 // tree.
 class ChromeProcessController : public mozilla::layers::GeckoContentController
 {
 protected:
   typedef mozilla::layers::FrameMetrics FrameMetrics;
   typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
 
 public:
-  explicit ChromeProcessController(nsIWidget* aWidget, APZEventState* aAPZEventState, APZCTreeManager* aAPZCTreeManager);
+  explicit ChromeProcessController(nsIWidget* aWidget, APZEventState* aAPZEventState, IAPZCTreeManager* aAPZCTreeManager);
   ~ChromeProcessController();
   virtual void Destroy() override;
 
   // GeckoContentController interface
   virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) override;
   virtual void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) override;
   virtual void HandleTap(TapType aType,
                          const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
@@ -48,17 +48,17 @@ public:
                                     APZStateChange aChange,
                                     int aArg) override;
   virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
                                          const nsString& aEvent) override;
   virtual void NotifyFlushComplete() override;
 private:
   nsCOMPtr<nsIWidget> mWidget;
   RefPtr<APZEventState> mAPZEventState;
-  RefPtr<APZCTreeManager> mAPZCTreeManager;
+  RefPtr<IAPZCTreeManager> mAPZCTreeManager;
   MessageLoop* mUILoop;
 
   void InitializeRoot();
   nsIPresShell* GetPresShell() const;
   nsIDocument* GetRootDocument() const;
   nsIDocument* GetRootContentDocument(const FrameMetrics::ViewID& aScrollId) const;
   void HandleDoubleTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
                        const ScrollableLayerGuid& aGuid);
--- a/gfx/layers/ipc/RemoteContentController.cpp
+++ b/gfx/layers/ipc/RemoteContentController.cpp
@@ -7,17 +7,17 @@
 
 #include "mozilla/layers/RemoteContentController.h"
 
 #include "base/message_loop.h"
 #include "base/task.h"
 #include "MainThreadUtils.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/TabParent.h"
-#include "mozilla/layers/APZCTreeManager.h"
+#include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layout/RenderFrameParent.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/unused.h"
 #include "Units.h"
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #endif
@@ -163,104 +163,104 @@ RemoteContentController::RecvUpdateHitRe
 }
 
 bool
 RemoteContentController::RecvZoomToRect(const uint32_t& aPresShellId,
                                         const ViewID& aViewId,
                                         const CSSRect& aRect,
                                         const uint32_t& aFlags)
 {
-  if (RefPtr<APZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
+  if (RefPtr<IAPZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
     apzcTreeManager->ZoomToRect(ScrollableLayerGuid(mLayersId, aPresShellId, aViewId),
                                 aRect, aFlags);
   }
   return true;
 }
 
 bool
 RemoteContentController::RecvContentReceivedInputBlock(const ScrollableLayerGuid& aGuid,
                                                        const uint64_t& aInputBlockId,
                                                        const bool& aPreventDefault)
 {
   if (aGuid.mLayersId != mLayersId) {
     // Guard against bad data from hijacked child processes
     NS_ERROR("Unexpected layers id in RecvContentReceivedInputBlock; dropping message...");
     return false;
   }
-  if (RefPtr<APZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
+  if (RefPtr<IAPZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
     APZThreadUtils::RunOnControllerThread(NewRunnableMethod<uint64_t,
                                                             bool>(apzcTreeManager,
-                                                                  &APZCTreeManager::ContentReceivedInputBlock,
+                                                                  &IAPZCTreeManager::ContentReceivedInputBlock,
                                                                   aInputBlockId, aPreventDefault));
 
   }
   return true;
 }
 
 bool
 RemoteContentController::RecvStartScrollbarDrag(const AsyncDragMetrics& aDragMetrics)
 {
-  if (RefPtr<APZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
+  if (RefPtr<IAPZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
     ScrollableLayerGuid guid(mLayersId, aDragMetrics.mPresShellId,
                              aDragMetrics.mViewId);
 
     APZThreadUtils::RunOnControllerThread(NewRunnableMethod
                                           <ScrollableLayerGuid,
                                            AsyncDragMetrics>(apzcTreeManager,
-                                                             &APZCTreeManager::StartScrollbarDrag,
+                                                             &IAPZCTreeManager::StartScrollbarDrag,
                                                              guid, aDragMetrics));
   }
   return true;
 }
 
 bool
 RemoteContentController::RecvSetTargetAPZC(const uint64_t& aInputBlockId,
                                            nsTArray<ScrollableLayerGuid>&& aTargets)
 {
   for (size_t i = 0; i < aTargets.Length(); i++) {
     if (aTargets[i].mLayersId != mLayersId) {
       // Guard against bad data from hijacked child processes
       NS_ERROR("Unexpected layers id in SetTargetAPZC; dropping message...");
       return false;
     }
   }
-  if (RefPtr<APZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
+  if (RefPtr<IAPZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
     // need a local var to disambiguate between the SetTargetAPZC overloads.
-    void (APZCTreeManager::*setTargetApzcFunc)(uint64_t, const nsTArray<ScrollableLayerGuid>&)
-        = &APZCTreeManager::SetTargetAPZC;
+    void (IAPZCTreeManager::*setTargetApzcFunc)(uint64_t, const nsTArray<ScrollableLayerGuid>&)
+        = &IAPZCTreeManager::SetTargetAPZC;
     APZThreadUtils::RunOnControllerThread(NewRunnableMethod
                                           <uint64_t,
                                            StoreCopyPassByRRef<nsTArray<ScrollableLayerGuid>>>
                                           (apzcTreeManager, setTargetApzcFunc, aInputBlockId, aTargets));
 
   }
   return true;
 }
 
 bool
 RemoteContentController::RecvSetAllowedTouchBehavior(const uint64_t& aInputBlockId,
                                                      nsTArray<TouchBehaviorFlags>&& aFlags)
 {
-  if (RefPtr<APZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
+  if (RefPtr<IAPZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
     APZThreadUtils::RunOnControllerThread(NewRunnableMethod
                                           <uint64_t,
                                            StoreCopyPassByRRef<nsTArray<TouchBehaviorFlags>>>
                                           (apzcTreeManager,
-                                           &APZCTreeManager::SetAllowedTouchBehavior,
+                                           &IAPZCTreeManager::SetAllowedTouchBehavior,
                                            aInputBlockId, Move(aFlags)));
   }
   return true;
 }
 
 bool
 RemoteContentController::RecvUpdateZoomConstraints(const uint32_t& aPresShellId,
                                                    const ViewID& aViewId,
                                                    const MaybeZoomConstraints& aConstraints)
 {
-  if (RefPtr<APZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
+  if (RefPtr<IAPZCTreeManager> apzcTreeManager = GetApzcTreeManager()) {
     apzcTreeManager->UpdateZoomConstraints(ScrollableLayerGuid(mLayersId, aPresShellId, aViewId),
                                            aConstraints);
   }
   return true;
 }
 
 void
 RemoteContentController::ActorDestroy(ActorDestroyReason aWhy)
@@ -301,25 +301,25 @@ RemoteContentController::Destroy()
 void
 RemoteContentController::ChildAdopted()
 {
   // Clear the cached APZCTreeManager.
   MutexAutoLock lock(mMutex);
   mApzcTreeManager = nullptr;
 }
 
-already_AddRefed<APZCTreeManager>
+already_AddRefed<IAPZCTreeManager>
 RemoteContentController::GetApzcTreeManager()
 {
   // We can't get a ref to the APZCTreeManager until after the child is
   // created and the static getter knows which CompositorBridgeParent is
   // instantiated with this layers ID. That's why try to fetch it when
   // we first need it and cache the result.
   MutexAutoLock lock(mMutex);
   if (!mApzcTreeManager) {
     mApzcTreeManager = GPUProcessManager::Get()->GetAPZCTreeManagerForLayers(mLayersId);
   }
-  RefPtr<APZCTreeManager> apzcTreeManager(mApzcTreeManager);
+  RefPtr<IAPZCTreeManager> apzcTreeManager(mApzcTreeManager);
   return apzcTreeManager.forget();
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/RemoteContentController.h
+++ b/gfx/layers/ipc/RemoteContentController.h
@@ -14,17 +14,17 @@
 namespace mozilla {
 
 namespace dom {
 class TabParent;
 }
 
 namespace layers {
 
-class APZCTreeManager;
+class IAPZCTreeManager;
 
 /**
  * RemoteContentController uses the PAPZ protocol to implement a
  * GeckoContentController for a browser living in a remote process.
  * Most of the member functions can be called on any thread, exceptions are
  * annotated in comments. The PAPZ protocol runs on the main thread (so all the
  * Recv* member functions do too).
  */
@@ -93,26 +93,26 @@ public:
   virtual void ChildAdopted() override;
 
 private:
   bool CanSend()
   {
     MOZ_ASSERT(NS_IsMainThread());
     return !!mBrowserParent;
   }
-  already_AddRefed<APZCTreeManager> GetApzcTreeManager();
+  already_AddRefed<IAPZCTreeManager> GetApzcTreeManager();
 
   MessageLoop* mUILoop;
   uint64_t mLayersId;
   RefPtr<dom::TabParent> mBrowserParent;
 
   // Mutex protecting members below accessed from multiple threads.
   mozilla::Mutex mMutex;
 
-  RefPtr<APZCTreeManager> mApzcTreeManager;
+  RefPtr<IAPZCTreeManager> mApzcTreeManager;
   nsRegion mTouchSensitiveRegion;
 };
 
 } // namespace layers
 
 } // namespace mozilla
 
 #endif // mozilla_layers_RemoteContentController_h
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -93,16 +93,17 @@ EXPORTS.gfxipc += [
 ]
 
 EXPORTS.mozilla.dom += [
     'apz/util/CheckerboardReportService.h',
 ]
 
 EXPORTS.mozilla.layers += [
     'apz/public/GeckoContentController.h',
+    'apz/public/IAPZCTreeManager.h',
     # exporting things from apz/src is temporary until we extract a
     # proper interface for the code there
     'apz/src/APZCTreeManager.h',
     'apz/src/APZUtils.h',
     'apz/src/AsyncDragMetrics.h',
     'apz/src/AsyncPanZoomAnimation.h',
     'apz/src/TouchCounter.h',
     'apz/testutil/APZTestData.h',
@@ -257,16 +258,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk
     ]
 
 if CONFIG['MOZ_ANDROID_APZ']:
     UNIFIED_SOURCES += [
         'apz/src/AndroidAPZ.cpp',
     ]
 
 UNIFIED_SOURCES += [
+    'apz/public/IAPZCTreeManager.cpp',
     'apz/src/APZCTreeManager.cpp',
     'apz/src/AsyncPanZoomController.cpp',
     'apz/src/Axis.cpp',
     'apz/src/CheckerboardEvent.cpp',
     'apz/src/DragTracker.cpp',
     'apz/src/GestureEventListener.cpp',
     'apz/src/HitTestingTreeNode.cpp',
     'apz/src/InputBlockState.cpp',
--- a/widget/android/AndroidContentController.cpp
+++ b/widget/android/AndroidContentController.cpp
@@ -3,44 +3,44 @@
  * 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 "AndroidContentController.h"
 
 #include "AndroidBridge.h"
 #include "base/message_loop.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
-#include "mozilla/layers/APZCTreeManager.h"
+#include "mozilla/layers/IAPZCTreeManager.h"
 #include "nsIObserverService.h"
 #include "nsLayoutUtils.h"
 #include "nsWindow.h"
 
-using mozilla::layers::APZCTreeManager;
+using mozilla::layers::IAPZCTreeManager;
 
 namespace mozilla {
 namespace widget {
 
 void
 AndroidContentController::Destroy()
 {
     mAndroidWindow = nullptr;
     ChromeProcessController::Destroy();
 }
 
 void
-AndroidContentController::NotifyDefaultPrevented(APZCTreeManager* aManager,
+AndroidContentController::NotifyDefaultPrevented(IAPZCTreeManager* aManager,
                                                  uint64_t aInputBlockId,
                                                  bool aDefaultPrevented)
 {
     if (!AndroidBridge::IsJavaUiThread()) {
         // The notification must reach the APZ on the Java UI thread (aka the
         // APZ "controller" thread) but we get it from the Gecko thread, so we
         // have to throw it onto the other thread.
         AndroidBridge::Bridge()->PostTaskToUiThread(NewRunnableMethod<uint64_t, bool>(
-            aManager, &APZCTreeManager::ContentReceivedInputBlock,
+            aManager, &IAPZCTreeManager::ContentReceivedInputBlock,
             aInputBlockId, aDefaultPrevented), 0);
         return;
     }
 
     aManager->ContentReceivedInputBlock(aInputBlockId, aDefaultPrevented);
 }
 
 void
--- a/widget/android/AndroidContentController.h
+++ b/widget/android/AndroidContentController.h
@@ -12,44 +12,44 @@
 #include "mozilla/TimeStamp.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsTArray.h"
 #include "nsWindow.h"
 
 namespace mozilla {
 namespace layers {
 class APZEventState;
-class APZCTreeManager;
+class IAPZCTreeManager;
 }
 namespace widget {
 
 class AndroidContentController final
     : public mozilla::layers::ChromeProcessController
 {
 public:
     AndroidContentController(nsWindow* aWindow,
                              mozilla::layers::APZEventState* aAPZEventState,
-                             mozilla::layers::APZCTreeManager* aAPZCTreeManager)
+                             mozilla::layers::IAPZCTreeManager* aAPZCTreeManager)
       : mozilla::layers::ChromeProcessController(aWindow, aAPZEventState, aAPZCTreeManager)
       , mAndroidWindow(aWindow)
     {}
 
     // ChromeProcessController methods
     virtual void Destroy() override;
     void HandleTap(TapType aType, const CSSPoint& aPoint, Modifiers aModifiers,
                    const ScrollableLayerGuid& aGuid, uint64_t aInputBlockId) override;
     void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) override;
     void UpdateOverscrollVelocity(const float aX, const float aY) override;
     void UpdateOverscrollOffset(const float aX, const float aY) override;
     void SetScrollingRootContent(const bool isRootContent) override;
     void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                               APZStateChange aChange,
                               int aArg) override;
 
-    static void NotifyDefaultPrevented(mozilla::layers::APZCTreeManager* aManager,
+    static void NotifyDefaultPrevented(mozilla::layers::IAPZCTreeManager* aManager,
                                        uint64_t aInputBlockId, bool aDefaultPrevented);
 private:
     nsWindow* mAndroidWindow;
 };
 
 } // namespace widget
 } // namespace mozilla
 
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -53,19 +53,19 @@ using mozilla::Unused;
 #include "nsWidgetsCID.h"
 #include "nsGfxCIID.h"
 
 #include "gfxContext.h"
 
 #include "Layers.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/AsyncCompositionManager.h"
-#include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/APZEventState.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"
 
 #include "nsTArray.h"
 
@@ -467,17 +467,17 @@ public:
         MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
 
         MutexAutoLock lock(mWindowLock);
         if (!mWindow) {
             // We already shut down.
             return;
         }
 
-        RefPtr<APZCTreeManager> controller = mWindow->mAPZC;
+        RefPtr<IAPZCTreeManager> controller = mWindow->mAPZC;
         RefPtr<CompositorBridgeParent> compositor = mWindow->GetCompositorBridgeParent();
         if (controller && compositor) {
             // TODO: Pass in correct values for presShellId and viewId.
             controller->CancelAnimation(ScrollableLayerGuid(
                     compositor->RootLayerTreeId(), 0, 0));
         }
     }
 
@@ -486,43 +486,46 @@ public:
         MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
 
         MutexAutoLock lock(mWindowLock);
         if (!mWindow) {
             // We already shut down.
             return;
         }
 
-        RefPtr<APZCTreeManager> controller = mWindow->mAPZC;
+        RefPtr<IAPZCTreeManager> controller = mWindow->mAPZC;
         if (controller) {
             controller->AdjustScrollForSurfaceShift(
                 ScreenPoint(aX, aY));
         }
     }
 
     void SetIsLongpressEnabled(bool aIsLongpressEnabled)
     {
         MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
 
-        APZCTreeManager::SetLongTapEnabled(aIsLongpressEnabled);
+        RefPtr<IAPZCTreeManager> controller = mWindow->mAPZC;
+        if (controller) {
+            controller->SetLongTapEnabled(aIsLongpressEnabled);
+        }
     }
 
     bool HandleScrollEvent(int64_t aTime, int32_t aMetaState,
                            float aX, float aY,
                            float aHScroll, float aVScroll)
     {
         MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
 
         MutexAutoLock lock(mWindowLock);
         if (!mWindow) {
             // We already shut down.
             return false;
         }
 
-        RefPtr<APZCTreeManager> controller = mWindow->mAPZC;
+        RefPtr<IAPZCTreeManager> controller = mWindow->mAPZC;
         if (!controller) {
             return false;
         }
 
         ScreenPoint origin = ScreenPoint(aX, aY);
 
         ScrollWheelInput input(aTime, TimeStamp::Now(), GetModifiers(aMetaState),
                                ScrollWheelInput::SCROLLMODE_SMOOTH,
@@ -612,17 +615,17 @@ public:
         MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
 
         MutexAutoLock lock(mWindowLock);
         if (!mWindow) {
             // We already shut down.
             return false;
         }
 
-        RefPtr<APZCTreeManager> controller = mWindow->mAPZC;
+        RefPtr<IAPZCTreeManager> controller = mWindow->mAPZC;
         if (!controller) {
             return false;
         }
 
         MouseInput::MouseType mouseType = MouseInput::MOUSE_NONE;
         MouseInput::ButtonType buttonType = MouseInput::NONE;
         switch (aAction) {
             case AndroidMotionEvent::ACTION_DOWN:
@@ -705,17 +708,17 @@ public:
         MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
 
         MutexAutoLock lock(mWindowLock);
         if (!mWindow) {
             // We already shut down.
             return false;
         }
 
-        RefPtr<APZCTreeManager> controller = mWindow->mAPZC;
+        RefPtr<IAPZCTreeManager> controller = mWindow->mAPZC;
         if (!controller) {
             return false;
         }
 
         nsTArray<int32_t> pointerId(aPointerId->GetElements());
         MultiTouchInput::MultiTouchType type;
         size_t startIndex = 0;
         size_t endIndex = pointerId.Length();
@@ -827,17 +830,17 @@ public:
                                                  blockId, status);
             window->DispatchHitTest(touchEvent);
         });
         return true;
     }
 
     void HandleMotionEventVelocity(int64_t aTime, float aSpeedY)
     {
-        RefPtr<APZCTreeManager> controller = mWindow->mAPZC;
+        RefPtr<IAPZCTreeManager> controller = mWindow->mAPZC;
         if (controller) {
             controller->ProcessTouchVelocity((uint32_t)aTime, aSpeedY);
         }
     }
 
     void UpdateOverscrollVelocity(const float x, const float y)
     {
         mNPZC->UpdateOverscrollVelocity(x, y);
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -44,17 +44,17 @@ class GLPresenter;
 namespace mozilla {
 class InputData;
 class PanGestureInput;
 class SwipeTracker;
 struct SwipeEventQueue;
 class VibrancyManager;
 namespace layers {
 class GLManager;
-class APZCTreeManager;
+class IAPZCTreeManager;
 } // namespace layers
 namespace widget {
 class RectTextureImage;
 } // namespace widget
 } // namespace mozilla
 
 @interface NSEvent (Undocumented)
 
@@ -287,17 +287,17 @@ public:
 // nsChildView
 //
 //-------------------------------------------------------------------------
 
 class nsChildView : public nsBaseWidget
 {
 private:
   typedef nsBaseWidget Inherited;
-  typedef mozilla::layers::APZCTreeManager APZCTreeManager;
+  typedef mozilla::layers::IAPZCTreeManager IAPZCTreeManager;
 
 public:
   nsChildView();
 
   // nsIWidget interface
   NS_IMETHOD              Create(nsIWidget* aParent,
                                  nsNativeWidget aNativeParent,
                                  const LayoutDeviceIntRect& aRect,
@@ -417,17 +417,17 @@ public:
                                                     double aDeltaX,
                                                     double aDeltaY,
                                                     double aDeltaZ,
                                                     uint32_t aModifierFlags,
                                                     uint32_t aAdditionalFlags,
                                                     nsIObserver* aObserver) override;
 
   // Mac specific methods
-  
+
   virtual bool      DispatchWindowEvent(mozilla::WidgetGUIEvent& event);
 
   void WillPaintWindow();
   bool PaintWindow(LayoutDeviceIntRegion aRegion);
   bool PaintWindowInContext(CGContextRef aContext, const LayoutDeviceIntRegion& aRegion,
                             mozilla::gfx::IntSize aSurfaceSize);
 
 #ifdef ACCESSIBILITY
@@ -495,17 +495,17 @@ public:
 
   already_AddRefed<mozilla::gfx::DrawTarget>
     StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
                                mozilla::layers::BufferMode* aBufferMode) override;
   void EndRemoteDrawing() override;
   void CleanupRemoteDrawing() override;
   bool InitCompositor(mozilla::layers::Compositor* aCompositor) override;
 
-  APZCTreeManager* APZCTM() { return mAPZC ; }
+  IAPZCTreeManager* APZCTM() { return mAPZC ; }
 
   NS_IMETHOD StartPluginIME(const mozilla::WidgetKeyboardEvent& aKeyboardEvent,
                             int32_t aPanelX, int32_t aPanelY,
                             nsString& aCommitted) override;
 
   NS_IMETHOD SetPluginFocused(bool& aFocused) override;
 
   bool IsPluginFocused() { return mPluginFocused; }
@@ -570,17 +570,17 @@ protected:
   NSView<mozView>*      mView;      // my parallel cocoa view (ChildView or NativeScrollbarView), [STRONG]
   RefPtr<mozilla::widget::TextInputHandler> mTextInputHandler;
   InputContext          mInputContext;
 
   NSView<mozView>*      mParentView;
   nsIWidget*            mParentWidget;
 
 #ifdef ACCESSIBILITY
-  // weak ref to this childview's associated mozAccessible for speed reasons 
+  // weak ref to this childview's associated mozAccessible for speed reasons
   // (we get queried for it *a lot* but don't want to own it)
   nsWeakPtr             mAccessible;
 #endif
 
   // Protects the view from being teared down while a composition is in
   // progress on the compositor thread.
   mozilla::Mutex mViewTearDownLock;
 
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -54,17 +54,17 @@
 #include "ClientLayerManager.h"
 #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/APZCTreeManager.h"
+#include "mozilla/layers/IAPZCTreeManager.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 "gfxUtils.h"
 #include "gfxPrefs.h"
@@ -193,17 +193,17 @@ static uint32_t gNumberOfWidgetsNeedingE
 - (void)clickHoldCallback:(id)inEvent;
 #endif
 
 #ifdef ACCESSIBILITY
 - (id<mozAccessible>)accessible;
 #endif
 
 - (LayoutDeviceIntPoint)convertWindowCoordinates:(NSPoint)aPoint;
-- (APZCTreeManager*)apzctm;
+- (IAPZCTreeManager*)apzctm;
 
 - (BOOL)inactiveWindowAcceptsMouseEvent:(NSEvent*)aEvent;
 - (void)updateWindowDraggableState;
 
 - (bool)shouldConsiderStartingSwipeFromEvent:(NSEvent*)aEvent;
 
 @end
 
@@ -4865,17 +4865,17 @@ PanGestureTypeForEvent(NSEvent* aEvent)
     mGeckoChild->DispatchAPZWheelInputEvent(wheelEvent, false);
   }
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 - (void)handleAsyncScrollEvent:(CGEventRef)cgEvent ofType:(CGEventType)type
 {
-  APZCTreeManager* apzctm = [self apzctm];
+  IAPZCTreeManager* apzctm = [self apzctm];
   if (!apzctm) {
     return;
   }
 
   CGPoint loc = CGEventGetLocation(cgEvent);
   loc.y = nsCocoaUtils::FlippedScreenY(loc.y);
   NSPoint locationInWindow =
     nsCocoaUtils::ConvertPointFromScreen([self window], NSPointFromCGPoint(loc));
@@ -5513,17 +5513,17 @@ PanGestureTypeForEvent(NSEvent* aEvent)
   if (!mGeckoChild) {
     return LayoutDeviceIntPoint(0, 0);
   }
 
   NSPoint localPoint = [self convertPoint:aPoint fromView:nil];
   return mGeckoChild->CocoaPointsToDevPixels(localPoint);
 }
 
-- (APZCTreeManager*)apzctm
+- (IAPZCTreeManager*)apzctm
 {
   return mGeckoChild ? mGeckoChild->APZCTM() : nullptr;
 }
 
 // This is a utility function used by NSView drag event methods
 // to send events. It contains all of the logic needed for Gecko
 // dragging to work. Returns the appropriate cocoa drag operation code.
 - (NSDragOperation)doDragAction:(EventMessage)aMessage sender:(id)aSender
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -45,17 +45,17 @@
 #include "nsContentUtils.h"
 #include "gfxPrefs.h"
 #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/APZCTreeManager.h"
+#include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/APZEventState.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/ChromeProcessController.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/gfx/GPUProcessManager.h"
@@ -989,40 +989,40 @@ nsBaseWidget::CreateRootContentControlle
 void nsBaseWidget::ConfigureAPZCTreeManager()
 {
   MOZ_ASSERT(mAPZC);
 
   ConfigureAPZControllerThread();
 
   mAPZC->SetDPI(GetDPI());
 
-  RefPtr<APZCTreeManager> treeManager = mAPZC;  // for capture by the lambdas
+  RefPtr<IAPZCTreeManager> treeManager = mAPZC;  // for capture by the lambdas
 
   ContentReceivedInputBlockCallback callback(
       [treeManager](const ScrollableLayerGuid& aGuid,
                     uint64_t aInputBlockId,
                     bool aPreventDefault)
       {
         MOZ_ASSERT(NS_IsMainThread());
         APZThreadUtils::RunOnControllerThread(NewRunnableMethod
                                               <uint64_t, bool>(treeManager,
-                                                               &APZCTreeManager::ContentReceivedInputBlock,
+                                                               &IAPZCTreeManager::ContentReceivedInputBlock,
                                                                aInputBlockId,
                                                                aPreventDefault));
       });
   mAPZEventState = new APZEventState(this, mozilla::Move(callback));
 
   mSetAllowedTouchBehaviorCallback = [treeManager](uint64_t aInputBlockId,
                                                    const nsTArray<TouchBehaviorFlags>& aFlags)
   {
     MOZ_ASSERT(NS_IsMainThread());
     APZThreadUtils::RunOnControllerThread(NewRunnableMethod
       <uint64_t,
        StoreCopyPassByLRef<nsTArray<TouchBehaviorFlags>>>(treeManager,
-                                                          &APZCTreeManager::SetAllowedTouchBehavior,
+                                                          &IAPZCTreeManager::SetAllowedTouchBehavior,
                                                           aInputBlockId, aFlags));
   };
 
   mRootContentController = CreateRootContentController();
   if (mRootContentController) {
     mCompositorSession->SetContentController(mRootContentController);
   }
 
@@ -1041,18 +1041,18 @@ void nsBaseWidget::ConfigureAPZControlle
   APZThreadUtils::SetControllerThread(MessageLoop::current());
 }
 
 void
 nsBaseWidget::SetConfirmedTargetAPZC(uint64_t aInputBlockId,
                                      const nsTArray<ScrollableLayerGuid>& aTargets) const
 {
   // Need to specifically bind this since it's overloaded.
-  void (APZCTreeManager::*setTargetApzcFunc)(uint64_t, const nsTArray<ScrollableLayerGuid>&)
-          = &APZCTreeManager::SetTargetAPZC;
+  void (IAPZCTreeManager::*setTargetApzcFunc)(uint64_t, const nsTArray<ScrollableLayerGuid>&)
+          = &IAPZCTreeManager::SetTargetAPZC;
   APZThreadUtils::RunOnControllerThread(NewRunnableMethod
     <uint64_t, StoreCopyPassByRRef<nsTArray<ScrollableLayerGuid>>>(mAPZC,
                                                                    setTargetApzcFunc,
                                                                    aInputBlockId, aTargets));
 }
 
 void
 nsBaseWidget::UpdateZoomConstraints(const uint32_t& aPresShellId,
@@ -1178,17 +1178,17 @@ private:
   uint64_t mInputBlockId;
   ScrollableLayerGuid mGuid;
 };
 
 class DispatchWheelInputOnControllerThread : public Runnable
 {
 public:
   DispatchWheelInputOnControllerThread(const WidgetWheelEvent& aWheelEvent,
-                                       APZCTreeManager* aAPZC,
+                                       IAPZCTreeManager* aAPZC,
                                        nsBaseWidget* aWidget)
     : mMainMessageLoop(MessageLoop::current())
     , mWheelInput(aWheelEvent)
     , mAPZC(aAPZC)
     , mWidget(aWidget)
     , mInputBlockId(0)
   {
   }
@@ -1202,17 +1202,17 @@ public:
     RefPtr<Runnable> r = new DispatchWheelEventOnMainThread(mWheelInput, mWidget, mAPZResult, mInputBlockId, mGuid);
     mMainMessageLoop->PostTask(r.forget());
     return NS_OK;
   }
 
 private:
   MessageLoop* mMainMessageLoop;
   ScrollWheelInput mWheelInput;
-  RefPtr<APZCTreeManager> mAPZC;
+  RefPtr<IAPZCTreeManager> mAPZC;
   nsBaseWidget* mWidget;
   nsEventStatus mAPZResult;
   uint64_t mInputBlockId;
   ScrollableLayerGuid mGuid;
 };
 
 nsEventStatus
 nsBaseWidget::DispatchInputEvent(WidgetInputEvent* aEvent)
@@ -1306,30 +1306,34 @@ void nsBaseWidget::CreateCompositor(int 
   if (!mShutdownObserver) {
     return;
   }
 
   CreateCompositorVsyncDispatcher();
 
   RefPtr<ClientLayerManager> lm = new ClientLayerManager(this);
 
+  bool useAPZ = UseAPZ();
+
   gfx::GPUProcessManager* gpu = gfx::GPUProcessManager::Get();
   mCompositorSession = gpu->CreateTopLevelCompositor(
     this,
     lm,
     GetDefaultScale(),
-    UseAPZ(),
+    useAPZ,
     UseExternalCompositingSurface(),
     gfx::IntSize(aWidth, aHeight));
   mCompositorBridgeChild = mCompositorSession->GetCompositorBridgeChild();
   mCompositorWidgetDelegate = mCompositorSession->GetCompositorWidgetDelegate();
 
-  mAPZC = mCompositorSession->GetAPZCTreeManager();
-  if (mAPZC) {
+  if (useAPZ) {
+    mAPZC = mCompositorSession->GetAPZCTreeManager();
     ConfigureAPZCTreeManager();
+  } else {
+    mAPZC = nullptr;
   }
 
   if (mInitialZoomConstraints) {
     UpdateZoomConstraints(mInitialZoomConstraints->mPresShellID,
                           mInitialZoomConstraints->mViewID,
                           Some(mInitialZoomConstraints->mConstraints));
     mInitialZoomConstraints.reset();
   }
@@ -1934,17 +1938,17 @@ nsBaseWidget::StartAsyncScrollbarDrag(co
 
   MOZ_ASSERT(XRE_IsParentProcess() && mCompositorSession);
 
   int layersId = mCompositorSession->RootLayerTreeId();;
   ScrollableLayerGuid guid(layersId, aDragMetrics.mPresShellId, aDragMetrics.mViewId);
 
   APZThreadUtils::RunOnControllerThread(NewRunnableMethod
     <ScrollableLayerGuid, AsyncDragMetrics>(mAPZC,
-                                            &APZCTreeManager::StartScrollbarDrag,
+                                            &IAPZCTreeManager::StartScrollbarDrag,
                                             guid, aDragMetrics));
 }
 
 already_AddRefed<nsIScreen>
 nsBaseWidget::GetWidgetScreen()
 {
   nsCOMPtr<nsIScreenManager> screenManager;
   screenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -46,17 +46,17 @@ namespace gfx {
 class DrawTarget;
 class SourceSurface;
 } // namespace gfx
 
 namespace layers {
 class BasicLayerManager;
 class CompositorBridgeChild;
 class CompositorBridgeParent;
-class APZCTreeManager;
+class IAPZCTreeManager;
 class GeckoContentController;
 class APZEventState;
 class CompositorSession;
 class ImageContainer;
 struct ScrollableLayerGuid;
 } // namespace layers
 
 namespace widget {
@@ -114,17 +114,17 @@ class nsBaseWidget : public nsIWidget, p
 protected:
   typedef base::Thread Thread;
   typedef mozilla::gfx::DrawTarget DrawTarget;
   typedef mozilla::gfx::SourceSurface SourceSurface;
   typedef mozilla::layers::BasicLayerManager BasicLayerManager;
   typedef mozilla::layers::BufferMode BufferMode;
   typedef mozilla::layers::CompositorBridgeChild CompositorBridgeChild;
   typedef mozilla::layers::CompositorBridgeParent CompositorBridgeParent;
-  typedef mozilla::layers::APZCTreeManager APZCTreeManager;
+  typedef mozilla::layers::IAPZCTreeManager IAPZCTreeManager;
   typedef mozilla::layers::GeckoContentController GeckoContentController;
   typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
   typedef mozilla::layers::APZEventState APZEventState;
   typedef mozilla::layers::SetAllowedTouchBehaviorCallback SetAllowedTouchBehaviorCallback;
   typedef mozilla::CSSIntRect CSSIntRect;
   typedef mozilla::CSSRect CSSRect;
   typedef mozilla::ScreenRotation ScreenRotation;
   typedef mozilla::widget::CompositorWidgetDelegate CompositorWidgetDelegate;
@@ -604,17 +604,17 @@ protected:
 
   nsIWidgetListener* mWidgetListener;
   nsIWidgetListener* mAttachedWidgetListener;
   nsIWidgetListener* mPreviouslyAttachedWidgetListener;
   RefPtr<LayerManager> mLayerManager;
   RefPtr<CompositorSession> mCompositorSession;
   RefPtr<CompositorBridgeChild> mCompositorBridgeChild;
   RefPtr<mozilla::CompositorVsyncDispatcher> mCompositorVsyncDispatcher;
-  RefPtr<APZCTreeManager> mAPZC;
+  RefPtr<IAPZCTreeManager> mAPZC;
   RefPtr<GeckoContentController> mRootContentController;
   RefPtr<APZEventState> mAPZEventState;
   SetAllowedTouchBehaviorCallback mSetAllowedTouchBehaviorCallback;
   RefPtr<WidgetShutdownObserver> mShutdownObserver;
   RefPtr<TextEventDispatcher> mTextEventDispatcher;
   nsCursor          mCursor;
   nsBorderStyle     mBorderStyle;
   LayoutDeviceIntRect mBounds;