Bug 1289650 - Convert APZChild into a wrapper around GeckoContentController. r?kats draft
authorRyan Hunt <rhunt@mozilla.com>
Wed, 10 Aug 2016 16:51:45 -0700
changeset 404718 86f582c354fed97448f139088a40521608084a21
parent 404717 d9d3ee883bb8c2d0aaa1884f19ab96537bb3e265
child 529242 38d46a6e7e4dbe18ab2ac19a20daec96952b3b18
push id27272
push userbmo:rhunt@mozilla.com
push dateTue, 23 Aug 2016 22:55:33 +0000
reviewerskats
bugs1289650
milestone51.0a1
Bug 1289650 - Convert APZChild into a wrapper around GeckoContentController. r?kats MozReview-Commit-ID: L7ZG7EWKWEo
dom/ipc/ContentChild.cpp
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
gfx/layers/apz/util/ContentProcessController.cpp
gfx/layers/apz/util/ContentProcessController.h
gfx/layers/ipc/APZChild.cpp
gfx/layers/ipc/APZChild.h
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/PAPZ.ipdl
gfx/layers/ipc/RemoteContentController.cpp
gfx/layers/ipc/RemoteContentController.h
gfx/layers/ipc/SharedBufferManagerParent.cpp
gfx/layers/moz.build
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -43,16 +43,17 @@
 #include "mozilla/ipc/FileDescriptorUtils.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/ipc/ProcessChild.h"
 #include "mozilla/ipc/PSendStreamChild.h"
 #include "mozilla/ipc/TestShellChild.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
 #include "mozilla/layers/APZChild.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
+#include "mozilla/layers/ContentProcessController.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/SharedBufferManagerChild.h"
 #include "mozilla/layout/RenderFrameChild.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/plugins/PluginInstanceParent.h"
 #include "mozilla/plugins/PluginModuleParent.h"
 #include "mozilla/widget/WidgetMessageUtils.h"
 #include "nsBaseDragService.h"
@@ -1376,17 +1377,17 @@ ContentChild::RecvSetProcessSandbox(cons
 #endif /* MOZ_CONTENT_SANDBOX */
 
   return true;
 }
 
 bool
 ContentChild::RecvNotifyLayerAllocated(const dom::TabId& aTabId, const uint64_t& aLayersId)
 {
-  APZChild* apz = APZChild::Create(aTabId);
+  APZChild* apz = ContentProcessController::Create(aTabId);
   return CompositorBridgeChild::Get()->SendPAPZConstructor(apz, aLayersId);
 }
 
 bool
 ContentChild::RecvSpeakerManagerNotify()
 {
 #ifdef MOZ_WIDGET_GONK
   // Only notify the process which has the SpeakerManager instance.
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -665,21 +665,16 @@ child:
      * @see nsIDOMWindowUtils sendKeyEvent.
      */
     async KeyEvent(nsString aType,
                    int32_t aKeyCode,
                    int32_t aCharCode,
                    int32_t aModifiers,
                    bool aPreventDefault);
 
-    /**
-     * APZ notification for mouse scroll testing events.
-     */
-    async MouseScrollTestEvent(uint64_t aLayersId, ViewID aScrollId, nsString aEvent);
-
     async CompositionEvent(WidgetCompositionEvent event);
 
     async SelectionEvent(WidgetSelectionEvent event);
 
     /**
      * Activate event forwarding from client to parent.
      */
     async ActivateFrameEvent(nsString aType, bool capture);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -24,16 +24,17 @@
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/ipc/DocumentRendererChild.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
 #include "mozilla/layers/APZChild.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/APZEventState.h"
+#include "mozilla/layers/ContentProcessController.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/DoubleTapToZoom.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layout/RenderFrameChild.h"
 #include "mozilla/layout/RenderFrameParent.h"
 #include "mozilla/LookAndFeel.h"
@@ -1934,36 +1935,16 @@ TabChild::RecvMouseWheelEvent(const Widg
 
   if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
     mAPZEventState->ProcessWheelEvent(localEvent, aGuid, aInputBlockId);
   }
   return true;
 }
 
 bool
