Bug 964750 - Make GestureEventListener rely on the EventStatus returned from the apzc. Add a check to apzc if touch-action allows zooming. Update apzc tests accordingly. r=drs
authorNick Lebedev <nicklebedev37@gmail.com>
Mon, 05 May 2014 11:23:00 -0400
changeset 182229 4486d2c281db4e662518a380f560bac7d85d3c55
parent 182228 47f27d39796d592e3689d7e7d73d6e407ed3106a
child 182230 07b29d7938d33eaa6a86be843833cff40cb3158b
push id43237
push userryanvm@gmail.com
push dateThu, 08 May 2014 21:25:57 +0000
treeherdermozilla-inbound@11a57591cedb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdrs
bugs964750
milestone32.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 964750 - Make GestureEventListener rely on the EventStatus returned from the apzc. Add a check to apzc if touch-action allows zooming. Update apzc tests accordingly. r=drs
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/GestureEventListener.cpp
gfx/tests/gtest/TestAsyncPanZoomController.cpp
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -875,16 +875,21 @@ nsEventStatus AsyncPanZoomController::On
   SetState(PINCHING);
   mLastZoomFocus = ToParentLayerCoords(aEvent.mFocusPoint) - mFrameMetrics.mCompositionBounds.TopLeft();
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
   APZC_LOG("%p got a scale in state %d\n", this, mState);
+
+  if (!TouchActionAllowPinchZoom()) {
+    return nsEventStatus_eIgnore;
+  }
+
   if (mState != PINCHING) {
     return nsEventStatus_eConsumeNoDefault;
   }
 
   float prevSpan = aEvent.mPreviousSpan;
   if (fabsf(prevSpan) <= EPSILON || fabsf(aEvent.mCurrentSpan) <= EPSILON) {
     // We're still handling it; we've just decided to throw this event away.
     return nsEventStatus_eConsumeNoDefault;
@@ -954,16 +959,20 @@ nsEventStatus AsyncPanZoomController::On
   }
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnScaleEnd(const PinchGestureInput& aEvent) {
   APZC_LOG("%p got a scale-end in state %d\n", this, mState);
 
+  if (!TouchActionAllowPinchZoom()) {
+    return nsEventStatus_eIgnore;
+  }
+
   SetState(NOTHING);
 
   {
     ReentrantMonitorAutoEnter lock(mMonitor);
     ScheduleComposite();
     RequestContentRepaint();
     UpdateSharedCompositorFrameMetrics();
   }
--- a/gfx/layers/apz/src/GestureEventListener.cpp
+++ b/gfx/layers/apz/src/GestureEventListener.cpp
@@ -216,19 +216,19 @@ nsEventStatus GestureEventListener::Hand
       SetState(GESTURE_PINCH);
       PinchGestureInput pinchEvent(PinchGestureInput::PINCHGESTURE_START,
                                    mLastTouchInput.mTime,
                                    GetCurrentFocus(mLastTouchInput),
                                    currentSpan,
                                    currentSpan,
                                    mLastTouchInput.modifiers);
 
-      mAsyncPanZoomController->HandleGestureEvent(pinchEvent);
+      rv = mAsyncPanZoomController->HandleGestureEvent(pinchEvent);
     }
