Bug 1337990 - Add a gtest for cross-apzc axis lock with touch-action disabled. r=kats draft
authorBotond Ballo <botond@mozilla.com>
Fri, 10 Feb 2017 17:37:15 -0500
changeset 484102 d758db722edb6bcbfc17824f0ce4aefa5a7c66ff
parent 484101 83ef27a26c36f3b7bf72e92ca64a4628a2d6eb9f
child 484103 1b81771499bf74b9feaa5bd530234f643d0267c3
push id45398
push userbballo@mozilla.com
push dateTue, 14 Feb 2017 21:04:50 +0000
reviewerskats
bugs1337990
milestone54.0a1
Bug 1337990 - Add a gtest for cross-apzc axis lock with touch-action disabled. r=kats MozReview-Commit-ID: 3ycm6B4dNen
gfx/layers/apz/test/gtest/APZTestCommon.h
gfx/layers/apz/test/gtest/TestScrollHandoff.cpp
--- a/gfx/layers/apz/test/gtest/APZTestCommon.h
+++ b/gfx/layers/apz/test/gtest/APZTestCommon.h
@@ -251,16 +251,31 @@ public:
     EXPECT_EQ(NOTHING, mState);
   }
 
   void AssertStateIsFling() const {
     ReentrantMonitorAutoEnter lock(mMonitor);
     EXPECT_EQ(FLING, mState);
   }
 