-TabChild::RecvMouseScrollTestEvent(const uint64_t& aLayersId,
-                                   const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
-{
-  if (aLayersId != mLayersId) {
-    RefPtr<TabParent> browser = TabParent::GetTabParentFromLayersId(aLayersId);
-    if (!browser) {
-      return false;
-    }
-    NS_DispatchToMainThread(NS_NewRunnableFunction(
-      [aLayersId, browser, aScrollId, aEvent] () -> void {
-        Unused << browser->SendMouseScrollTestEvent(aLayersId, aScrollId, aEvent);
-      }));
-    return true;
-  }
-
-  APZCCallbackHelper::NotifyMozMouseScrollEvent(aScrollId, aEvent);
-  return true;
-}
-
-bool
 TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
                              const ScrollableLayerGuid& aGuid,
                              const uint64_t& aInputBlockId,
                              const nsEventStatus& aApzResponse)
 {
   TABC_LOG("Receiving touch event of type %d\n", aEvent.mMessage);
 
   WidgetTouchEvent localEvent(aEvent);
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -383,20 +383,16 @@ public:
                          const nsEventStatus& aApzResponse) override;
 
   virtual bool RecvKeyEvent(const nsString& aType,
                             const int32_t& aKeyCode,
                             const int32_t& aCharCode,
                             const int32_t& aModifiers,
                             const bool& aPreventDefault) override;
 
