Bug 1188225 - Implement ChromeProcessController::HandleDoubleTap. r=botond
authorRandall Barker <rbarker@mozilla.com>
Thu, 13 Aug 2015 18:26:00 -0400
changeset 257896 ae48bb7aad1b8aeb6bafcc6343a6a654866202ff
parent 257895 23146a80594cf148f6d52696e36706de01abd817
child 257897 e8ae270ae0d5abf285d55b35fe8ea8d3bb255e4e
push id29233
push userkwierso@gmail.com
push dateFri, 14 Aug 2015 23:32:11 +0000
treeherdermozilla-central@45bea43ad812 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1188225
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1188225 - Implement ChromeProcessController::HandleDoubleTap. r=botond
gfx/layers/apz/util/APZCCallbackHelper.cpp
gfx/layers/apz/util/APZCCallbackHelper.h
gfx/layers/apz/util/ChromeProcessController.cpp
gfx/layers/apz/util/ChromeProcessController.h
widget/android/AndroidContentController.h
widget/android/nsWindow.cpp
widget/nsBaseWidget.cpp
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -387,18 +387,18 @@ APZCCallbackHelper::AcknowledgeScrollUpd
     nsCOMPtr<nsIRunnable> r1 = new AcknowledgeScrollUpdateEvent(aScrollId, aScrollGeneration);
     if (!NS_IsMainThread()) {
         NS_DispatchToMainThread(r1);
     } else {
         r1->Run();
     }
 }
 
-static nsIPresShell*
-GetRootContentDocumentPresShellForContent(nsIContent* aContent)
+nsIPresShell*
+APZCCallbackHelper::GetRootContentDocumentPresShellForContent(nsIContent* aContent)
 {
     nsIDocument* doc = aContent->GetComposedDoc();
     if (!doc) {
         return nullptr;
     }
     nsIPresShell* shell = doc->GetShell();
     if (!shell) {
         return nullptr;
--- a/gfx/layers/apz/util/APZCCallbackHelper.h
+++ b/gfx/layers/apz/util/APZCCallbackHelper.h
@@ -80,16 +80,19 @@ public:
     static void RequestFlingSnap(const FrameMetrics::ViewID& aScrollId,
                                  const mozilla::CSSPoint& aDestination);
 
     /* Tell layout that we received the scroll offset update for the given view ID, so
        that it accepts future scroll offset updates from APZ. */
     static void AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
                                         const uint32_t& aScrollGeneration);
 
+    /* Get the pres shell associated with the root content document enclosing |aContent|. */
+    static nsIPresShell* GetRootContentDocumentPresShellForContent(nsIContent* aContent);
+
     /* Apply an "input transform" to the given |aInput| and return the transformed value.
        The input transform applied is the one for the content element corresponding to
        |aGuid|; this is populated in a previous call to UpdateCallbackTransform. See that
        method's documentations for details.
        This method additionally adjusts |aInput| by inversely scaling by the provided
        pres shell resolution, to cancel out a compositor-side transform (added in
        bug 1076241) that APZ doesn't unapply. */
     static CSSPoint ApplyCallbackTransform(const CSSPoint& aInput,
--- a/gfx/layers/apz/util/ChromeProcessController.cpp
+++ b/gfx/layers/apz/util/ChromeProcessController.cpp
@@ -6,40 +6,48 @@
 #include "ChromeProcessController.h"
 
 #include "MainThreadUtils.h"    // for NS_IsMainThread()
 #include "base/message_loop.h"  // for MessageLoop
 #include "mozilla/dom/Element.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/APZEventState.h"
+#include "mozilla/layers/APZCTreeManager.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)
+                                                 APZEventState* aAPZEventState,
+                                                 APZCTreeManager* aAPZCTreeManager)
   : mWidget(aWidget)
   , mAPZEventState(aAPZEventState)
+  , mAPZCTreeManager(aAPZCTreeManager)
   , mUILoop(MessageLoop::current())
 {
   // Otherwise we're initializing mUILoop incorrectly.
   MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aAPZEventState);
+  MOZ_ASSERT(aAPZCTreeManager);
 
   mUILoop->PostTask(
       FROM_HERE,
       NewRunnableMethod(this, &ChromeProcessController::InitializeRoot));
 }
 
+ChromeProcessController::~ChromeProcessController() {}
+
 void
 ChromeProcessController::InitializeRoot()
 {
   APZCCallbackHelper::InitializeRootDisplayport(GetPresShell());
 }
 
 void
 ChromeProcessController::RequestContentRepaint(const FrameMetrics& aFrameMetrics)