+  void AssertAxisLocked(ScrollDirection aDirection) const {
+    ReentrantMonitorAutoEnter lock(mMonitor);
+    switch (aDirection) {
+    case ScrollDirection::NONE:
+      EXPECT_EQ(PANNING, mState);
+      break;
+    case ScrollDirection::HORIZONTAL:
+      EXPECT_EQ(PANNING_LOCKED_X, mState);
+      break;
+    case ScrollDirection::VERTICAL:
+      EXPECT_EQ(PANNING_LOCKED_Y, mState);
+      break;
+    }
+  }
+
   void AdvanceAnimationsUntilEnd(const TimeDuration& aIncrement = TimeDuration::FromMilliseconds(10)) {
     while (AdvanceAnimations(mcc->Time())) {
       mcc->AdvanceBy(aIncrement);
     }
   }
 
   bool SampleContentTransformForFrame(AsyncTransform* aOutTransform,
                                       ParentLayerPoint& aScrollOffset,
@@ -287,16 +302,23 @@ class APZCTesterBase : public ::testing:
 public:
   APZCTesterBase() {
     mcc = new NiceMock<MockContentControllerDelayed>();
   }
 
   enum class PanOptions {
     None = 0,
     KeepFingerDown = 0x1,
+    /*
+     * Do not adjust the touch-start coordinates to overcome the touch-start
+     * tolerance threshold. If this option is passed, it's up to the caller
+     * to pass in coordinates that are sufficient to overcome the touch-start
+     * tolerance *and* cause the desired amount of scrolling.
+     */
+    ExactCoordinates = 0x2
   };
 
   template<class InputReceiver>
   void Tap(const RefPtr<InputReceiver>& aTarget, const ScreenIntPoint& aPoint,
            TimeDuration aTapLength,
            nsEventStatus (*aOutEventStatuses)[2] = nullptr,
            uint64_t* aOutInputBlockId = nullptr);
 
@@ -413,30 +435,43 @@ APZCTesterBase::Pan(const RefPtr<InputRe
                     uint64_t* aOutInputBlockId)
 {
   // Reduce the touch start and move tolerance to a tiny value.
   // We can't use a scoped pref because this value might be read at some later
   // time when the events are actually processed, rather than when we deliver
   // them.
   gfxPrefs::SetAPZTouchStartTolerance(1.0f / 1000.0f);
   gfxPrefs::SetAPZTouchMoveTolerance(0.0f);
-  const int OVERCOME_TOUCH_TOLERANCE = 1;
+  int overcomeTouchToleranceX = 0;
+  int overcomeTouchToleranceY = 0;
+  if (!(aOptions & PanOptions::ExactCoordinates)) {
+    // Have the direction of the adjustment to overcome the touch tolerance
+    // match the direction of the entire gesture, otherwise we run into
+    // trouble such as accidentally activating the axis lock.
+    if (aTouchStart.x != aTouchEnd.x) {
+      overcomeTouchToleranceX = 1;
+    }
+    if (aTouchStart.y != aTouchEnd.y) {
+      overcomeTouchToleranceY = 1;
+    }
+  }
 
   const TimeDuration TIME_BETWEEN_TOUCH_EVENT = TimeDuration::FromMilliseconds(50);
 
   // Even if the caller doesn't care about the block id, we need it to set the
   // allowed touch behaviour below, so make sure aOutInputBlockId is non-null.
   uint64_t blockId;
   if (!aOutInputBlockId) {
     aOutInputBlockId = &blockId;
   }
 
   // Make sure the move is large enough to not be handled as a tap
   nsEventStatus status = TouchDown(aTarget,
-      ScreenIntPoint(aTouchStart.x, aTouchStart.y + OVERCOME_TOUCH_TOLERANCE),
+      ScreenIntPoint(aTouchStart.x + overcomeTouchToleranceX,
+                     aTouchStart.y + overcomeTouchToleranceY),
       mcc->Time(), aOutInputBlockId);
   if (aOutEventStatuses) {
     (*aOutEventStatuses)[0] = status;
   }
 
   mcc->AdvanceBy(TIME_BETWEEN_TOUCH_EVENT);
 
   // Allowed touch behaviours must be set after sending touch-start.
--- a/gfx/layers/apz/test/gtest/TestScrollHandoff.cpp
+++ b/gfx/layers/apz/test/gtest/TestScrollHandoff.cpp
@@ -121,16 +121,28 @@ protected:
     EXPECT_GT(childVelocityAfterFling2,
               childVelocityAfterFling1 * kAcceleration / 2);
 
     // We should not have accelerated twice.
     // The division by 4 is to account for friction.
     EXPECT_LE(childVelocityAfterFling2,
               childVelocityAfterFling1 * kAcceleration * kAcceleration / 4);
   }
+
+  void TestCrossApzcAxisLock() {
+    SCOPED_GFX_PREF(APZAxisLockMode, int32_t, 1);
+
+    CreateScrollHandoffLayerTree1();
+
+    RefPtr<TestAsyncPanZoomController> childApzc = ApzcOf(layers[1]);
+    Pan(childApzc, ScreenIntPoint(10, 60), ScreenIntPoint(15, 90),
+        PanOptions::KeepFingerDown | PanOptions::ExactCoordinates);
+
+    childApzc->AssertAxisLocked(ScrollDirection::VERTICAL);
+  }
 };
 
 // Here we test that if the processing of a touch block is deferred while we
 // wait for content to send a prevent-default message, overscroll is still
 // handed off correctly when the block is processed.
 TEST_F(APZScrollHandoffTester, DeferredInputEventProcessing) {
   // Set up the APZC tree.
   CreateScrollHandoffLayerTree1();
@@ -514,8 +526,13 @@ TEST_F(APZScrollHandoffTester, Immediate
 
   // Allow the fling to run its course. The fling should also be handed off.
   childApzc->AdvanceAnimationsUntilEnd();
   parentApzc->AdvanceAnimationsUntilEnd();
 
   // Verify that the parent scrolled from the fling.
   EXPECT_GT(parentApzc->GetFrameMetrics().GetScrollOffset().y, 10);
 }
+
+TEST_F(APZScrollHandoffTester, CrossApzcAxisLock_NoTouchAction) {
+  SCOPED_GFX_PREF(TouchActionEnabled, bool, false);
+  TestCrossApzcAxisLock();
+}