-  virtual bool RecvMouseScrollTestEvent(const uint64_t& aLayersId,
-                                        const FrameMetrics::ViewID& aScrollId,
-                                        const nsString& aEvent) override;
-
   virtual bool RecvNativeSynthesisResponse(const uint64_t& aObserverId,
                                            const nsCString& aResponse) override;
 
   virtual bool RecvPluginEvent(const WidgetPluginEvent& aEvent) override;
 
   virtual bool
   RecvCompositionEvent(const mozilla::WidgetCompositionEvent& aEvent) override;
 
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/util/ContentProcessController.cpp
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=4 ts=8 et 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 "ContentProcessController.h"
+
+#include "mozilla/dom/TabChild.h"
+#include "mozilla/layers/APZCCallbackHelper.h"
+#include "mozilla/layers/APZChild.h"
+
+#include "InputData.h"                  // for InputData
+
+namespace mozilla {
+namespace layers {
+
+/**
+ * There are cases where we try to create the APZChild before the corresponding
+ * TabChild has been created, we use an observer for the "tab-child-created"
+ * topic to set the TabChild in the APZChild when it has been created.
+ */
+class TabChildCreatedObserver : public nsIObserver
+{
+public:
+  TabChildCreatedObserver(ContentProcessController* aController, const dom::TabId& aTabId)
+    : mController(aController),
+      mTabId(aTabId)
+  {}
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIOBSERVER
+
+private:
+  virtual ~TabChildCreatedObserver()
+  {}
+
+  // TabChildCreatedObserver is owned by mController, and mController outlives its
+  // TabChildCreatedObserver, so the raw pointer is fine.
+  ContentProcessController* mController;
+  dom::TabId mTabId;
+};
+
+NS_IMPL_ISUPPORTS(TabChildCreatedObserver, nsIObserver)
+
+NS_IMETHODIMP
+TabChildCreatedObserver::Observe(nsISupports* aSubject,
+                                 const char* aTopic,
+                                 const char16_t* aData)
+{
+  MOZ_ASSERT(strcmp(aTopic, "tab-child-created") == 0);
+
+  nsCOMPtr<nsITabChild> tabChild(do_QueryInterface(aSubject));
+  NS_ENSURE_TRUE(tabChild, NS_ERROR_FAILURE);
+
+  dom::TabChild* browser = static_cast<dom::TabChild*>(tabChild.get());
+
+  if (browser->GetTabId() == mTabId) {
+    mController->SetBrowser(browser);
+  }
+  return NS_OK;
+}
+
+APZChild*
+ContentProcessController::Create(const dom::TabId& aTabId)
+{
+  RefPtr<dom::TabChild> browser = dom::TabChild::FindTabChild(aTabId);
+
+  ContentProcessController* controller = new ContentProcessController();
+
+  nsAutoPtr<APZChild> apz(new APZChild(controller));
+
+  if (browser) {
+
+    controller->SetBrowser(browser);
+
+  } else {
+
+    RefPtr<TabChildCreatedObserver> observer =
+      new TabChildCreatedObserver(controller, aTabId);
+    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
+    if (!os ||
+        NS_FAILED(os->AddObserver(observer, "tab-child-created", false))) {
+      return nullptr;
+    }
+    controller->SetObserver(observer);
+
+  }
+
+  return apz.forget();
+}
+
+ContentProcessController::ContentProcessController()
+    : mBrowser(nullptr)
+{
+}
+ContentProcessController::~ContentProcessController()
+{
+  if (mObserver) {
+    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
+    os->RemoveObserver(mObserver, "tab-child-created");
+  } else if (mBrowser) {
+    mBrowser->SetAPZChild(nullptr);
+  }
+}
+
+void
+ContentProcessController::SetObserver(nsIObserver* aObserver)
+{
+  MOZ_ASSERT(!mBrowser);
+  mObserver = aObserver;
+}
+
+void
+ContentProcessController::SetBrowser(dom::TabChild* aBrowser)
+{
+  MOZ_ASSERT(!mBrowser);
+  mBrowser = aBrowser;
+
+  if (mObserver) {
+    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
+    os->RemoveObserver(mObserver, "tab-child-created");
+    mObserver = nullptr;
+  }
+}
+void
+ContentProcessController::RequestContentRepaint(const FrameMetrics& aFrameMetrics)
+{
+  if (mBrowser) {
+    mBrowser->UpdateFrame(aFrameMetrics);
+  }
+}
+
+void
+ContentProcessController::HandleTap(
+                        TapType aType,
+                        const LayoutDevicePoint& aPoint,
+                        Modifiers aModifiers,
+                        const ScrollableLayerGuid& aGuid,
+                        uint64_t aInputBlockId)
+{
+  if (mBrowser) {
+    mBrowser->HandleTap(aType, aPoint - mBrowser->GetChromeDisplacement(), aModifiers, aGuid,
+        aInputBlockId, (aType == TapType::eSingleTap));
+  }
+}
+
+void
+ContentProcessController::NotifyAPZStateChange(
+                                  const ScrollableLayerGuid& aGuid,
+                                  APZStateChange aChange,
+                                  int aArg)
+{
+  if (mBrowser) {
+    mBrowser->NotifyAPZStateChange(aGuid.mScrollId, aChange, aArg);
+  }
+}
+
+void
+ContentProcessController::NotifyMozMouseScrollEvent(
+                                  const FrameMetrics::ViewID& aScrollId,
+                                  const nsString& aEvent)
+{
+  if (mBrowser) {
+    APZCCallbackHelper::NotifyMozMouseScrollEvent(aScrollId, aEvent);
+  }
+}
+
+void
+ContentProcessController::NotifyFlushComplete()
+{
+  if (mBrowser) {
+    nsCOMPtr<nsIPresShell> shell;
+    if (nsCOMPtr<nsIDocument> doc = mBrowser->GetDocument()) {
+      shell = doc->GetShell();
+    }
+    APZCCallbackHelper::NotifyFlushComplete(shell.get());
+  }
+}
+
+void
+ContentProcessController::PostDelayedTask(already_AddRefed<Runnable> aRunnable, int aDelayMs)
+{
+  MOZ_ASSERT_UNREACHABLE("ContentProcessController should only be used remotely.");
+}
+
+bool
+ContentProcessController::IsRepaintThread()
+{
+  return NS_IsMainThread();
+}
+
+void
+ContentProcessController::DispatchToRepaintThread(already_AddRefed<Runnable> aTask)
+{
+  NS_DispatchToMainThread(Move(aTask));
+}
+
+} // namespace layers
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/util/ContentProcessController.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=4 ts=8 et 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_ContentProcessController_h
+#define mozilla_layers_ContentProcessController_h
+
+#include "mozilla/layers/GeckoContentController.h"
+
+class nsIObserver;
+
+namespace mozilla {
+
+namespace dom {
+class TabChild;
+} // namespace dom
+
+namespace layers {
+
+class APZChild;
+
+class ContentProcessController final
+      : public GeckoContentController
+{
+public:
+  ~ContentProcessController();
+
+  static APZChild* Create(const dom::TabId& aTabId);
+
+  // ContentProcessController
+
+  void SetBrowser(dom::TabChild* aBrowser);
+
+  // GeckoContentController
+
+  void RequestContentRepaint(const FrameMetrics& frame) override;
+
+  void HandleTap(TapType aType,
+                 const LayoutDevicePoint& aPoint,
+                 Modifiers aModifiers,
+                 const ScrollableLayerGuid& aGuid,
+                 uint64_t aInputBlockId) override;
+
+  void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
+                            APZStateChange aChange,
+                            int aArg) override;
+
+  void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
+                                 const nsString& aEvent) override;
+
+  void NotifyFlushComplete() override;
+
+  void PostDelayedTask(already_AddRefed<Runnable> aRunnable, int aDelayMs) override;
+
+  bool IsRepaintThread() override;
+
+  void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) override;
+
+private:
+  ContentProcessController();
+
+  void SetObserver(nsIObserver* aObserver);
+
+  RefPtr<dom::TabChild> mBrowser;
+  RefPtr<nsIObserver> mObserver;
+};
+
+} // namespace layers
+
+} // namespace mozilla
+
+#endif // mozilla_layers_ContentProcessController_h
--- a/gfx/layers/ipc/APZChild.cpp
+++ b/gfx/layers/ipc/APZChild.cpp
@@ -1,183 +1,111 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=4 ts=8 et 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/APZChild.h"
+#include "mozilla/layers/GeckoContentController.h"
 
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 
+#include "InputData.h" // for InputData
+
 namespace mozilla {
 namespace layers {
 
-/**
- * There are cases where we try to create the APZChild before the corresponding
- * TabChild has been created, we use an observer for the "tab-child-created"
- * topic to set the TabChild in the APZChild when it has been created.
- */
-class TabChildCreatedObserver : public nsIObserver
-{
-public:
-  TabChildCreatedObserver(APZChild* aAPZChild, const dom::TabId& aTabId)
-    : mAPZChild(aAPZChild),
-      mTabId(aTabId)
-  {}
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIOBSERVER
-
-private:
-  virtual ~TabChildCreatedObserver()
-  {}
-
-  // TabChildCreatedObserver is owned by mAPZChild, and mAPZChild outlives its
-  // TabChildCreatedObserver, so the raw pointer is fine.
-  APZChild* mAPZChild;
-  dom::TabId mTabId;
-};
-
-NS_IMPL_ISUPPORTS(TabChildCreatedObserver, nsIObserver)
-
-NS_IMETHODIMP
-TabChildCreatedObserver::Observe(nsISupports* aSubject,
-                                 const char* aTopic,
-                                 const char16_t* aData)
+APZChild::APZChild(RefPtr<GeckoContentController> aController)
+  : mController(aController)
 {
-  MOZ_ASSERT(strcmp(aTopic, "tab-child-created") == 0);
-
-  nsCOMPtr<nsITabChild> tabChild(do_QueryInterface(aSubject));
-  NS_ENSURE_TRUE(tabChild, NS_ERROR_FAILURE);
-
-  dom::TabChild* browser = static_cast<dom::TabChild*>(tabChild.get());
-  if (browser->GetTabId() == mTabId) {
-    mAPZChild->SetBrowser(browser);
-  }
-  return NS_OK;
-}
-
-APZChild*
-APZChild::Create(const dom::TabId& aTabId)
-{
-  RefPtr<dom::TabChild> browser = dom::TabChild::FindTabChild(aTabId);
-  nsAutoPtr<APZChild> apz(new APZChild);
-  if (browser) {
-    apz->SetBrowser(browser);
-  } else {
-    RefPtr<TabChildCreatedObserver> observer =
-      new TabChildCreatedObserver(apz, aTabId);
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    if (!os ||
-        NS_FAILED(os->AddObserver(observer, "tab-child-created", false))) {
-      return nullptr;
-    }
-    apz->SetObserver(observer);
-  }
-
-  return apz.forget();
-}
-
-APZChild::APZChild()
-  : mDestroyed(false)
-{
+  MOZ_ASSERT(mController);
 }
 
 APZChild::~APZChild()
 {
-  if (mObserver) {
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    os->RemoveObserver(mObserver, "tab-child-created");
-  } else if (mBrowser) {
-    mBrowser->SetAPZChild(nullptr);
+  if (mController) {
+    mController->Destroy();
+    mController = nullptr;
   }
 }
 
 bool
 APZChild::RecvRequestContentRepaint(const FrameMetrics& aFrameMetrics)
 {
-  return mBrowser->UpdateFrame(aFrameMetrics);
+  MOZ_ASSERT(mController->IsRepaintThread());
+
+  mController->RequestContentRepaint(aFrameMetrics);
+  return true;
 }
 
 bool
 APZChild::RecvHandleTap(const TapType& aType,
                         const LayoutDevicePoint& aPoint,
                         const Modifiers& aModifiers,
                         const ScrollableLayerGuid& aGuid,
                         const uint64_t& aInputBlockId,
                         const bool& aCallTakeFocusForClickFromTap)
 {
-  mBrowser->HandleTap(aType, aPoint - mBrowser->GetChromeDisplacement(), aModifiers, aGuid,
-      aInputBlockId, aCallTakeFocusForClickFromTap);
+  mController->HandleTap(aType, aPoint, aModifiers, aGuid,
+      aInputBlockId);
+  return true;
+}
+
+bool
+APZChild::RecvUpdateOverscrollVelocity(const float& aX, const float& aY, const bool& aIsRootContent)
+{
+  mController->UpdateOverscrollVelocity(aX, aY, aIsRootContent);
+  return true;
+}
+
+bool
+APZChild::RecvUpdateOverscrollOffset(const float& aX, const float& aY, const bool& aIsRootContent)
+{
+  mController->UpdateOverscrollOffset(aX, aY, aIsRootContent);
   return true;
 }
 
 bool
-APZChild::RecvNotifyMozMouseScrollEvent(const uint64_t& aLayersId,
-                                        const ViewID& aScrollId,
-                                        const nsString& aEvent)
+APZChild::RecvSetScrollingRootContent(const bool& aIsRootContent)
 {
-  if (mBrowser) {
-    mBrowser->RecvMouseScrollTestEvent(aLayersId, aScrollId, aEvent);
-  }
+  mController->SetScrollingRootContent(aIsRootContent);
   return true;
 }
 
 bool
-APZChild::RecvNotifyAPZStateChange(const ViewID& aViewId,
+APZChild::RecvNotifyMozMouseScrollEvent(const ViewID& aScrollId,
+                                        const nsString& aEvent)
+{
+  mController->NotifyMozMouseScrollEvent(aScrollId, aEvent);
+  return true;
+}
+
+bool
+APZChild::RecvNotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                    const APZStateChange& aChange,
                                    const int& aArg)
 {
-  return mBrowser->NotifyAPZStateChange(aViewId, aChange, aArg);
+  mController->NotifyAPZStateChange(aGuid, aChange, aArg);
+  return true;
 }
 
 bool
 APZChild::RecvNotifyFlushComplete()
 {
-  nsCOMPtr<nsIPresShell> shell;
-  if (nsCOMPtr<nsIDocument> doc = mBrowser->GetDocument()) {
-    shell = doc->GetShell();
-  }
-  APZCCallbackHelper::NotifyFlushComplete(shell.get());
+  MOZ_ASSERT(mController->IsRepaintThread());
+
+  mController->NotifyFlushComplete();
   return true;
 }
 
 bool
 APZChild::RecvDestroy()
 {
-  mDestroyed = true;
-  if (mBrowser) {
-    mBrowser->SetAPZChild(nullptr);
-    mBrowser = nullptr;
-  }
+  // mController->Destroy will be called in the destructor
   PAPZChild::Send__delete__(this);
   return true;
 }
 
-void
-APZChild::SetObserver(nsIObserver* aObserver)
-{
-  MOZ_ASSERT(!mBrowser);
-  mObserver = aObserver;
-}
-
-void
-APZChild::SetBrowser(dom::TabChild* aBrowser)
-{
-  MOZ_ASSERT(!mBrowser);
-  if (mObserver) {
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    os->RemoveObserver(mObserver, "tab-child-created");
-    mObserver = nullptr;
-  }
-  // We might get the tab-child-created notification after we receive a
-  // Destroy message from the parent. In that case we don't want to install
-  // ourselves with the browser.
-  if (!mDestroyed) {
-    mBrowser = aBrowser;
-    mBrowser->SetAPZChild(this);
-  }
-}
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/APZChild.h
+++ b/gfx/layers/ipc/APZChild.h
@@ -4,63 +4,55 @@
  * 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_APZChild_h
 #define mozilla_layers_APZChild_h
 
 #include "mozilla/layers/PAPZChild.h"
 
-class nsIObserver;
-
 namespace mozilla {
 
-namespace dom {
-class TabChild;
-} // namespace dom
+namespace layers {
 
-namespace layers {
+class GeckoContentController;
 
 class APZChild final : public PAPZChild
 {
 public:
-  static APZChild* Create(const dom::TabId& aTabId);
-
+  explicit APZChild(RefPtr<GeckoContentController> aController);
   ~APZChild();
 
-  void SetBrowser(dom::TabChild* aBrowser);
-
   bool RecvRequestContentRepaint(const FrameMetrics& frame) override;
 
   bool RecvHandleTap(const TapType& aType,
                      const LayoutDevicePoint& aPoint,
                      const Modifiers& aModifiers,
                      const ScrollableLayerGuid& aGuid,
                      const uint64_t& aInputBlockId,
                      const bool& aCallTakeFocusForClickFromTap) override;
 
-  bool RecvNotifyMozMouseScrollEvent(const uint64_t& aLayersId,
-                                     const ViewID& aScrollId,
+  bool RecvUpdateOverscrollVelocity(const float& aX, const float& aY, const bool& aIsRootContent) override;
+
+  bool RecvUpdateOverscrollOffset(const float& aX, const float& aY, const bool& aIsRootContent) override;
+
+  bool RecvSetScrollingRootContent(const bool& aIsRootContent) override;
+
+  bool RecvNotifyMozMouseScrollEvent(const ViewID& aScrollId,
                                      const nsString& aEvent) override;
 
-  bool RecvNotifyAPZStateChange(const ViewID& aViewId,
+  bool RecvNotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                 const APZStateChange& aChange,
                                 const int& aArg) override;
 
   bool RecvNotifyFlushComplete() override;
 
   bool RecvDestroy() override;
 
 private:
-  APZChild();
-
-  void SetObserver(nsIObserver* aObserver);
-
-  RefPtr<dom::TabChild> mBrowser;
-  RefPtr<nsIObserver> mObserver;
-  bool mDestroyed;
+  RefPtr<GeckoContentController> mController;
 };
 
 } // namespace layers
 
 } // namespace mozilla
 
 #endif // mozilla_layers_APZChild_h
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -2551,17 +2551,17 @@ PAPZParent*
 CrossProcessCompositorBridgeParent::AllocPAPZParent(const uint64_t& aLayersId)
 {
   // Check to see if this child process has access to this layer tree.
   if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) {
     NS_ERROR("Unexpected layers id in AllocPAPZParent; dropping message...");
     return nullptr;
   }
 
-  RemoteContentController* controller = new RemoteContentController(aLayersId);
+  RemoteContentController* controller = new RemoteContentController();
 
   // Increment the controller's refcount before we return it. This will keep the
   // controller alive until it is released by IPDL in DeallocPAPZParent.
   controller->AddRef();
 
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
   CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId];
   MOZ_ASSERT(!state.mController);
--- a/gfx/layers/ipc/PAPZ.ipdl
+++ b/gfx/layers/ipc/PAPZ.ipdl
@@ -52,19 +52,25 @@ child:
 
   // The aCallTakeFocusForClickFromTap argument is used for eSingleTap types,
   // to request that the child take focus before dispatching the mouse events
   // for the tap (otherwise the resulting focus behaviour is incorrect).
   async HandleTap(TapType aType, LayoutDevicePoint point, Modifiers aModifiers,
                   ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
                   bool aCallTakeFocusForClickFromTap);
 
-  async NotifyMozMouseScrollEvent(uint64_t aLayersId, ViewID aScrollId, nsString aEvent);
+  async UpdateOverscrollVelocity(float aX, float aY, bool aIsRootContent);
+
+  async UpdateOverscrollOffset(float aX, float aY, bool aIsRootContent);
 
-  async NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg);
+  async SetScrollingRootContent(bool aIsRootContent);
+
+  async NotifyMozMouseScrollEvent(ViewID aScrollId, nsString aEvent);
+
+  async NotifyAPZStateChange(ScrollableLayerGuid aGuid, APZStateChange aChange, int aArg);
 
   async NotifyFlushComplete();
 
   async Destroy();
 };
 
 } // layers
 } // mozilla