@@ -93,35 +101,69 @@ ChromeProcessController::GetPresShell() 
 {
   if (nsView* view = nsView::GetViewFor(mWidget)) {
     return view->GetPresShell();
   }
   return nullptr;
 }
 
 nsIDocument*
-ChromeProcessController::GetDocument() const
+ChromeProcessController::GetRootDocument() const
 {
   if (nsIPresShell* presShell = GetPresShell()) {
     return presShell->GetDocument();
   }
   return nullptr;
 }
 
-already_AddRefed<nsIDOMWindowUtils>
-ChromeProcessController::GetDOMWindowUtils() const
+nsIDocument*
+ChromeProcessController::GetRootContentDocument(const FrameMetrics::ViewID& aScrollId) const
 {
-  if (nsIDocument* doc = GetDocument()) {
-    nsCOMPtr<nsIDOMWindowUtils> result = do_GetInterface(doc->GetWindow());
-    return result.forget();
+  nsIContent* content = nsLayoutUtils::FindContentFor(aScrollId);
+  if (!content) {
+    return nullptr;
+  }
+  nsIPresShell* presShell = APZCCallbackHelper::GetRootContentDocumentPresShellForContent(content);
+  if (presShell) {
+    return presShell->GetDocument();
   }
   return nullptr;
 }
 
 void
+ChromeProcessController::HandleDoubleTap(const mozilla::CSSPoint& aPoint,
+                                         Modifiers aModifiers,
+                                         const ScrollableLayerGuid& aGuid)
+{
+  if (MessageLoop::current() != mUILoop) {
+    mUILoop->PostTask(
+        FROM_HERE,
+        NewRunnableMethod(this, &ChromeProcessController::HandleDoubleTap,
+                          aPoint, aModifiers, aGuid));
+    return;
+  }
+
+  nsCOMPtr<nsIDocument> document = GetRootContentDocument(aGuid.mScrollId);
+  if (!document.get()) {
+    return;
+  }
+
+  CSSPoint point = APZCCallbackHelper::ApplyCallbackTransform(aPoint, aGuid);
+  CSSRect zoomToRect = CalculateRectToZoomTo(document, point);
+
+  uint32_t presShellId;
+  FrameMetrics::ViewID viewId;
+  if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(
+      document->GetDocumentElement(), &presShellId, &viewId)) {
+    mAPZCTreeManager->ZoomToRect(
+      ScrollableLayerGuid(aGuid.mLayersId, presShellId, viewId), zoomToRect);
+  }
+}
+
+void
 ChromeProcessController::HandleSingleTap(const CSSPoint& aPoint,
                                          Modifiers aModifiers,
                                          const ScrollableLayerGuid& aGuid)
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
         FROM_HERE,
         NewRunnableMethod(this, &ChromeProcessController::HandleSingleTap,
@@ -157,17 +199,17 @@ ChromeProcessController::NotifyAPZStateC
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
         FROM_HERE,
         NewRunnableMethod(this, &ChromeProcessController::NotifyAPZStateChange,
                           aGuid, aChange, aArg));
     return;
   }
 
-  mAPZEventState->ProcessAPZStateChange(GetDocument(), aGuid.mScrollId, aChange, aArg);
+  mAPZEventState->ProcessAPZStateChange(GetRootDocument(), aGuid.mScrollId, aChange, aArg);
 }
 
 void
 ChromeProcessController::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(
       FROM_HERE,
--- a/gfx/layers/apz/util/ChromeProcessController.h
+++ b/gfx/layers/apz/util/ChromeProcessController.h
@@ -16,59 +16,62 @@ class nsIPresShell;
 class nsIWidget;
 
 class MessageLoop;
 
 namespace mozilla {
 
 namespace layers {
 
+class APZCTreeManager;
 class APZEventState;
 
 // A ChromeProcessController is attached to the root of a compositor's layer
 // tree.
 class ChromeProcessController : public mozilla::layers::GeckoContentController
 {
   typedef mozilla::layers::FrameMetrics FrameMetrics;
   typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
 
 public:
-  explicit ChromeProcessController(nsIWidget* aWidget, APZEventState* aAPZEventState);
+  explicit ChromeProcessController(nsIWidget* aWidget, APZEventState* aAPZEventState, APZCTreeManager* aAPZCTreeManager);
+  ~ChromeProcessController();
   virtual void Destroy() override;
 
   // GeckoContentController interface
   virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) override;
   virtual void PostDelayedTask(Task* aTask, int aDelayMs) override;
   virtual void RequestFlingSnap(const FrameMetrics::ViewID& aScrollId,
                                 const mozilla::CSSPoint& aDestination) override;
   virtual void AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
                                        const uint32_t& aScrollGeneration) override;
 
   virtual void HandleDoubleTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
-                               const ScrollableLayerGuid& aGuid) override {}
+                               const ScrollableLayerGuid& aGuid) override;
   virtual void HandleSingleTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
                                const ScrollableLayerGuid& aGuid) override;
   virtual void HandleLongTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
                                const ScrollableLayerGuid& aGuid,
                                uint64_t aInputBlockId) override;
   virtual void SendAsyncScrollDOMEvent(bool aIsRootContent, const mozilla::CSSRect &aContentRect,
                                        const mozilla::CSSSize &aScrollableSize) override {}
   virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                     APZStateChange aChange,
                                     int aArg) override;
   virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
                                          const nsString& aEvent) override;
   virtual void NotifyFlushComplete() override;
 private:
   nsCOMPtr<nsIWidget> mWidget;
   nsRefPtr<APZEventState> mAPZEventState;
