Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/layers/apz/test/gtest/TestPinching.cpp
Line
Count
Source (jump to first uncovered line)
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 APZCPinchTester : public APZCBasicTester {
12
public:
13
  explicit APZCPinchTester(AsyncPanZoomController::GestureBehavior aGestureBehavior = AsyncPanZoomController::DEFAULT_GESTURES)
14
    : APZCBasicTester(aGestureBehavior)
15
0
  {
16
0
  }
17
18
protected:
19
  FrameMetrics GetPinchableFrameMetrics()
20
0
  {
21
0
    FrameMetrics fm;
22
0
    fm.SetCompositionBounds(ParentLayerRect(0, 0, 100, 200));
23
0
    fm.SetScrollableRect(CSSRect(0, 0, 980, 1000));
24
0
    fm.SetScrollOffset(CSSPoint(300, 300));
25
0
    fm.SetViewport(CSSRect(300, 300, 100, 200));
26
0
    fm.SetZoom(CSSToParentLayerScale2D(2.0, 2.0));
27
0
    // APZC only allows zooming on the root scrollable frame.
28
0
    fm.SetIsRootContent(true);
29
0
    // the visible area of the document in CSS pixels is x=300 y=300 w=50 h=100
30
0
    return fm;
31
0
  }
32
33
  void DoPinchTest(bool aShouldTriggerPinch,
34
                   nsTArray<uint32_t> *aAllowedTouchBehaviors = nullptr)
35
0
  {
36
0
    apzc->SetFrameMetrics(GetPinchableFrameMetrics());
37
0
    MakeApzcZoomable();
38
0
39
0
    if (aShouldTriggerPinch) {
40
0
      // One repaint request for each gesture.
41
0
      EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(2);
42
0
    } else {
43
0
      EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(0);
44
0
    }
45
0
46
0
    int touchInputId = 0;
47
0
    if (mGestureBehavior == AsyncPanZoomController::USE_GESTURE_DETECTOR) {
48
0
      PinchWithTouchInputAndCheckStatus(apzc, ScreenIntPoint(250, 300), 1.25,
49
0
          touchInputId, aShouldTriggerPinch, aAllowedTouchBehaviors);
50
0
    } else {
51
0
      PinchWithPinchInputAndCheckStatus(apzc, ScreenIntPoint(250, 300), 1.25,
52
0
          aShouldTriggerPinch);
53
0
    }
54
0
55
0
    apzc->AssertStateIsReset();
56
0
57
0
    FrameMetrics fm = apzc->GetFrameMetrics();
58
0
59
0
    if (aShouldTriggerPinch) {
60
0
      // the visible area of the document in CSS pixels is now x=325 y=330 w=40 h=80
61
0
      EXPECT_EQ(2.5f, fm.GetZoom().ToScaleFactor().scale);
62
0
      EXPECT_EQ(325, fm.GetScrollOffset().x);
63
0
      EXPECT_EQ(330, fm.GetScrollOffset().y);
64
0
    } else {
65
0
      // The frame metrics should stay the same since touch-action:none makes
66
0
      // apzc ignore pinch gestures.
67
0
      EXPECT_EQ(2.0f, fm.GetZoom().ToScaleFactor().scale);
68
0
      EXPECT_EQ(300, fm.GetScrollOffset().x);
69
0
      EXPECT_EQ(300, fm.GetScrollOffset().y);
70
0
    }
71
0
72
0
    // part 2 of the test, move to the top-right corner of the page and pinch and
73
0
    // make sure we stay in the correct spot
74
0
    fm.SetZoom(CSSToParentLayerScale2D(2.0, 2.0));
75
0
    fm.SetScrollOffset(CSSPoint(930, 5));
76
0
    apzc->SetFrameMetrics(fm);
77
0
    // the visible area of the document in CSS pixels is x=930 y=5 w=50 h=100
78
0
79
0
    if (mGestureBehavior == AsyncPanZoomController::USE_GESTURE_DETECTOR) {
80
0
      PinchWithTouchInputAndCheckStatus(apzc, ScreenIntPoint(250, 300), 0.5,
81
0
          touchInputId, aShouldTriggerPinch, aAllowedTouchBehaviors);
82
0
    } else {
83
0
      PinchWithPinchInputAndCheckStatus(apzc, ScreenIntPoint(250, 300), 0.5,
84
0
          aShouldTriggerPinch);
85
0
    }
86
0
87
0
    apzc->AssertStateIsReset();
88
0
89
0
    fm = apzc->GetFrameMetrics();
90
0
91
0
    if (aShouldTriggerPinch) {
92
0
      // the visible area of the document in CSS pixels is now x=805 y=0 w=100 h=200
93
0
      EXPECT_EQ(1.0f, fm.GetZoom().ToScaleFactor().scale);
94
0
      EXPECT_EQ(805, fm.GetScrollOffset().x);
95
0
      EXPECT_EQ(0, fm.GetScrollOffset().y);
96
0
    } else {
97
0
      EXPECT_EQ(2.0f, fm.GetZoom().ToScaleFactor().scale);
98
0
      EXPECT_EQ(930, fm.GetScrollOffset().x);
99
0
      EXPECT_EQ(5, fm.GetScrollOffset().y);
100
0
    }
101
0
  }
102
};
103
104
class APZCPinchGestureDetectorTester : public APZCPinchTester {
105
public:
106
  APZCPinchGestureDetectorTester()
107
    : APZCPinchTester(AsyncPanZoomController::USE_GESTURE_DETECTOR)
108
0
  {
109
0
  }
110
111
0
  void DoPinchWithPreventDefaultTest() {
112
0
    FrameMetrics originalMetrics = GetPinchableFrameMetrics();
113
0
    apzc->SetFrameMetrics(originalMetrics);
114
0
115
0
    MakeApzcWaitForMainThread();
116
0
    MakeApzcZoomable();
117
0
118
0
    int touchInputId = 0;
119
0
    uint64_t blockId = 0;
120
0
    PinchWithTouchInput(apzc, ScreenIntPoint(250, 300), 1.25, touchInputId,
121
0
        nullptr, nullptr, &blockId);
122
0
123
0
    // Send the prevent-default notification for the touch block
124
0
    apzc->ContentReceivedInputBlock(blockId, true);
125
0
126
0
    // verify the metrics didn't change (i.e. the pinch was ignored)
127
0
    FrameMetrics fm = apzc->GetFrameMetrics();
128
0
    EXPECT_EQ(originalMetrics.GetZoom(), fm.GetZoom());
129
0
    EXPECT_EQ(originalMetrics.GetScrollOffset().x, fm.GetScrollOffset().x);
130
0
    EXPECT_EQ(originalMetrics.GetScrollOffset().y, fm.GetScrollOffset().y);
131
0
132
0
    apzc->AssertStateIsReset();
133
0
  }
134
};
135
136
class APZCPinchLockingTester : public APZCPinchTester {
137
private:
138
  static const int mDPI = 160;
139
140
  ScreenIntPoint mFocus;
141
  float mSpan;
142
143
public:
144
  APZCPinchLockingTester()
145
    : APZCPinchTester(AsyncPanZoomController::USE_GESTURE_DETECTOR)
146
    , mFocus(ScreenIntPoint(200, 300))
147
    , mSpan(10.0)
148
0
  {
149
0
  }
150
151
0
  virtual void SetUp() {
152
0
    APZCPinchTester::SetUp();
153
0
    tm->SetDPI(mDPI);
154
0
    apzc->SetFrameMetrics(GetPinchableFrameMetrics());
155
0
    MakeApzcZoomable();
156
0
157
0
    apzc->ReceiveInputEvent(
158
0
        CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_START,
159
0
                                mFocus, mSpan, mSpan),
160
0
        nullptr);
161
0
  }