--- a/gfx/layers/ipc/RemoteContentController.cpp
+++ b/gfx/layers/ipc/RemoteContentController.cpp
@@ -21,19 +21,18 @@
 #include "AndroidBridge.h"
 #endif
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
-RemoteContentController::RemoteContentController(uint64_t aLayersId)
+RemoteContentController::RemoteContentController()
   : mCompositorThread(MessageLoop::current())
-  , mLayersId(aLayersId)
   , mCanSend(true)
   , mMutex("RemoteContentController")
 {
 }
 
 RemoteContentController::~RemoteContentController()
 {
 }
@@ -119,35 +118,73 @@ RemoteContentController::NotifyAPZStateC
                                         APZStateChange,
                                         int>(this,
                                              &RemoteContentController::NotifyAPZStateChange,
                                              aGuid, aChange, aArg));
     return;
   }
 
   if (mCanSend) {
-    Unused << SendNotifyAPZStateChange(aGuid.mScrollId, aChange, aArg);
+    Unused << SendNotifyAPZStateChange(aGuid, aChange, aArg);
+  }
+}
+
+void
+RemoteContentController::UpdateOverscrollVelocity(float aX, float aY, bool aIsRootContent)
+{
+  if (MessageLoop::current() != mCompositorThread) {
+    mCompositorThread->PostTask(NewRunnableMethod<float,
+                                        float, bool>(this,
+                                             &RemoteContentController::UpdateOverscrollVelocity,
+                                             aX, aY, aIsRootContent));
+    return;
   }
+  Unused << SendUpdateOverscrollVelocity(aX, aY, aIsRootContent);
+}
+
+void
+RemoteContentController::UpdateOverscrollOffset(float aX, float aY, bool aIsRootContent)
+{
+  if (MessageLoop::current() != mCompositorThread) {
+    mCompositorThread->PostTask(NewRunnableMethod<float,
+                                        float, bool>(this,
+                                             &RemoteContentController::UpdateOverscrollOffset,
+                                             aX, aY, aIsRootContent));
+    return;
+  }
+  Unused << SendUpdateOverscrollOffset(aX, aY, aIsRootContent);
+}
+
+void
+RemoteContentController::SetScrollingRootContent(bool aIsRootContent)
+{
+  if (MessageLoop::current() != mCompositorThread) {
+    mCompositorThread->PostTask(NewRunnableMethod<bool>(this,
+                                             &RemoteContentController::SetScrollingRootContent,
+                                             aIsRootContent));
+    return;
+  }
+  Unused << SendSetScrollingRootContent(aIsRootContent);
 }
 
 void
 RemoteContentController::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
                                                    const nsString& aEvent)
 {
   if (MessageLoop::current() != mCompositorThread) {
     // We have to send messages from the compositor thread
     mCompositorThread->PostTask(NewRunnableMethod<FrameMetrics::ViewID,
                                         nsString>(this,
                                                   &RemoteContentController::NotifyMozMouseScrollEvent,
                                                   aScrollId, aEvent));
     return;
   }
 
   if (mCanSend) {
-    Unused << SendNotifyMozMouseScrollEvent(mLayersId, aScrollId, aEvent);
+    Unused << SendNotifyMozMouseScrollEvent(aScrollId, aEvent);
   }
 }
 
 void
 RemoteContentController::NotifyFlushComplete()
 {
   MOZ_ASSERT(IsRepaintThread());
 
--- a/gfx/layers/ipc/RemoteContentController.h
+++ b/gfx/layers/ipc/RemoteContentController.h
@@ -28,17 +28,17 @@ namespace layers {
  */
 class RemoteContentController : public GeckoContentController
                               , public PAPZParent
 {
   using GeckoContentController::TapType;
   using GeckoContentController::APZStateChange;
 
 public:
-  explicit RemoteContentController(uint64_t aLayersId);
+  RemoteContentController();
 
   virtual ~RemoteContentController();
 
   virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) override;
 
   virtual void HandleTap(TapType aTapType,
                          const LayoutDevicePoint& aPoint,
                          Modifiers aModifiers,
@@ -52,30 +52,35 @@ public:
   virtual void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) override;
 
   virtual bool GetTouchSensitiveRegion(CSSRect* aOutRegion) override;
 
   virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                     APZStateChange aChange,
                                     int aArg) override;
 
+  virtual void UpdateOverscrollVelocity(float aX, float aY, bool aIsRootContent) override;
+
+  virtual void UpdateOverscrollOffset(float aX, float aY, bool aIsRootContent) override;
+
+  virtual void SetScrollingRootContent(bool aIsRootContent) override;
+
   virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
                                          const nsString& aEvent) override;
 
   virtual void NotifyFlushComplete() override;
 
   virtual bool RecvUpdateHitRegion(const nsRegion& aRegion) override;
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   virtual void Destroy() override;
 
 private:
   MessageLoop* mCompositorThread;