-    rv = nsEventStatus_eConsumeNoDefault;
+
     mPreviousSpan = currentSpan;
     break;
   }
 
   case GESTURE_PINCH: {
     if (mLastTouchInput.mTouches.Length() < 2) {
       NS_WARNING("Wrong input: less than 2 moving points in GESTURE_PINCH state");
       // Prevent APZC::OnTouchMove() from handling this wrong input
@@ -240,18 +240,17 @@ nsEventStatus GestureEventListener::Hand
 
     PinchGestureInput pinchEvent(PinchGestureInput::PINCHGESTURE_SCALE,
                                  mLastTouchInput.mTime,
                                  GetCurrentFocus(mLastTouchInput),
                                  currentSpan,
                                  mPreviousSpan,
                                  mLastTouchInput.modifiers);
 
-    mAsyncPanZoomController->HandleGestureEvent(pinchEvent);
-    rv = nsEventStatus_eConsumeNoDefault;
+    rv = mAsyncPanZoomController->HandleGestureEvent(pinchEvent);
     mPreviousSpan = currentSpan;
 
     break;
   }
 
   default:
     NS_WARNING("Unhandled state upon touch move");
     SetState(GESTURE_NONE);
@@ -272,51 +271,51 @@ nsEventStatus GestureEventListener::Hand
 
   case GESTURE_FIRST_SINGLE_TOUCH_DOWN: {
     CancelLongTapTimeoutTask();
     CancelMaxTapTimeoutTask();
     TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_UP,
                              mLastTouchInput.mTime,
                              mLastTouchInput.mTouches[0].mScreenPoint,
                              mLastTouchInput.modifiers);
-    nsEventStatus tapupStatus = mAsyncPanZoomController->HandleGestureEvent(tapEvent);
-    if (tapupStatus == nsEventStatus_eIgnore) {
+    rv = mAsyncPanZoomController->HandleGestureEvent(tapEvent);
+    if (rv == nsEventStatus_eIgnore) {
       SetState(GESTURE_FIRST_SINGLE_TOUCH_UP);
       CreateMaxTapTimeoutTask();
     } else {
       // We sent the tapup into content without waiting for a double tap
       SetState(GESTURE_NONE);
     }
     break;
   }
 
   case GESTURE_SECOND_SINGLE_TOUCH_DOWN: {
     CancelMaxTapTimeoutTask();
     SetState(GESTURE_NONE);
     TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_DOUBLE,
                              mLastTouchInput.mTime,
                              mLastTouchInput.mTouches[0].mScreenPoint,
                              mLastTouchInput.modifiers);
-    mAsyncPanZoomController->HandleGestureEvent(tapEvent);
+    rv = mAsyncPanZoomController->HandleGestureEvent(tapEvent);
     break;
   }
 
   case GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN:
     CancelLongTapTimeoutTask();
     SetState(GESTURE_NONE);
     TriggerSingleTapConfirmedEvent();
     break;
 
   case GESTURE_LONG_TOUCH_DOWN: {
     SetState(GESTURE_NONE);
     TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_LONG_UP,
                              mLastTouchInput.mTime,
                              mLastTouchInput.mTouches[0].mScreenPoint,
                              mLastTouchInput.modifiers);
-    mAsyncPanZoomController->HandleGestureEvent(tapEvent);
+    rv = mAsyncPanZoomController->HandleGestureEvent(tapEvent);
     break;
   }
 
   case GESTURE_MULTI_TOUCH_DOWN:
     if (mTouches.Length() < 2) {
       SetState(GESTURE_NONE);
     }
     break;
@@ -325,19 +324,19 @@ nsEventStatus GestureEventListener::Hand
     if (mTouches.Length() < 2) {
       SetState(GESTURE_NONE);
       PinchGestureInput pinchEvent(PinchGestureInput::PINCHGESTURE_END,
                                    mLastTouchInput.mTime,
                                    ScreenPoint(),
                                    1.0f,
                                    1.0f,
                                    mLastTouchInput.modifiers);
-      mAsyncPanZoomController->HandleGestureEvent(pinchEvent);
+      rv = mAsyncPanZoomController->HandleGestureEvent(pinchEvent);
     }
-    rv = nsEventStatus_eConsumeNoDefault;
+
     break;
 
   default:
     NS_WARNING("Unhandled state upon touch end");
     SetState(GESTURE_NONE);
     break;
   }
 
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -285,38 +285,185 @@ void DoPanTest(bool aShouldTriggerScroll
   apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
 
   EXPECT_EQ(ScreenPoint(), pointOut);
   EXPECT_EQ(ViewTransform(), viewTransformOut);
 
   apzc->Destroy();
 }
 
-static void
-ApzcPinch(AsyncPanZoomController* aApzc, int aFocusX, int aFocusY, float aScale) {
-  aApzc->HandleGestureEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_START,
+static void ApzcPinchWithPinchInput(AsyncPanZoomController* aApzc,
+                                    int aFocusX,
+                                    int aFocusY,
+                                    float aScale,
+                                    bool aShouldTriggerPinch,
+                                    nsTArray<uint32_t>* aAllowedTouchBehaviors = nullptr) {
+  if (aAllowedTouchBehaviors) {
+    aApzc->SetAllowedTouchBehavior(*aAllowedTouchBehaviors);
+  }
+
+  nsEventStatus expectedStatus = aShouldTriggerPinch
+    ? nsEventStatus_eConsumeNoDefault
+    : nsEventStatus_eIgnore;
+  nsEventStatus actualStatus;
+
+  actualStatus = aApzc->HandleGestureEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_START,
                                             0,
                                             ScreenPoint(aFocusX, aFocusY),
                                             10.0,
                                             10.0,
                                             0));
