Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/gfx/layers/apz/test/gtest/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 30 kB image not shown  

Quelle  TestAxisLock.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */


#include "APZCTreeManagerTester.h"
#include "APZTestCommon.h"

#include "InputUtils.h"
#include "gtest/gtest.h"

#include <cmath>

class APZCAxisLockCompatTester : public APZCTreeManagerTester,
                                 public testing::WithParamInterface<int> {
 public:
  APZCAxisLockCompatTester() : oldAxisLockMode(0) { CreateMockHitTester(); }

  int oldAxisLockMode;

  UniquePtr<ScopedLayerTreeRegistration> registration;

  RefPtr<TestAsyncPanZoomController> apzc;

  void SetUp() {
    APZCTreeManagerTester::SetUp();

    oldAxisLockMode = Preferences::GetInt("apz.axis_lock.mode");

    Preferences::SetInt("apz.axis_lock.mode", GetParam());
  }

  void TearDown() {
    APZCTreeManagerTester::TearDown();

    Preferences::SetInt("apz.axis_lock.mode", oldAxisLockMode);
  }

  static std::string PrintFromParam(const testing::TestParamInfo<int>& info) {
    switch (info.param) {
      case 0:
        return "FREE";
      case 1:
        return "STANDARD";
      case 2:
        return "STICKY";
      case 3:
        return "DOMINANT_AXIS";
      case 4:
        return "BREAKABLE";
      default:
        return "UNKNOWN";
    }
  }
};

class APZCAxisLockTester : public APZCTreeManagerTester {
 public:
  APZCAxisLockTester() { CreateMockHitTester(); }

  UniquePtr<ScopedLayerTreeRegistration> registration;

  RefPtr<TestAsyncPanZoomController> apzc;

  void SetupBasicTest() {
    const char* treeShape = "x";
    LayerIntRect layerVisibleRect[] = {
        LayerIntRect(0, 0, 100, 100),
    };
    CreateScrollData(treeShape, layerVisibleRect);
    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID,
                              CSSRect(0, 0, 500, 500));

    registration = MakeUnique<ScopedLayerTreeRegistration>(LayersId{0}, mcc);

    UpdateHitTestingTree();
  }

  void BreakStickyAxisLockTestGesture(const ScrollDirections& aDirections) {
    float panX = 0;
    float panY = 0;

    if (aDirections.contains(ScrollDirection::eVertical)) {
      panY = 30;
    }
    if (aDirections.contains(ScrollDirection::eHorizontal)) {
      panX = 30;
    }

    // Kick off the gesture that may lock onto an axis
    QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
    PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
               ScreenPoint(panX, panY), mcc->Time());
    mcc->AdvanceByMillis(5);
    apzc->AdvanceAnimations(mcc->GetSampleTime());

    QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
    PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
               ScreenPoint(panX, panY), mcc->Time());
  }

  void BreakStickyAxisLockTest(const ScrollDirections& aDirections) {
    // Create the gesture for the test.
    BreakStickyAxisLockTestGesture(aDirections);

    // Based on the scroll direction(s) ensure the state is what we expect.
    if (aDirections == ScrollDirection::eVertical) {
      apzc->AssertStateIsPanningLockedY();
      apzc->AssertAxisLocked(ScrollDirection::eVertical);
      EXPECT_GT(apzc->GetVelocityVector().y, 0);
      EXPECT_EQ(apzc->GetVelocityVector().x, 0);
    } else if (aDirections == ScrollDirection::eHorizontal) {
      apzc->AssertStateIsPanningLockedX();
      apzc->AssertAxisLocked(ScrollDirection::eHorizontal);
      EXPECT_GT(apzc->GetVelocityVector().x, 0);
      EXPECT_EQ(apzc->GetVelocityVector().y, 0);
    } else {
      apzc->AssertStateIsPanning();
      apzc->AssertNotAxisLocked();
      EXPECT_GT(apzc->GetVelocityVector().x, 0);
      EXPECT_GT(apzc->GetVelocityVector().y, 0);
    }

    // Cleanup for next test.
    apzc->AdvanceAnimationsUntilEnd();
  }
};