162
163
0
  void twoFingerPan() {
164
0
    ScreenCoord panDistance
165
0
      = gfxPrefs::APZPinchLockScrollLockThreshold() * 1.2 * tm->GetDPI();
166
0
167
0
    mFocus = ScreenIntPoint(
168
0
      (int) (mFocus.x + panDistance),
169
0
      (int) (mFocus.y)
170
0
    );
171
0
172
0
    apzc->ReceiveInputEvent(
173
0
        CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE,
174
0
                                mFocus, mSpan, mSpan),
175
0
        nullptr);
176
0
  }
177
178
0
  void twoFingerZoom() {
179
0
    float pinchDistance
180
0
      = gfxPrefs::APZPinchLockSpanBreakoutThreshold() * 1.2 * tm->GetDPI();
181
0
182
0
    float newSpan = mSpan + pinchDistance;
183
0
184
0
    apzc->ReceiveInputEvent(
185
0
        CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE,
186
0
                                mFocus, newSpan, mSpan),
187
0
        nullptr);
188
0
    mSpan = newSpan;
189
0
  }
190
191
0
  bool isPinchLockActive() {
192
0
    FrameMetrics originalMetrics = apzc->GetFrameMetrics();
193
0
194
0
    // Send a small scale input to the APZC
195
0
    float pinchDistance
196
0
      = gfxPrefs::APZPinchLockSpanBreakoutThreshold() * 0.8 * tm->GetDPI();
197
0
    apzc->ReceiveInputEvent(
198
0
        CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE,
199
0
                                mFocus, mSpan + pinchDistance, mSpan),
200
0
        nullptr);