-  aApzc->HandleGestureEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE,
+  EXPECT_EQ(actualStatus, expectedStatus);
+  actualStatus = aApzc->HandleGestureEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE,
                                             0,
                                             ScreenPoint(aFocusX, aFocusY),
                                             10.0 * aScale,
                                             10.0,
                                             0));
-  aApzc->HandleGestureEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_END,
+  EXPECT_EQ(actualStatus, expectedStatus);
+  actualStatus = aApzc->HandleGestureEvent(PinchGestureInput(PinchGestureInput::PINCHGESTURE_END,
                                             0,
                                             ScreenPoint(aFocusX, aFocusY),
                                             // note: negative values here tell APZC
                                             //       not to turn the pinch into a pan
                                             -1.0,
                                             -1.0,
                                             0));
+  EXPECT_EQ(actualStatus, expectedStatus);
+}
+
+static void ApzcPinchWithTouchMoveInput(AsyncPanZoomController* aApzc,
+                                        int aFocusX,
+                                        int aFocusY,
+                                        float aScale,
+                                        int& inputId,
+                                        bool aShouldTriggerPinch,
+                                        nsTArray<uint32_t>* aAllowedTouchBehaviors = nullptr) {
+  // Having pinch coordinates in float type may cause problems with high-precision scale values
+  // since SingleTouchData accepts integer value. But for trivial tests it should be ok.
+  float pinchLength = 100.0;
+  float pinchLengthScaled = pinchLength * aScale;
+
+  nsEventStatus expectedStatus = aShouldTriggerPinch
+    ? nsEventStatus_eConsumeNoDefault
+    : nsEventStatus_eIgnore;
+  nsEventStatus actualStatus;
+
+  MultiTouchInput mtiStart = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, 0, 0);
+  mtiStart.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(aFocusX, aFocusY), ScreenSize(0, 0), 0, 0));
+  mtiStart.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(aFocusX, aFocusY), ScreenSize(0, 0), 0, 0));
+  aApzc->ReceiveInputEvent(mtiStart);
+
+  if (aAllowedTouchBehaviors) {
+    aApzc->SetAllowedTouchBehavior(*aAllowedTouchBehaviors);
+  }
+
+  MultiTouchInput mtiMove1 = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, 0, 0);
+  mtiMove1.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(aFocusX - pinchLength, aFocusY), ScreenSize(0, 0), 0, 0));
+  mtiMove1.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(aFocusX + pinchLength, aFocusY), ScreenSize(0, 0), 0, 0));
+  actualStatus = aApzc->ReceiveInputEvent(mtiMove1);
+  EXPECT_EQ(actualStatus, expectedStatus);
+
+  MultiTouchInput mtiMove2 = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, 0, 0);
+  mtiMove2.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(aFocusX - pinchLengthScaled, aFocusY), ScreenSize(0, 0), 0, 0));
+  mtiMove2.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(aFocusX + pinchLengthScaled, aFocusY), ScreenSize(0, 0), 0, 0));
+  actualStatus = aApzc->ReceiveInputEvent(mtiMove2);
+  EXPECT_EQ(actualStatus, expectedStatus);
+
+  MultiTouchInput mtiEnd = MultiTouchInput(MultiTouchInput::MULTITOUCH_END, 0, 0);
+  mtiEnd.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(aFocusX - pinchLengthScaled, aFocusY), ScreenSize(0, 0), 0, 0));
+  mtiEnd.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(aFocusX + pinchLengthScaled, aFocusY), ScreenSize(0, 0), 0, 0));
+  actualStatus = aApzc->ReceiveInputEvent(mtiEnd);
+  EXPECT_EQ(actualStatus, expectedStatus);
+  inputId += 2;
+}
+
+static
+void DoPinchTest(bool aUseGestureRecognizer, bool aShouldTriggerPinch,
+                 nsTArray<uint32_t> *aAllowedTouchBehaviors = nullptr) {
+  nsRefPtr<MockContentController> mcc = new NiceMock<MockContentController>();
+  nsRefPtr<TestAPZCTreeManager> tm = new TestAPZCTreeManager();
+  nsRefPtr<TestAsyncPanZoomController> apzc = new TestAsyncPanZoomController(0, mcc, tm,
+    aUseGestureRecognizer
+      ? AsyncPanZoomController::USE_GESTURE_DETECTOR
+      : AsyncPanZoomController::DEFAULT_GESTURES);
+
+  FrameMetrics fm;
+  fm.mViewport = CSSRect(0, 0, 980, 480);
+  fm.mCompositionBounds = ParentLayerIntRect(200, 200, 100, 200);
+  fm.mScrollableRect = CSSRect(0, 0, 980, 1000);
+  fm.SetScrollOffset(CSSPoint(300, 300));
+  fm.SetZoom(CSSToScreenScale(2.0));
+  apzc->SetFrameMetrics(fm);
+  apzc->UpdateZoomConstraints(ZoomConstraints(true, true, CSSToScreenScale(0.25), CSSToScreenScale(4.0)));
+  // the visible area of the document in CSS pixels is x=300 y=300 w=50 h=100
+
+  if (aShouldTriggerPinch) {
+    EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(AtLeast(1));
+    EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
+  } else {
+    EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(AtMost(2));
+    EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(0);
+  }
+
+  if (aAllowedTouchBehaviors) {
+    apzc->SetTouchActionEnabled(true);
+  } else {
+    apzc->SetTouchActionEnabled(false);
+  }
+
+  int touchInputId = 0;
+  if (aUseGestureRecognizer) {
+    ApzcPinchWithTouchMoveInput(apzc, 250, 300, 1.25, touchInputId, aShouldTriggerPinch, aAllowedTouchBehaviors);
+  } else {
+    ApzcPinchWithPinchInput(apzc, 250, 300, 1.25, aShouldTriggerPinch, aAllowedTouchBehaviors);
+  }
+
+  fm = apzc->GetFrameMetrics();
+
+  if (aShouldTriggerPinch) {
+    // the visible area of the document in CSS pixels is now x=305 y=310 w=40 h=80
+    EXPECT_EQ(2.5f, fm.GetZoom().scale);
+    EXPECT_EQ(305, fm.GetScrollOffset().x);
+    EXPECT_EQ(310, fm.GetScrollOffset().y);
+  } else {
+    // The frame metrics should stay the same since touch-action:none makes
+    // apzc ignore pinch gestures.
+    EXPECT_EQ(2.0f, fm.GetZoom().scale);
+    EXPECT_EQ(300, fm.GetScrollOffset().x);
+    EXPECT_EQ(300, fm.GetScrollOffset().y);
+  }
+
+  // part 2 of the test, move to the top-right corner of the page and pinch and
+  // make sure we stay in the correct spot
+  fm.SetZoom(CSSToScreenScale(2.0));
+  fm.SetScrollOffset(CSSPoint(930, 5));
+  apzc->SetFrameMetrics(fm);
+  // the visible area of the document in CSS pixels is x=930 y=5 w=50 h=100
+
+  if (aUseGestureRecognizer) {
+    ApzcPinchWithTouchMoveInput(apzc, 250, 300, 0.5, touchInputId, aShouldTriggerPinch, aAllowedTouchBehaviors);
+  } else {
+    ApzcPinchWithPinchInput(apzc, 250, 300, 0.5, aShouldTriggerPinch, aAllowedTouchBehaviors);
+  }
+
+  fm = apzc->GetFrameMetrics();
+
+  if (aShouldTriggerPinch) {
+    // the visible area of the document in CSS pixels is now x=880 y=0 w=100 h=200
+    EXPECT_EQ(1.0f, fm.GetZoom().scale);
+    EXPECT_EQ(880, fm.GetScrollOffset().x);
+    EXPECT_EQ(0, fm.GetScrollOffset().y);
+  } else {
+    EXPECT_EQ(2.0f, fm.GetZoom().scale);
+    EXPECT_EQ(930, fm.GetScrollOffset().x);
+    EXPECT_EQ(5, fm.GetScrollOffset().y);
+  }
+
+  apzc->Destroy();
 }
 
 static nsEventStatus
 ApzcDown(AsyncPanZoomController* apzc, int aX, int aY, int& aTime) {
   MultiTouchInput mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, aTime, 0);
   mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(aX, aY), ScreenSize(0, 0), 0, 0));
   return apzc->ReceiveInputEvent(mti);
 }