TEST_F(APZCAxisLockTester, BasicDominantAxisUse) {
  SCOPED_GFX_PREF_INT("apz.axis_lock.mode", 1);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.lock_angle", M_PI / 4.0f);

  SetupBasicTest();

  apzc = ApzcOf(root);

  // Kick off the initial gesture that triggers the momentum scroll.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(1, 2), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
             ScreenPoint(15, 30), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
             ScreenPoint(15, 30), mcc->Time());

  // Should be in a PANNING_LOCKED_Y state with no horizontal velocity.
  apzc->AssertStateIsPanningLockedY();
  apzc->AssertAxisLocked(ScrollDirection::eVertical);
  EXPECT_GT(apzc->GetVelocityVector().y, 0);
  EXPECT_EQ(apzc->GetVelocityVector().x, 0);

  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50),
             ScreenPoint(0, 0), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // Ensure that we have not panned on the horizontal axis.
  ParentLayerPoint panEndOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  EXPECT_EQ(panEndOffset.x, 0);

  // The lock onto the Y axis extends into momentum scroll.
  apzc->AssertAxisLocked(ScrollDirection::eVertical);

  // Start the momentum scroll.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_MOMENTUMSTART, manager,
             ScreenIntPoint(50, 50), ScreenPoint(30, 90), mcc->Time());
  mcc->AdvanceByMillis(10);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_MOMENTUMPAN, manager,
             ScreenIntPoint(50, 50), ScreenPoint(10, 30), mcc->Time());
  mcc->AdvanceByMillis(10);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_MOMENTUMPAN, manager,
             ScreenIntPoint(50, 50), ScreenPoint(10, 30), mcc->Time());
  mcc->AdvanceByMillis(10);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // In momentum locking mode, we should still be locked onto the Y axis.
  apzc->AssertStateIsPanMomentum();
  apzc->AssertAxisLocked(ScrollDirection::eVertical);
  EXPECT_GT(apzc->GetVelocityVector().y, 0);
  EXPECT_EQ(apzc->GetVelocityVector().x, 0);

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_MOMENTUMEND, manager,
             ScreenIntPoint(50, 50), ScreenPoint(0, 0), mcc->Time());

  // After momentum scroll end, ensure we are no longer locked onto an axis.
  apzc->AssertNotAxisLocked();

  // Wait until the end of the animation and ensure the final state is
  // reasonable.
  apzc->AdvanceAnimationsUntilEnd();
  ParentLayerPoint finalOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);

  // Ensure we have scrolled some amount on the Y axis in momentum scroll.
  EXPECT_GT(finalOffset.y, panEndOffset.y);
  EXPECT_EQ(finalOffset.x, 0.0f);
}

TEST_F(APZCAxisLockTester, NewGestureBreaksMomentumAxisLock) {
  SCOPED_GFX_PREF_INT("apz.axis_lock.mode", 1);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.lock_angle", M_PI / 4.0f);

  SetupBasicTest();

  apzc = ApzcOf(root);

  // Kick off the initial gesture that triggers the momentum scroll.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(2, 1), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
             ScreenPoint(30, 15), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
             ScreenPoint(30, 15), mcc->Time());

  // Should be in a PANNING_LOCKED_X state with no vertical velocity.
  apzc->AssertStateIsPanningLockedX();
  apzc->AssertAxisLocked(ScrollDirection::eHorizontal);
  EXPECT_GT(apzc->GetVelocityVector().x, 0);
  EXPECT_EQ(apzc->GetVelocityVector().y, 0);

  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50),
             ScreenPoint(0, 0), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // Double check that we have not panned on the vertical axis.
  ParentLayerPoint panEndOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  EXPECT_EQ(panEndOffset.y, 0);

  // Ensure that the axis locks extends into momentum scroll.
  apzc->AssertAxisLocked(ScrollDirection::eHorizontal);

  // Start the momentum scroll.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_MOMENTUMSTART, manager,
             ScreenIntPoint(50, 50), ScreenPoint(80, 40), mcc->Time());
  mcc->AdvanceByMillis(10);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_MOMENTUMPAN, manager,
             ScreenIntPoint(50, 50), ScreenPoint(20, 10), mcc->Time());
  mcc->AdvanceByMillis(10);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_MOMENTUMPAN, manager,
             ScreenIntPoint(50, 50), ScreenPoint(20, 10), mcc->Time());
  mcc->AdvanceByMillis(10);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // In momentum locking mode, we should still be locked onto the X axis.
  apzc->AssertStateIsPanMomentum();
  apzc->AssertAxisLocked(ScrollDirection::eHorizontal);
  EXPECT_GT(apzc->GetVelocityVector().x, 0);
  EXPECT_EQ(apzc->GetVelocityVector().y, 0);

  ParentLayerPoint beforeBreakOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  EXPECT_EQ(beforeBreakOffset.y, 0);
  // Ensure we have scrolled some amount on the X axis in momentum scroll.
  EXPECT_GT(beforeBreakOffset.x, panEndOffset.x);

  // Kick off the gesture that breaks the lock onto the X axis.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(1, 2), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  ParentLayerPoint afterBreakOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
             ScreenPoint(15, 30), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
             ScreenPoint(15, 30), mcc->Time());

  // The lock onto the X axis should be broken and we now should be locked
  // onto the Y axis.
  apzc->AssertStateIsPanningLockedY();
  apzc->AssertAxisLocked(ScrollDirection::eVertical);
  EXPECT_GT(apzc->GetVelocityVector().y, 0);
  EXPECT_EQ(apzc->GetVelocityVector().x, 0);

  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50),
             ScreenPoint(0, 0), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // The lock onto the Y axis extends into momentum scroll.
  apzc->AssertAxisLocked(ScrollDirection::eVertical);

  // Wait until the end of the animation and ensure the final state is
  // reasonable.
  apzc->AdvanceAnimationsUntilEnd();
  ParentLayerPoint finalOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);

  EXPECT_GT(finalOffset.y, 0);
  // Ensure that we did not scroll on the X axis after the vertical scroll
  // started.
  EXPECT_EQ(finalOffset.x, afterBreakOffset.x);
}