201
0
202
0
    FrameMetrics result = apzc->GetFrameMetrics();
203
0
    bool lockActive = originalMetrics.GetZoom() == result.GetZoom()
204
0
      && originalMetrics.GetScrollOffset().x == result.GetScrollOffset().x
205
0
      && originalMetrics.GetScrollOffset().y == result.GetScrollOffset().y;
206
0
207
0
    // Avoid side effects, reset to original frame metrics
208
0
    apzc->SetFrameMetrics(originalMetrics);
209
0
    return lockActive;
210
0
  }
211
};
212
213
0
TEST_F(APZCPinchTester, Pinch_DefaultGestures_NoTouchAction) {
214
0
  SCOPED_GFX_PREF(TouchActionEnabled, bool, false);
215
0
  DoPinchTest(true);
216
0
}
217
218
0
TEST_F(APZCPinchGestureDetectorTester, Pinch_UseGestureDetector_NoTouchAction) {
219
0
  SCOPED_GFX_PREF(TouchActionEnabled, bool, false);
220
0
  DoPinchTest(true);
221
0
}
222
223
0
TEST_F(APZCPinchGestureDetectorTester, Pinch_UseGestureDetector_TouchActionNone) {
224
0
  SCOPED_GFX_PREF(TouchActionEnabled, bool, true);
225
0
  nsTArray<uint32_t> behaviors = { mozilla::layers::AllowedTouchBehavior::NONE,
226
0
                                   mozilla::layers::AllowedTouchBehavior::NONE };
227
0
  DoPinchTest(false, &behaviors);
228
0
}
229
230
0
TEST_F(APZCPinchGestureDetectorTester, Pinch_UseGestureDetector_TouchActionZoom) {
231
0
  SCOPED_GFX_PREF(TouchActionEnabled, bool, true);
232
0
  nsTArray<uint32_t> behaviors;
233
0
  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
234
0
  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
235
0
  DoPinchTest(true, &behaviors);
236
0
}
237
238
0
TEST_F(APZCPinchGestureDetectorTester, Pinch_UseGestureDetector_TouchActionNotAllowZoom) {
239
0
  SCOPED_GFX_PREF(TouchActionEnabled, bool, true);
240
0
  nsTArray<uint32_t> behaviors;
241
0
  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN);
242
0
  behaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::PINCH_ZOOM);
243
0
  DoPinchTest(false, &behaviors);