@@ -346,91 +493,64 @@ ApzcTap(AsyncPanZoomController* apzc, in
 
 TEST_F(AsyncPanZoomControllerTester, Constructor) {
   // RefCounted class can't live in the stack
   nsRefPtr<MockContentController> mcc = new NiceMock<MockContentController>();
   nsRefPtr<TestAsyncPanZoomController> apzc = new TestAsyncPanZoomController(0, mcc);
   apzc->SetFrameMetrics(TestFrameMetrics());
 }
 
-TEST_F(AsyncPanZoomControllerTester, Pinch) {
-  nsRefPtr<MockContentController> mcc = new NiceMock<MockContentController>();
-  nsRefPtr<TestAsyncPanZoomController> apzc = new TestAsyncPanZoomController(0, mcc);
-
-  FrameMetrics fm;
-  fm.mViewport = CSSRect(0, 0, 980, 480);
-  fm.mCompositionBounds = ParentLayerIntRect(200, 200, 100, 200);
-  fm.mScrollableRect = CSSRect(0, 0, 980, 1000);
-  fm.SetScrollOffset(CSSPoint(300, 300));
-  fm.SetZoom(CSSToScreenScale(2.0));
-  apzc->SetFrameMetrics(fm);
-  apzc->UpdateZoomConstraints(ZoomConstraints(true, true, CSSToScreenScale(0.25), CSSToScreenScale(4.0)));
-  // the visible area of the document in CSS pixels is x=300 y=300 w=50 h=100
-
-  EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(AtLeast(1));
-  EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
-
-  ApzcPinch(apzc, 250, 300, 1.25);
+TEST_F(AsyncPanZoomControllerTester, Pinch_DefaultGestures_NoTouchAction) {
+  DoPinchTest(false, true);
+}
 
-  // the visible area of the document in CSS pixels is now x=305 y=310 w=40 h=80
-  fm = apzc->GetFrameMetrics();
-  EXPECT_EQ(2.5f, fm.GetZoom().scale);
-  EXPECT_EQ(305, fm.GetScrollOffset().x);
-  EXPECT_EQ(310, fm.GetScrollOffset().y);
+TEST_F(AsyncPanZoomControllerTester, Pinch_DefaultGestures_TouchActionNone) {
+  nsTArray<uint32_t> behaviors;
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::NONE);
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::NONE);
+  DoPinchTest(false, false, &behaviors);
+}
 
