1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "APZCBasicTester.h"
8 #include "APZTestCommon.h"
9 #include "InputUtils.h"
10 
11 class APZCPanningTester : public APZCBasicTester {
12  protected:
DoPanTest(bool aShouldTriggerScroll,bool aShouldBeConsumed,uint32_t aBehavior)13   void DoPanTest(bool aShouldTriggerScroll, bool aShouldBeConsumed,
14                  uint32_t aBehavior) {
15     if (aShouldTriggerScroll) {
16       // One repaint request for each pan.
17       EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(2);
18     } else {
19       EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(0);
20     }
21 
22     int touchStart = 50;
23     int touchEnd = 10;
24     ParentLayerPoint pointOut;
25     AsyncTransform viewTransformOut;
26 
27     nsTArray<uint32_t> allowedTouchBehaviors;
28     allowedTouchBehaviors.AppendElement(aBehavior);
29 
30     // Pan down
31     PanAndCheckStatus(apzc, touchStart, touchEnd, aShouldBeConsumed,
32                       &allowedTouchBehaviors);
33     apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
34 
35     if (aShouldTriggerScroll) {
36       EXPECT_EQ(ParentLayerPoint(0, -(touchEnd - touchStart)), pointOut);
37       EXPECT_NE(AsyncTransform(), viewTransformOut);
38     } else {
39       EXPECT_EQ(ParentLayerPoint(), pointOut);
40       EXPECT_EQ(AsyncTransform(), viewTransformOut);
41     }
42 
43     // Clear the fling from the previous pan, or stopping it will
44     // consume the next touchstart
45     apzc->CancelAnimation();
46 
47     // Pan back
48     PanAndCheckStatus(apzc, touchEnd, touchStart, aShouldBeConsumed,
49                       &allowedTouchBehaviors);
50     apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
51 
52     EXPECT_EQ(ParentLayerPoint(), pointOut);
53     EXPECT_EQ(AsyncTransform(), viewTransformOut);
54   }
55 
DoPanWithPreventDefaultTest()56   void DoPanWithPreventDefaultTest() {
57     MakeApzcWaitForMainThread();
58 
59     int touchStart = 50;
60     int touchEnd = 10;
61     ParentLayerPoint pointOut;
62     AsyncTransform viewTransformOut;
63     uint64_t blockId = 0;
64 
65     // Pan down
66     nsTArray<uint32_t> allowedTouchBehaviors;
67     allowedTouchBehaviors.AppendElement(
68         mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
69     PanAndCheckStatus(apzc, touchStart, touchEnd, true, &allowedTouchBehaviors,
70                       &blockId);
71 
72     // Send the signal that content has handled and preventDefaulted the touch
73     // events. This flushes the event queue.
74     apzc->ContentReceivedInputBlock(blockId, true);
75 
76     apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
77     EXPECT_EQ(ParentLayerPoint(), pointOut);
78     EXPECT_EQ(AsyncTransform(), viewTransformOut);
79 
80     apzc->AssertStateIsReset();
81   }
82 };
83 
TEST_F(APZCPanningTester,Pan)84 TEST_F(APZCPanningTester, Pan) {
85   SCOPED_GFX_PREF_BOOL("layout.css.touch_action.enabled", false);
86   // Velocity bias can cause extra repaint requests.
87   SCOPED_GFX_PREF_FLOAT("apz.velocity_bias", 0.0);
88   DoPanTest(true, true, mozilla::layers::AllowedTouchBehavior::NONE);
89 }
90 
91 // In the each of the following 4 pan tests we are performing two pan gestures:
92 // vertical pan from top to bottom and back - from bottom to top. According to
93 // the pointer-events/touch-action spec AUTO and PAN_Y touch-action values allow
94 // vertical scrolling while NONE and PAN_X forbid it. The first parameter of
95 // DoPanTest method specifies this behavior. However, the events will be marked
96 // as consumed even if the behavior in PAN_X, because the user could move their
97 // finger horizontally too - APZ has no way of knowing beforehand and so must
98 // consume the events.
TEST_F(APZCPanningTester,PanWithTouchActionAuto)99 TEST_F(APZCPanningTester, PanWithTouchActionAuto) {
100   SCOPED_GFX_PREF_BOOL("layout.css.touch_action.enabled", true);
101   // Velocity bias can cause extra repaint requests.
102   SCOPED_GFX_PREF_FLOAT("apz.velocity_bias", 0.0);
103   DoPanTest(true, true,
104             mozilla::layers::AllowedTouchBehavior::HORIZONTAL_PAN |
105                 mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
106 }
107 
TEST_F(APZCPanningTester,PanWithTouchActionNone)108 TEST_F(APZCPanningTester, PanWithTouchActionNone) {
109   SCOPED_GFX_PREF_BOOL("layout.css.touch_action.enabled", true);
110   // Velocity bias can cause extra repaint requests.
111   SCOPED_GFX_PREF_FLOAT("apz.velocity_bias", 0.0);
112   DoPanTest(false, false, 0);
113 }
114 
TEST_F(APZCPanningTester,PanWithTouchActionPanX)115 TEST_F(APZCPanningTester, PanWithTouchActionPanX) {
116   SCOPED_GFX_PREF_BOOL("layout.css.touch_action.enabled", true);
117   // Velocity bias can cause extra repaint requests.
118   SCOPED_GFX_PREF_FLOAT("apz.velocity_bias", 0.0);
119   DoPanTest(false, false,
120             mozilla::layers::AllowedTouchBehavior::HORIZONTAL_PAN);
121 }
122 
TEST_F(APZCPanningTester,PanWithTouchActionPanY)123 TEST_F(APZCPanningTester, PanWithTouchActionPanY) {
124   SCOPED_GFX_PREF_BOOL("layout.css.touch_action.enabled", true);
125   // Velocity bias can cause extra repaint requests.
126   SCOPED_GFX_PREF_FLOAT("apz.velocity_bias", 0.0);
127   DoPanTest(true, true, mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
128 }
129 
TEST_F(APZCPanningTester,PanWithPreventDefaultAndTouchAction)130 TEST_F(APZCPanningTester, PanWithPreventDefaultAndTouchAction) {
131   SCOPED_GFX_PREF_BOOL("layout.css.touch_action.enabled", true);
132   DoPanWithPreventDefaultTest();
133 }
134 
TEST_F(APZCPanningTester,PanWithPreventDefault)135 TEST_F(APZCPanningTester, PanWithPreventDefault) {
136   SCOPED_GFX_PREF_BOOL("layout.css.touch_action.enabled", false);
137   DoPanWithPreventDefaultTest();
138 }
139