244
0
}
245
246
0
TEST_F(APZCPinchGestureDetectorTester, Pinch_UseGestureDetector_TouchActionNone_NoAPZZoom) {
247
0
  SCOPED_GFX_PREF(TouchActionEnabled, bool, true);
248
0
  SCOPED_GFX_PREF(APZAllowZooming, bool, false);
249
0
250
0
  // Since we are preventing the pinch action via touch-action we should not be
251
0
  // sending the pinch gesture notifications that would normally be sent when
252
0
  // APZAllowZooming is false.
253
0
  EXPECT_CALL(*mcc, NotifyPinchGesture(_, _, _, _)).Times(0);
254
0
  nsTArray<uint32_t> behaviors = { mozilla::layers::AllowedTouchBehavior::NONE,
255
0
                                   mozilla::layers::AllowedTouchBehavior::NONE };
256
0
  DoPinchTest(false, &behaviors);
257
0
}
258
259
0
TEST_F(APZCPinchGestureDetectorTester, Pinch_PreventDefault) {
260
0
  DoPinchWithPreventDefaultTest();
261
0
}
262
263
0
TEST_F(APZCPinchGestureDetectorTester, Pinch_PreventDefault_NoAPZZoom) {
264
0
  SCOPED_GFX_PREF(APZAllowZooming, bool, false);
265
0
266
0
  // Since we are preventing the pinch action we should not be sending the pinch
267
0
  // gesture notifications that would normally be sent when APZAllowZooming is
268
0
  // false.
269
0
  EXPECT_CALL(*mcc, NotifyPinchGesture(_, _, _, _)).Times(0);
270
0
271
0
  DoPinchWithPreventDefaultTest();
272
0
}
273
274
0
TEST_F(APZCPinchGestureDetectorTester, Panning_TwoFingerFling_ZoomDisabled) {
275
0
  SCOPED_GFX_PREF(APZFlingMinVelocityThreshold, float, 0.0f);
276
0
277
0
  apzc->SetFrameMetrics(GetPinchableFrameMetrics());
278
0
  MakeApzcUnzoomable();
279
0
280
0
  // Perform a two finger pan
281
0
  int touchInputId = 0;
282
0
  uint64_t blockId = 0;
283
0
  PinchWithTouchInput(apzc, ScreenIntPoint(100, 200), ScreenIntPoint(100, 100),
284
0
      1, touchInputId, nullptr, nullptr, &blockId);
285
0
286
0
  // Expect to be in a flinging state
287
0
  apzc->AssertStateIsFling();
288
0
}
289
290
0
TEST_F(APZCPinchGestureDetectorTester, Panning_TwoFingerFling_ZoomEnabled) {
291
0
  SCOPED_GFX_PREF(APZFlingMinVelocityThreshold, float, 0.0f);
292
0
293
0
  apzc->SetFrameMetrics(GetPinchableFrameMetrics());
294
0
  MakeApzcZoomable();
295
0
296
0
  // Perform a two finger pan
297
0
  int touchInputId = 0;
298
0
  uint64_t blockId = 0;
299
0
  PinchWithTouchInput(apzc, ScreenIntPoint(100, 200), ScreenIntPoint(100, 100),
300
0
      1, touchInputId, nullptr, nullptr, &blockId);
301
0
302
0
  // Expect to NOT be in flinging state
303
0
  apzc->AssertStateIsReset();
304
0
}
305
306
0
TEST_F(APZCPinchGestureDetectorTester, Panning_TwoThenOneFingerFling_ZoomEnabled) {
307
0
  SCOPED_GFX_PREF(APZFlingMinVelocityThreshold, float, 0.0f);
308
0
309
0
  apzc->SetFrameMetrics(GetPinchableFrameMetrics());
310
0
  MakeApzcZoomable();
311
0
312
0
  // Perform a two finger pan lifting only the first finger
313
0
  int touchInputId = 0;
314
0
  uint64_t blockId = 0;
315
0
  PinchWithTouchInput(apzc, ScreenIntPoint(100, 200), ScreenIntPoint(100, 100),
316
0
      1, touchInputId, nullptr, nullptr, &blockId, PinchOptions::LiftFinger2);
317
0
318
0
  // Lift second finger after a pause
319
0
  mcc->AdvanceBy(TimeDuration::FromMilliseconds(50));
320
0
  TouchUp(apzc, ScreenIntPoint(100, 100), mcc->Time());
321
0
322
0
  // Expect to NOT be in flinging state
323
0
  apzc->AssertStateIsReset();
324
0
}
325
326
0
TEST_F(APZCPinchTester, Panning_TwoFinger_ZoomDisabled) {
327
0
  // set up APZ
328
0
  apzc->SetFrameMetrics(GetPinchableFrameMetrics());
329
0
  MakeApzcUnzoomable();
330
0
331
0
  nsEventStatus statuses[3];  // scalebegin, scale, scaleend
332
0
  PinchWithPinchInput(apzc, ScreenIntPoint(250, 350), ScreenIntPoint(200, 300),
333
0
      10, &statuses);
334
0
335
0
  FrameMetrics fm = apzc->GetFrameMetrics();
336
0
337
0
  // It starts from (300, 300), then moves the focus point from (250, 350) to
338
0
  // (200, 300) pans by (50, 50) screen pixels, but there is a 2x zoom, which
339
0
  // causes the scroll offset to change by half of that (25, 25) pixels.
340
0
  EXPECT_EQ(325, fm.GetScrollOffset().x);
341
0
  EXPECT_EQ(325, fm.GetScrollOffset().y);
342
0
  EXPECT_EQ(2.0, fm.GetZoom().ToScaleFactor().scale);
343
0
}
344
345
0
TEST_F(APZCPinchTester, Panning_Beyond_LayoutViewport) {
346
0
  apzc->SetFrameMetrics(GetPinchableFrameMetrics());
347
0
  MakeApzcZoomable();
348
0
349
0
  // Case 1 - visual viewport is still inside layout viewport.
350
0
  Pan(apzc, 350, 300, PanOptions::NoFling);
351
0
  FrameMetrics fm = apzc->GetFrameMetrics();
352
0
  // It starts from (300, 300) pans by (0, 50) screen pixels, but there is a
353
0
  // 2x zoom, which causes the scroll offset to change by half of that (0, 25).
354
0
  // But the visual viewport is still inside the layout viewport.
355
0
  EXPECT_EQ(300, fm.GetScrollOffset().x);
356
0
  EXPECT_EQ(325, fm.GetScrollOffset().y);
357
0
  EXPECT_EQ(300, fm.GetViewport().X());
358
0
  EXPECT_EQ(300, fm.GetViewport().Y());
359
0
360
0
  // Case 2 - visual viewport crosses the bottom boundary of the layout
361
0
  // viewport.
362
0
  Pan(apzc, 525, 325, PanOptions::NoFling);
363
0
  fm = apzc->GetFrameMetrics();
364
0
  // It starts from (300, 325) pans by (0, 200) screen pixels, but there is a
365
0
  // 2x zoom, which causes the scroll offset to change by half of that
366
0
  // (0, 100). The visual viewport crossed the bottom boundary of the layout
367
0
  // viewport by 25px.
368
0
  EXPECT_EQ(300, fm.GetScrollOffset().x);
369
0
  EXPECT_EQ(425, fm.GetScrollOffset().y);
370
0
  EXPECT_EQ(300, fm.GetViewport().X());
371
0
  EXPECT_EQ(325, fm.GetViewport().Y());
372
0
373
0
  // Case 3 - visual viewport crosses the top boundary of the layout viewport.
374
0
  Pan(apzc, 425, 775, PanOptions::NoFling);
375
0
  fm = apzc->GetFrameMetrics();
376
0
  // It starts from (300, 425) pans by (0, -350) screen pixels, but there is a
377
0
  // 2x zoom, which causes the scroll offset to change by half of that
378
0
  // (0, -175). The visual viewport crossed the top of the layout viewport by
379
0
  // 75px.
380
0
  EXPECT_EQ(300, fm.GetScrollOffset().x);
381
0
  EXPECT_EQ(250, fm.GetScrollOffset().y);
382
0
  EXPECT_EQ(300, fm.GetViewport().X());
383
0
  EXPECT_EQ(250, fm.GetViewport().Y());
384
0
385
0
  // Case 4 - visual viewport crosses the left boundary of the layout viewport.
386
0
  Pan(apzc, ScreenIntPoint(150, 10), ScreenIntPoint(350, 10), PanOptions::NoFling);
387
0
  fm = apzc->GetFrameMetrics();
388
0
  // It starts from (300, 250) pans by (-200, 0) screen pixels, but there is a
389
0
  // 2x zoom, which causes the scroll offset to change by half of that
390
0
  // (-100, 0). The visual viewport crossed the left boundary of the layout
391
0
  // viewport by 100px.
392
0
  EXPECT_EQ(200, fm.GetScrollOffset().x);
393
0
  EXPECT_EQ(250, fm.GetScrollOffset().y);
394
0
  EXPECT_EQ(200, fm.GetViewport().X());
395
0
  EXPECT_EQ(250, fm.GetViewport().Y());
396
0
397
0
  // Case 5 - visual viewport crosses the right boundary of the layout viewport.
398
0
  Pan(apzc, ScreenIntPoint(350, 10), ScreenIntPoint(150, 10), PanOptions::NoFling);
399
0
  fm = apzc->GetFrameMetrics();
400
0
  // It starts from (200, 250) pans by (200, 0) screen pixels, but there is a
401
0
  // 2x zoom, which causes the scroll offset to change by half of that
402
0
  // (100, 0). The visual viewport crossed the right boundary of the layout
403
0
  // viewport by 50px.
404
0
  EXPECT_EQ(300, fm.GetScrollOffset().x);
405
0
  EXPECT_EQ(250, fm.GetScrollOffset().y);
406
0
  EXPECT_EQ(250, fm.GetViewport().X());
407
0
  EXPECT_EQ(250, fm.GetViewport().Y());
408
0
409
0
  // Case 6 - visual viewport crosses both the vertical and horizontal
410
0
  // boundaries of the layout viewport by moving diagonally towards the
411
0
  // top-right corner.
412
0
  Pan(apzc, ScreenIntPoint(350, 200), ScreenIntPoint(150, 400), PanOptions::NoFling);
413
0
  fm = apzc->GetFrameMetrics();
414
0
  // It starts from (300, 250) pans by (200, -200) screen pixels, but there is
415
0
  // a 2x zoom, which causes the scroll offset to change by half of that
416
0
  // (100, -100). The visual viewport moved by (100, -100) outside the
417
0
  // boundary of the layout viewport.
418
0
  EXPECT_EQ(400, fm.GetScrollOffset().x);
419
0
  EXPECT_EQ(150, fm.GetScrollOffset().y);
420
0
  EXPECT_EQ(350, fm.GetViewport().X());
421
0
  EXPECT_EQ(150, fm.GetViewport().Y());
422
0
}
423
424
0
TEST_F(APZCPinchGestureDetectorTester, Pinch_APZZoom_Disabled) {
425
0
  SCOPED_GFX_PREF(APZAllowZooming, bool, false);
426
0
427
0
  FrameMetrics originalMetrics = GetPinchableFrameMetrics();
428
0
  apzc->SetFrameMetrics(originalMetrics);
429
0
430
0
  // When APZAllowZooming is false, the ZoomConstraintsClient produces
431
0
  // ZoomConstraints with mAllowZoom set to false.
432
0
  MakeApzcUnzoomable();
433
0
434
0
  // With APZAllowZooming false, we expect the NotifyPinchGesture function to
435
0
  // get called as the pinch progresses, but the metrics shouldn't change.
436
0
  EXPECT_CALL(*mcc, NotifyPinchGesture(PinchGestureInput::PINCHGESTURE_START, apzc->GetGuid(), LayoutDeviceCoord(0), _)).Times(1);
437
0
  EXPECT_CALL(*mcc, NotifyPinchGesture(PinchGestureInput::PINCHGESTURE_SCALE, apzc->GetGuid(), _, _)).Times(AtLeast(1));
438
0
  EXPECT_CALL(*mcc, NotifyPinchGesture(PinchGestureInput::PINCHGESTURE_END, apzc->GetGuid(), LayoutDeviceCoord(0), _)).Times(1);
439
0
440
0
  int touchInputId = 0;
441
0
  uint64_t blockId = 0;
442
0
  PinchWithTouchInput(apzc, ScreenIntPoint(250, 300), 1.25, touchInputId,
443
0
      nullptr, nullptr, &blockId);
444
0
445
0
  // verify the metrics didn't change (i.e. the pinch was ignored inside APZ)
446
0
  FrameMetrics fm = apzc->GetFrameMetrics();
447
0
  EXPECT_EQ(originalMetrics.GetZoom(), fm.GetZoom());
448
0
  EXPECT_EQ(originalMetrics.GetScrollOffset().x, fm.GetScrollOffset().x);
449
0
  EXPECT_EQ(originalMetrics.GetScrollOffset().y, fm.GetScrollOffset().y);
450
0
451
0
  apzc->AssertStateIsReset();
452
0
}
453
454
0
TEST_F(APZCPinchGestureDetectorTester, Pinch_NoSpan) {
455
0
  SCOPED_GFX_PREF(APZAllowZooming, bool, false);
456
0
  SCOPED_GFX_PREF(TouchActionEnabled, bool, false);
457
0
458
0
  FrameMetrics originalMetrics = GetPinchableFrameMetrics();
459
0
  apzc->SetFrameMetrics(originalMetrics);
460
0
461
0
  // When APZAllowZooming is false, the ZoomConstraintsClient produces
462
0
  // ZoomConstraints with mAllowZoom set to false.
463
0
  MakeApzcUnzoomable();
464
0
465
0
  // With APZAllowZooming false, we expect the NotifyPinchGesture function to
466
0
  // get called as the pinch progresses, but the metrics shouldn't change.
467
0
  EXPECT_CALL(*mcc, NotifyPinchGesture(PinchGestureInput::PINCHGESTURE_START, apzc->GetGuid(), LayoutDeviceCoord(0), _)).Times(1);
468
0
  EXPECT_CALL(*mcc, NotifyPinchGesture(PinchGestureInput::PINCHGESTURE_SCALE, apzc->GetGuid(), _, _)).Times(AtLeast(1));
469
0
  EXPECT_CALL(*mcc, NotifyPinchGesture(PinchGestureInput::PINCHGESTURE_END, apzc->GetGuid(), LayoutDeviceCoord(0), _)).Times(1);
470
0
471
0
  int inputId = 0;
472
0
  ScreenIntPoint focus(250, 300);
473
0
474
0
  // Do a pinch holding a zero span and moving the focus by y=100
475
0
476
0
  MultiTouchInput mtiStart = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, 0, TimeStamp(), 0);