TEST_F(APZCAxisLockTester, BreakStickyAxisLock) {
  SCOPED_GFX_PREF_INT("apz.axis_lock.mode", 2);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.lock_angle", M_PI / 6.0f);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.breakout_angle", M_PI / 6.0f);

  SetupBasicTest();

  apzc = ApzcOf(root);

  // Start a gesture to get us locked onto the Y axis.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(0, 2), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // Ensure that we have locked onto the Y axis.
  apzc->AssertStateIsPanningLockedY();

  // Test switch to locking onto the X axis.
  BreakStickyAxisLockTest(ScrollDirection::eHorizontal);

  // Test switch back to locking onto the Y axis.
  BreakStickyAxisLockTest(ScrollDirection::eVertical);

  // Test breaking all axis locks from a Y axis lock.
  BreakStickyAxisLockTest(ScrollDirections(ScrollDirection::eHorizontal,
                                           ScrollDirection::eVertical));

  // We should be in a panning state.
  apzc->AssertStateIsPanning();
  apzc->AssertNotAxisLocked();

  // Lock back to the X axis.
  BreakStickyAxisLockTestGesture(ScrollDirection::eHorizontal);

  // End the gesture.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50),
             ScreenPoint(0, 0), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // Start a gesture to get us locked onto the X axis.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(2, 0), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // Ensure that we have locked onto the X axis.
  apzc->AssertStateIsPanningLockedX();

  // Test breaking all axis locks from a X axis lock.
  BreakStickyAxisLockTest(ScrollDirections(ScrollDirection::eHorizontal,
                                           ScrollDirection::eVertical));

  // We should be in a panning state.
  apzc->AssertStateIsPanning();
  apzc->AssertNotAxisLocked();

  // Test switch back to locking onto the Y axis.
  BreakStickyAxisLockTest(ScrollDirection::eVertical);
}

TEST_F(APZCAxisLockTester, BreakAxisLockByLockAngle) {
  SCOPED_GFX_PREF_INT("apz.axis_lock.mode", 2);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.lock_angle", M_PI / 4.0f);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.breakout_angle", M_PI / 8.0f);

  SetupBasicTest();

  apzc = ApzcOf(root);

  // Start a gesture to get us locked onto the Y axis.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(1, 10), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // Ensure that we have locked onto the Y axis.
  apzc->AssertStateIsPanningLockedY();

  // Stay within 45 degrees from the X axis, and more than 22.5 degrees from
  // the Y axis. This should break the Y lock and lock us to the X axis.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_PAN, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(12, 10), mcc->Time());
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // Ensure that we have locked onto the X axis.
  apzc->AssertStateIsPanningLockedX();

  // End the gesture.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50),
             ScreenPoint(0, 0), mcc->Time());
  apzc->AdvanceAnimations(mcc->GetSampleTime());
}