-  uint64_t mLayersId;
   bool mCanSend;
 
   // Mutex protecting members below accessed from multiple threads.
   mozilla::Mutex mMutex;
   nsRegion mTouchSensitiveRegion;
 };
 
 } // namespace layers
--- a/gfx/layers/ipc/SharedBufferManagerParent.cpp
+++ b/gfx/layers/ipc/SharedBufferManagerParent.cpp
@@ -8,16 +8,17 @@
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for CancelableTask, DeleteTask, etc
 #include "base/thread.h"
 #include "mozilla/Sprintf.h"            // for SprintfLiteral
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"      // for Transport
+#include "mozilla/Sprintf.h"
 #include "mozilla/UniquePtr.h"          // for UniquePtr
 #include "mozilla/unused.h"
 #include "nsIMemoryReporter.h"
 #ifdef MOZ_WIDGET_GONK
 #include "mozilla/LinuxUtils.h"
 #include "ui/PixelFormat.h"
 #endif
 #include "nsPrintfCString.h"
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -107,16 +107,17 @@ EXPORTS.mozilla.layers += [
     'apz/src/AsyncPanZoomAnimation.h',
     'apz/src/TouchCounter.h',
     'apz/testutil/APZTestData.h',
     'apz/util/ActiveElementManager.h',
     'apz/util/APZCCallbackHelper.h',
     'apz/util/APZEventState.h',
     'apz/util/APZThreadUtils.h',
     'apz/util/ChromeProcessController.h',
+    'apz/util/ContentProcessController.h',
     'apz/util/DoubleTapToZoom.h',
     'apz/util/InputAPZContext.h',
     'apz/util/ScrollInputMethods.h',
     'apz/util/ScrollLinkedEffectDetector.h',
     'apz/util/TouchActionHelper.h',
     'AsyncCanvasRenderer.h',
     'AtomicRefCountedWithFinalize.h',
     'AxisPhysicsModel.h',
@@ -283,16 +284,17 @@ UNIFIED_SOURCES += [
     'apz/src/WheelScrollAnimation.cpp',
     'apz/testutil/APZTestData.cpp',
     'apz/util/ActiveElementManager.cpp',
     'apz/util/APZCCallbackHelper.cpp',
     'apz/util/APZEventState.cpp',
     'apz/util/APZThreadUtils.cpp',
     'apz/util/CheckerboardReportService.cpp',
     'apz/util/ChromeProcessController.cpp',
+    'apz/util/ContentProcessController.cpp',
     'apz/util/DoubleTapToZoom.cpp',
     'apz/util/InputAPZContext.cpp',
     'apz/util/ScrollLinkedEffectDetector.cpp',
     'apz/util/TouchActionHelper.cpp',
     'AsyncCanvasRenderer.cpp',
     'AxisPhysicsModel.cpp',
     'AxisPhysicsMSDModel.cpp',
     'basic/BasicCanvasLayer.cpp',