477
0
  mtiStart.mTouches.AppendElement(CreateSingleTouchData(inputId, focus));
478
0
  mtiStart.mTouches.AppendElement(CreateSingleTouchData(inputId + 1, focus));
479
0
  apzc->ReceiveInputEvent(mtiStart, nullptr);
480
0
481
0
  focus.y -= 35 + 1; // this is to get over the PINCH_START_THRESHOLD in GestureEventListener.cpp
482
0
  MultiTouchInput mtiMove1 = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, 0, TimeStamp(), 0);
483
0
  mtiMove1.mTouches.AppendElement(CreateSingleTouchData(inputId, focus));
484
0
  mtiMove1.mTouches.AppendElement(CreateSingleTouchData(inputId + 1, focus));
485
0
  apzc->ReceiveInputEvent(mtiMove1, nullptr);
486
0
487
0
  focus.y -= 100; // do a two-finger scroll of 100 screen pixels
488
0
  MultiTouchInput mtiMove2 = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, 0, TimeStamp(), 0);
489
0
  mtiMove2.mTouches.AppendElement(CreateSingleTouchData(inputId, focus));
490
0
  mtiMove2.mTouches.AppendElement(CreateSingleTouchData(inputId + 1, focus));
491
0
  apzc->ReceiveInputEvent(mtiMove2, nullptr);