-  // part 2 of the test, move to the top-right corner of the page and pinch and
-  // make sure we stay in the correct spot
-  fm.SetZoom(CSSToScreenScale(2.0));
-  fm.SetScrollOffset(CSSPoint(930, 5));
-  apzc->SetFrameMetrics(fm);
-  // the visible area of the document in CSS pixels is x=930 y=5 w=50 h=100
-
-  ApzcPinch(apzc, 250, 300, 0.5);
-
-  // the visible area of the document in CSS pixels is now x=880 y=0 w=100 h=200
-  fm = apzc->GetFrameMetrics();
-  EXPECT_EQ(1.0f, fm.GetZoom().scale);
-  EXPECT_EQ(880, fm.GetScrollOffset().x);
-  EXPECT_EQ(0, fm.GetScrollOffset().y);
-
-  apzc->Destroy();
+TEST_F(AsyncPanZoomControllerTester, Pinch_DefaultGestures_TouchActionZoom) {
+  nsTArray<uint32_t> behaviors;
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
+  DoPinchTest(false, true, &behaviors);
 }
 
-TEST_F(AsyncPanZoomControllerTester, PinchWithTouchActionNone) {
-  nsRefPtr<MockContentController> mcc = new NiceMock<MockContentController>();
-  nsRefPtr<TestAsyncPanZoomController> apzc = new TestAsyncPanZoomController(0, mcc);
+TEST_F(AsyncPanZoomControllerTester, Pinch_DefaultGestures_TouchActionNotAllowZoom) {
+  nsTArray<uint32_t> behaviors;
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
+  DoPinchTest(false, false, &behaviors);
+}
 
-  FrameMetrics fm;
-  fm.mViewport = CSSRect(0, 0, 980, 480);
-  fm.mCompositionBounds = ParentLayerIntRect(200, 200, 100, 200);
-  fm.mScrollableRect = CSSRect(0, 0, 980, 1000);
-  fm.SetScrollOffset(CSSPoint(300, 300));
-  fm.SetZoom(CSSToScreenScale(2.0));
-  apzc->SetFrameMetrics(fm);
-  // the visible area of the document in CSS pixels is x=300 y=300 w=50 h=100
+TEST_F(AsyncPanZoomControllerTester, Pinch_UseGestureDetector_NoTouchAction) {
+  DoPinchTest(true, true);
+}
 
-  // Apzc's OnScaleEnd method calls once SendAsyncScrollDOMEvent and RequestContentRepaint methods,
-  // therefore we're setting these specific values.
-  EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(AtMost(1));
-  EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(AtMost(1));
-
-  nsTArray<uint32_t> values;
-  values.AppendElement(mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
-  values.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
-  apzc->SetTouchActionEnabled(true);
+TEST_F(AsyncPanZoomControllerTester, Pinch_UseGestureDetector_TouchActionNone) {
+  nsTArray<uint32_t> behaviors;
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::NONE);
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::NONE);
+  DoPinchTest(true, false, &behaviors);
+}
 