TEST_F(APZCAxisLockTester, TestCanBreakBreakableAxisLock) {
  SCOPED_GFX_PREF_INT("apz.axis_lock.mode", 4);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.lock_angle", M_PI / 4.0f);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.breakout_angle", M_PI / 8.0f);

  SetupBasicTest();

  apzc = ApzcOf(root);

  // Start a gesture to get us locked onto the Y axis.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(0, 10), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // Ensure that we have locked onto the Y axis.
  apzc->AssertStateIsPanningLockedY();

  // Break the Y axis in a way that would lock onto the X axis if the
  // AxisLockMode is STICKY, but should freely pan if it is BREAKABLE.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_PAN, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(10, 0), mcc->Time());
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // Ensure that we have broken the Y axis, and are not locked onto the X axis.
  apzc->AssertStateIsPanning();

  // Do a gesture that would re-lock on the Y axis if we were STICKY.
  // Should not re-lock.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_PAN, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(0, -10), mcc->Time());
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  // Ensure that we have not acquired a lock on the Y axis.
  apzc->AssertStateIsPanning();

  // End the gesture.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50),
             ScreenPoint(0, 0), mcc->Time());
  apzc->AdvanceAnimations(mcc->GetSampleTime());
}

TEST_F(APZCAxisLockTester, TestDominantAxisScrolling) {
  SCOPED_GFX_PREF_INT("apz.axis_lock.mode", 3);

  int panY;
  int panX;

  SetupBasicTest();

  apzc = ApzcOf(root);

  ParentLayerPoint lastOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncPanZoomController::eForEventHandling);

  // In dominant axis mode, test pan gesture events with varying gesture
  // angles and ensure that we only pan on one axis.
  for (panX = 0, panY = 50; panY >= 0; panY -= 10, panX += 5) {
    // Gesture that should be locked onto one axis
    QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
    PanGesture(PanGestureInput::PANGESTURE_START, manager,
               ScreenIntPoint(50, 50), ScreenIntPoint(panX, panY), mcc->Time());
    mcc->AdvanceByMillis(5);
    apzc->AdvanceAnimations(mcc->GetSampleTime());

    QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
    PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
               ScreenPoint(static_cast<float>(panX), static_cast<float>(panY)),
               mcc->Time());
    mcc->AdvanceByMillis(5);
    apzc->AdvanceAnimations(mcc->GetSampleTime());

    QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
    PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50),
               ScreenPoint(0, 0), mcc->Time());
    apzc->AdvanceAnimationsUntilEnd();

    ParentLayerPoint scrollOffset = apzc->GetCurrentAsyncScrollOffset(
        AsyncPanZoomController::eForEventHandling);

    if (panX > panY) {
      // If we're closer to the X axis ensure that we moved on the horizontal
      // axis and there was no movement on the vertical axis.
      EXPECT_GT(scrollOffset.x, lastOffset.x);
      EXPECT_EQ(scrollOffset.y, lastOffset.y);
    } else {
      // If we're closer to the Y axis ensure that we moved on the vertical
      // axis and there was no movement on the horizontal axis.
      EXPECT_GT(scrollOffset.y, lastOffset.y);
      EXPECT_EQ(scrollOffset.x, lastOffset.x);
    }

    lastOffset = scrollOffset;
  }
}

TEST_F(APZCAxisLockTester, TestCanScrollWithAxisLock) {
  SCOPED_GFX_PREF_INT("apz.axis_lock.mode", 2);

  SetupBasicTest();

  apzc = ApzcOf(root);

  // The axis locks do not impact CanScroll()
  apzc->SetAxisLocked(ScrollDirection::eHorizontal, true);
  EXPECT_EQ(apzc->CanScroll(ParentLayerPoint(10, 0)), true);

  apzc->SetAxisLocked(ScrollDirection::eHorizontal, false);
  apzc->SetAxisLocked(ScrollDirection::eVertical, true);
  EXPECT_EQ(apzc->CanScroll(ParentLayerPoint(0, 10)), true);
}