492
0
493
0
  MultiTouchInput mtiEnd = MultiTouchInput(MultiTouchInput::MULTITOUCH_END, 0, TimeStamp(), 0);
494
0
  mtiEnd.mTouches.AppendElement(CreateSingleTouchData(inputId, focus));
495
0
  mtiEnd.mTouches.AppendElement(CreateSingleTouchData(inputId + 1, focus));
496
0
  apzc->ReceiveInputEvent(mtiEnd, nullptr);
497
0
498
0
  // Done, check the metrics to make sure we scrolled by 100 screen pixels,
499
0
  // which is 50 CSS pixels for the pinchable frame metrics.
500
0
501
0
  FrameMetrics fm = apzc->GetFrameMetrics();
502
0
  EXPECT_EQ(originalMetrics.GetZoom(), fm.GetZoom());
503
0
  EXPECT_EQ(originalMetrics.GetScrollOffset().x, fm.GetScrollOffset().x);
504
0
  EXPECT_EQ(originalMetrics.GetScrollOffset().y + 50, fm.GetScrollOffset().y);
505
0
506
0
  apzc->AssertStateIsReset();
507
0
}
508
509
0
TEST_F(APZCPinchTester, Pinch_TwoFinger_APZZoom_Disabled_Bug1354185) {
510
0
  // Set up APZ such that mZoomConstraints.mAllowZoom is false.
511
0
  SCOPED_GFX_PREF(APZAllowZooming, bool, false);
512
0
  apzc->SetFrameMetrics(GetPinchableFrameMetrics());
513
0
  MakeApzcUnzoomable();
514
0
515
0
  // We expect a repaint request for scrolling.
516
0
  EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
517
0
518
0
  // Send only the PINCHGESTURE_START and PINCHGESTURE_SCALE events,
519
0
  // in order to trigger a call to AsyncPanZoomController::OnScale
520
0
  // but not to AsyncPanZoomController::OnScaleEnd.
521
0
  ScreenIntPoint aFocus(250, 350);
522
0
  ScreenIntPoint aSecondFocus(200, 300);
523
0
  float aScale = 10;
524
0
  apzc->ReceiveInputEvent(
525
0
      CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_START,
526
0
                              aFocus, 10.0, 10.0),
527
0
      nullptr);