-  apzc->SetAllowedTouchBehavior(values);
-  ApzcPinch(apzc, 250, 300, 1.25);
+TEST_F(AsyncPanZoomControllerTester, Pinch_UseGestureDetector_TouchActionZoom) {
+  nsTArray<uint32_t> behaviors;
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
+  DoPinchTest(true, true, &behaviors);
+}
 
-  // The frame metrics should stay the same since touch-action:none makes
-  // apzc ignore pinch gestures.
-  fm = apzc->GetFrameMetrics();
-  EXPECT_EQ(2.0f, fm.GetZoom().scale);
-  EXPECT_EQ(300, fm.GetScrollOffset().x);
-  EXPECT_EQ(300, fm.GetScrollOffset().y);
+TEST_F(AsyncPanZoomControllerTester, Pinch_UseGestureDetector_TouchActionNotAllowZoom) {
+  nsTArray<uint32_t> behaviors;
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
+  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
+  DoPinchTest(true, false, &behaviors);
 }
 
 TEST_F(AsyncPanZoomControllerTester, Overzoom) {
   nsRefPtr<MockContentController> mcc = new NiceMock<MockContentController>();
   nsRefPtr<TestAsyncPanZoomController> apzc = new TestAsyncPanZoomController(0, mcc);
 
   FrameMetrics fm;
   fm.mViewport = CSSRect(0, 0, 100, 100);
@@ -440,17 +560,17 @@ TEST_F(AsyncPanZoomControllerTester, Ove
   fm.SetZoom(CSSToScreenScale(1.0));
   apzc->SetFrameMetrics(fm);
   apzc->UpdateZoomConstraints(ZoomConstraints(true, true, CSSToScreenScale(0.25), CSSToScreenScale(4.0)));
   // the visible area of the document in CSS pixels is x=10 y=0 w=100 h=100
 
   EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(AtLeast(1));
   EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
 
-  ApzcPinch(apzc, 50, 50, 0.5);
+  ApzcPinchWithPinchInput(apzc, 50, 50, 0.5, true);
 
   fm = apzc->GetFrameMetrics();
   EXPECT_EQ(0.8f, fm.GetZoom().scale);
   // bug 936721 - PGO builds introduce rounding error so
   // use a fuzzy match instead
   EXPECT_LT(abs(fm.GetScrollOffset().x), 1e-5);
   EXPECT_LT(abs(fm.GetScrollOffset().y), 1e-5);
 }
@@ -702,17 +822,17 @@ TEST_F(AsyncPanZoomControllerTester, Sho
     0, mcc, tm, AsyncPanZoomController::USE_GESTURE_DETECTOR);
 
   apzc->SetFrameMetrics(TestFrameMetrics());
   apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
   apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
 
   int time = 0;
   nsEventStatus status = ApzcTap(apzc, 10, 10, time, 100, mcc.get());
-  EXPECT_EQ(nsEventStatus_eIgnore, status);
+  EXPECT_EQ(nsEventStatus_eConsumeNoDefault, status);
 
   // This verifies that the single tap notification is sent after the
   // touchdown is fully processed. The ordering here is important.
   mcc->CheckHasDelayedTask();
 
   EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
   mcc->RunDelayedTask();
 
@@ -726,17 +846,17 @@ TEST_F(AsyncPanZoomControllerTester, Med
     0, mcc, tm, AsyncPanZoomController::USE_GESTURE_DETECTOR);
 
   apzc->SetFrameMetrics(TestFrameMetrics());
   apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
   apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
 
   int time = 0;
   nsEventStatus status = ApzcTap(apzc, 10, 10, time, 400, mcc.get());
-  EXPECT_EQ(nsEventStatus_eIgnore, status);
+  EXPECT_EQ(nsEventStatus_eConsumeNoDefault, status);
 
   // This verifies that the single tap notification is sent after the
   // touchdown is fully processed. The ordering here is important.
   mcc->CheckHasDelayedTask();
 
   EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
   mcc->RunDelayedTask();