TEST_F(APZCAxisLockTester, TestScrollHandoffAxisLockConflict) {
  SCOPED_GFX_PREF_INT("apz.axis_lock.mode", 2);

  // Create two scrollable frames. One parent frame with one child.
  const char* treeShape = "x(x)";
  LayerIntRect layerVisibleRect[] = {
      LayerIntRect(0, 0, 100, 100),
      LayerIntRect(0, 0, 100, 100),
  };
  CreateScrollData(treeShape, layerVisibleRect);
  SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID,
                            CSSRect(0, 0, 500, 500));
  SetScrollableFrameMetrics(layers[1], ScrollableLayerGuid::START_SCROLL_ID + 1,
                            CSSRect(0, 0, 500, 500));
  SetScrollHandoff(layers[1], root);

  registration = MakeUnique<ScopedLayerTreeRegistration>(LayersId{0}, mcc);

  UpdateHitTestingTree();

  RefPtr<TestAsyncPanZoomController> rootApzc = ApzcOf(root);
  apzc = ApzcOf(layers[1]);

  // Create a gesture on the y-axis that should lock the x axis.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID + 1);
  PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(0, 2), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID + 1);
  PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
             ScreenPoint(0, 15), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID + 1);
  PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50),
             ScreenPoint(0, 0), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimationsUntilEnd();

  // We are locked onto the y-axis.
  apzc->AssertAxisLocked(ScrollDirection::eVertical);

  // There should be movement in the child.
  ParentLayerPoint childCurrentOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  EXPECT_GT(childCurrentOffset.y, 0);
  EXPECT_EQ(childCurrentOffset.x, 0);

  // There should be no movement in the parent.
  ParentLayerPoint parentCurrentOffset = rootApzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  EXPECT_EQ(parentCurrentOffset.y, 0);
  EXPECT_EQ(parentCurrentOffset.x, 0);

  // Create a gesture on the x-axis, that should be directed
  // at the child, even if the x-axis is locked.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID + 1);
  PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(2, 0), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID + 1);
  PanGesture(PanGestureInput::PANGESTURE_PAN, apzc, ScreenIntPoint(50, 50),
             ScreenPoint(15, 0), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimations(mcc->GetSampleTime());

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID + 1);
  PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50),
             ScreenPoint(0, 0), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimationsUntilEnd();

  // We broke the y-axis lock and are now locked onto the x-axis.
  apzc->AssertAxisLocked(ScrollDirection::eHorizontal);

  // There should be some movement in the child on the x-axis.
  ParentLayerPoint childFinalOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  EXPECT_GT(childFinalOffset.x, 0);

  // There should still be no movement in the parent.
  ParentLayerPoint parentFinalOffset = rootApzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  EXPECT_EQ(parentFinalOffset.y, 0);
  EXPECT_EQ(parentFinalOffset.x, 0);
}

// The delta from the initial pan gesture should be reflected in the
// current offset for all axis locking modes.
TEST_P(APZCAxisLockCompatTester, TestPanGestureStart) {
  const char* treeShape = "x";
  LayerIntRect layerVisibleRect[] = {
      LayerIntRect(0, 0, 100, 100),
  };
  CreateScrollData(treeShape, layerVisibleRect);
  SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID,
                            CSSRect(0, 0, 500, 500));

  registration = MakeUnique<ScopedLayerTreeRegistration>(LayersId{0}, mcc);

  UpdateHitTestingTree();

  apzc = ApzcOf(root);

  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50),
             ScreenIntPoint(0, 10), mcc->Time());
  mcc->AdvanceByMillis(5);
  apzc->AdvanceAnimationsUntilEnd();
  ParentLayerPoint currentOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);

  EXPECT_EQ(currentOffset.x, 0);
  EXPECT_EQ(currentOffset.y, 10);
}