+  nsRefPtr<APZCTreeManager> mAPZCTreeManager;
   MessageLoop* mUILoop;
 
   void InitializeRoot();
   nsIPresShell* GetPresShell() const;
-  nsIDocument* GetDocument() const;
-  already_AddRefed<nsIDOMWindowUtils> GetDOMWindowUtils() const;
+  nsIDocument* GetRootDocument() const;
+  nsIDocument* GetRootContentDocument(const FrameMetrics::ViewID& aScrollId) const;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /* mozilla_layers_ChromeProcessController_h */
--- a/widget/android/AndroidContentController.h
+++ b/widget/android/AndroidContentController.h
@@ -2,33 +2,38 @@
  * 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 AndroidContentController_h__
 #define AndroidContentController_h__
 
 #include "mozilla/layers/ChromeProcessController.h"
-#include "mozilla/layers/APZEventState.h"
 #include "mozilla/EventForwards.h"  // for Modifiers
 #include "mozilla/StaticPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "GeneratedJNIWrappers.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsTArray.h"
 
 namespace mozilla {
+namespace layers {
+class APZEventState;
+class APZCTreeManager;
+}
 namespace widget {
 namespace android {
 
 class AndroidContentController final : public mozilla::layers::ChromeProcessController
 {
 public:
-    AndroidContentController(nsIWidget* aWidget, mozilla::layers::APZEventState* aAPZEventState)
-      : mozilla::layers::ChromeProcessController(aWidget, aAPZEventState)
+    AndroidContentController(nsIWidget* aWidget,
+                             mozilla::layers::APZEventState* aAPZEventState,
+                             mozilla::layers::APZCTreeManager* aAPZCTreeManager)
+      : mozilla::layers::ChromeProcessController(aWidget, aAPZEventState, aAPZCTreeManager)
     {}
 
     // ChromeProcessController methods
     void PostDelayedTask(Task* aTask, int aDelayMs) override;
 
 public:
     static NativePanZoomController::LocalRef SetNativePanZoomController(NativePanZoomController::Param obj);
     static void NotifyDefaultPrevented(uint64_t aInputBlockId, bool aDefaultPrevented);
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -2517,17 +2517,17 @@ void
 nsWindow::ConfigureAPZControllerThread()
 {
     APZThreadUtils::SetControllerThread(nullptr);
 }
 
 already_AddRefed<GeckoContentController>
 nsWindow::CreateRootContentController()
 {
-    nsRefPtr<GeckoContentController> controller = new widget::android::AndroidContentController(this, mAPZEventState);
+    nsRefPtr<GeckoContentController> controller = new widget::android::AndroidContentController(this, mAPZEventState, mAPZC);
     return controller.forget();
 }
 
 uint64_t
 nsWindow::RootLayerTreeId()
 {
     MOZ_ASSERT(sCompositorParent);
     return sCompositorParent->RootLayerTreeId();
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -866,17 +866,17 @@ void nsBaseWidget::CreateCompositor()
   nsIntRect rect;
   GetBounds(rect);
   CreateCompositor(rect.width, rect.height);
 }
 
 already_AddRefed<GeckoContentController>
 nsBaseWidget::CreateRootContentController()
 {
-  nsRefPtr<GeckoContentController> controller = new ChromeProcessController(this, mAPZEventState);
+  nsRefPtr<GeckoContentController> controller = new ChromeProcessController(this, mAPZEventState, mAPZC);
   return controller.forget();
 }
 
 class ChromeProcessSetAllowedTouchBehaviorCallback : public SetAllowedTouchBehaviorCallback {
 public:
   explicit ChromeProcessSetAllowedTouchBehaviorCallback(APZCTreeManager* aTreeManager)
     : mTreeManager(aTreeManager)
   {}