528
0
529
0
  apzc->ReceiveInputEvent(
530
0
      CreatePinchGestureInput(PinchGestureInput::PINCHGESTURE_SCALE,
531
0
                              aSecondFocus, 10.0 * aScale, 10.0),
532
0
      nullptr);
533
0
}
534
535
0
TEST_F(APZCPinchLockingTester, Pinch_Locking_Free) {
536
0
  SCOPED_GFX_PREF(APZPinchLockMode, int32_t, 0); // PINCH_FREE
537
0
538
0
  twoFingerPan();
539
0
  EXPECT_FALSE(isPinchLockActive());
540
0
}
541
542
0
TEST_F(APZCPinchLockingTester, Pinch_Locking_Normal_Lock) {
543
0
  SCOPED_GFX_PREF(APZPinchLockMode, int32_t, 1); // PINCH_NORMAL
544
0
545
0
  twoFingerPan();
546
0
  EXPECT_TRUE(isPinchLockActive());
547
0
}
548
549
0
TEST_F(APZCPinchLockingTester, Pinch_Locking_Normal_Lock_Break) {
550
0
  SCOPED_GFX_PREF(APZPinchLockMode, int32_t, 1); // PINCH_NORMAL
551
0
552
0
  twoFingerPan();
553
0
  twoFingerZoom();
554
0
  EXPECT_TRUE(isPinchLockActive());
555
0
}
556
557
0
TEST_F(APZCPinchLockingTester, Pinch_Locking_Sticky_Lock) {
558
0
  SCOPED_GFX_PREF(APZPinchLockMode, int32_t, 2); // PINCH_STICKY
559
0
560
0
  twoFingerPan();
561
0
  EXPECT_TRUE(isPinchLockActive());
562
0
}
563
564
0
TEST_F(APZCPinchLockingTester, Pinch_Locking_Sticky_Lock_Break) {
565
0
  SCOPED_GFX_PREF(APZPinchLockMode, int32_t, 2); // PINCH_STICKY
566
0
567
0
  twoFingerPan();
568
0
  twoFingerZoom();
569
0
  EXPECT_FALSE(isPinchLockActive());
570
0
}
571
572
0
TEST_F(APZCPinchLockingTester, Pinch_Locking_Sticky_Lock_Break_Lock) {
573
0
  SCOPED_GFX_PREF(APZPinchLockMode, int32_t, 2); // PINCH_STICKY
574
0
575
0
  twoFingerPan();
576
0
  twoFingerZoom();
577
0
  twoFingerPan();
578
0
  EXPECT_TRUE(isPinchLockActive());
579
0
}
580