#ifdef MOZ_WIDGET_ANDROID
TEST_F(APZCAxisLockTester, TouchScrollWithStickyAxisLocking) {
  SCOPED_GFX_PREF_INT("apz.axis_lock.mode", 2);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.breakout_threshold", 10);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.breakout_angle", 0.392699);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.lock_angle", 0.523599);

  SetupBasicTest();

  apzc = ApzcOf(root);

  // Scroll somewhere into the middle of the scroll range, so that we have
  // lots of space to scroll in both directions.
  apzc->GetFrameMetrics().SetVisualScrollOffset(CSSPoint(250, 250));

  UpdateHitTestingTree();

  // Trigger a touch scroll that will cause us to lock onto the
  // y-axis.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  Unused << TouchDown(apzc, ScreenIntPoint(50, 50), mcc->Time());
  mcc->AdvanceByMillis(50);

  Unused << TouchMove(apzc, ScreenIntPoint(50, 60), mcc->Time());
  mcc->AdvanceByMillis(400);

  Unused << TouchMove(apzc, ScreenIntPoint(50, 70), mcc->Time());
  mcc->AdvanceByMillis(400);

  apzc->AssertStateIsPanningLockedY();

  ParentLayerPoint currentOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  ParentLayerPoint lastOffset = currentOffset;

  // A touch scroll in the reverse direction with slight movement
  // on the x-axis should not cause us to break the y-axis lock.
  Unused << TouchMove(apzc, ScreenIntPoint(55, 60), mcc->Time());
  mcc->AdvanceByMillis(200);

  // We should have scrolled only on the y-axis.
  currentOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  EXPECT_GT(currentOffset.y, lastOffset.y);
  EXPECT_EQ(currentOffset.x, lastOffset.x);
  lastOffset = currentOffset;
  apzc->AssertStateIsPanningLockedY();

  Unused << TouchMove(apzc, ScreenIntPoint(60, 50), mcc->Time());
  mcc->AdvanceByMillis(200);

  // We should continue to scroll only on the y-axis.
  currentOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  EXPECT_GT(currentOffset.y, lastOffset.y);
  EXPECT_EQ(currentOffset.x, lastOffset.x);
  apzc->AssertStateIsPanningLockedY();
  lastOffset = currentOffset;

  Unused << TouchMove(apzc, ScreenIntPoint(60, 40), mcc->Time());
  mcc->AdvanceByMillis(200);

  currentOffset = apzc->GetCurrentAsyncScrollOffset(
      AsyncTransformConsumer::eForEventHandling);
  EXPECT_GT(currentOffset.y, lastOffset.y);
  EXPECT_EQ(currentOffset.x, lastOffset.x);
  apzc->AssertStateIsPanningLockedY();
  lastOffset = currentOffset;

  Unused << TouchUp(apzc, ScreenIntPoint(65, 40), mcc->Time());
}
#endif

// TODO(bug 1915260): Make this test pass.
#ifdef MOZ_WIDGET_ANDROID
TEST_F(APZCAxisLockTester, TouchScrollWithStickyAxisLockingBug1915260) {
  SCOPED_GFX_PREF_INT("apz.axis_lock.mode", 2);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.breakout_threshold", 10);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.breakout_angle", 0.392699);
  SCOPED_GFX_PREF_FLOAT("apz.axis_lock.lock_angle", 0.523599);

  SetupBasicTest();

  apzc = ApzcOf(root);

  // Scroll somewhere into the middle of the scroll range, so that we have
  // lots of space to scroll in both directions.
  apzc->GetFrameMetrics().SetVisualScrollOffset(CSSPoint(250, 250));

  // Trigger a touch scroll that will cause us to lock onto the
  // y-axis.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  Unused << TouchDown(apzc, ScreenIntPoint(50, 50), mcc->Time());
  mcc->AdvanceByMillis(10);

  Unused << TouchMove(apzc, ScreenIntPoint(50, 60), mcc->Time());
  mcc->AdvanceByMillis(200);

  Unused << TouchMove(apzc, ScreenIntPoint(50, 70), mcc->Time());
  mcc->AdvanceByMillis(200);

  // We should be locked on the y-axis at this point.
  // apzc->AssertStateIsPanningLockedY();

  // Assuming the last event in the historical touch scroll buffer
  // we use to determine touch scroll direction is (50,60), this
  // touch-move event will exceed the breakout threshold and will
  // be considered to be a horizontal scroll, thus breaking the
  // lock onto the y-axis.
  Unused << TouchMove(apzc, ScreenIntPoint(60, 60), mcc->Time());
  mcc->AdvanceByMillis(100);
  // TODO(bug 1915260): We should still be be locked on the y-axis at this
  // point.
  // apzc->AssertStateIsPanningLockedY();

  Unused << TouchUp(apzc, ScreenIntPoint(65, 45), mcc->Time());
}
#endif

// All APZCAxisLockCompatTester tests should be run for each apz.axis_lock.mode.
// If another mode is added, the value should be added to this list.
INSTANTIATE_TEST_SUITE_P(APZCAxisLockCompat, APZCAxisLockCompatTester,
                         testing::Values(0, 1, 2, 3, 4),
                         APZCAxisLockCompatTester::PrintFromParam);

Messung V0.5
C=89 H=99 G=94

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.