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 20 kB image not shown  

Quelle  TestEventResult.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 "mozilla/EventForwards.h"
#include "mozilla/layers/LayersTypes.h"
#include <tuple>

class APZEventResultTester : public APZCTreeManagerTester {
 protected:
  UniquePtr<ScopedLayerTreeRegistration> registration;

  void UpdateOverscrollBehavior(OverscrollBehavior aX, OverscrollBehavior aY) {
    ModifyFrameMetrics(root, [aX, aY](ScrollMetadata& sm, FrameMetrics& _) {
      OverscrollBehaviorInfo overscroll;
      overscroll.mBehaviorX = aX;
      overscroll.mBehaviorY = aY;
      sm.SetOverscrollBehavior(overscroll);
    });
    UpdateHitTestingTree();
  }

  void SetScrollOffsetOnMainThread(const CSSPoint& aPoint) {
    RefPtr<TestAsyncPanZoomController> apzc = ApzcOf(root);

    ScrollMetadata metadata = apzc->GetScrollMetadata();
    metadata.GetMetrics().SetLayoutScrollOffset(aPoint);
    nsTArray<ScrollPositionUpdate> scrollUpdates;
    scrollUpdates.AppendElement(ScrollPositionUpdate::NewScroll(
        ScrollOrigin::Other, CSSPoint::ToAppUnits(aPoint)));
    metadata.SetScrollUpdates(scrollUpdates);
    metadata.GetMetrics().SetScrollGeneration(
        scrollUpdates.LastElement().GetGeneration());
    apzc->NotifyLayersUpdated(metadata, /*aIsFirstPaint=*/false,
                              /*aThisLayerTreeUpdated=*/true);
  }

  void CreateScrollableRootLayer() {
    const char* treeShape = "x";
    LayerIntRect layerVisibleRects[] = {
        LayerIntRect(0, 0, 100, 100),
    };
    CreateScrollData(treeShape, layerVisibleRects);
    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID,
                              CSSRect(0, 0, 200, 200));
    ModifyFrameMetrics(root, [](ScrollMetadata& sm, FrameMetrics& metrics) {
      metrics.SetIsRootContent(true);
    });
    registration = MakeUnique<ScopedLayerTreeRegistration>(LayersId{0}, mcc);
    UpdateHitTestingTree();
  }

  enum class PreventDefaultFlag { No, Yes };
  std::tuple<APZEventResult, APZHandledResult> TapDispatchToContent(
      const ScreenIntPoint& aPoint, PreventDefaultFlag aPreventDefaultFlag) {
    APZEventResult result =
        Tap(manager, aPoint, TimeDuration::FromMilliseconds(100));

    APZHandledResult delayedAnswer{APZHandledPlace::Invalid, SideBits::eNone,
                                   ScrollDirections()};
    manager->AddInputBlockCallback(
        result.mInputBlockId, [&](uint64_t id, const APZHandledResult& answer) {
          EXPECT_EQ(id, result.mInputBlockId);
          delayedAnswer = answer;
        });
    manager->SetAllowedTouchBehavior(result.mInputBlockId,
                                     {AllowedTouchBehavior::VERTICAL_PAN});
    manager->SetTargetAPZC(result.mInputBlockId, {result.mTargetGuid});
    manager->ContentReceivedInputBlock(
        result.mInputBlockId, aPreventDefaultFlag == PreventDefaultFlag::Yes);
    return {result, delayedAnswer};
  }

  void OverscrollDirectionsWithEventHandlerTest(
      PreventDefaultFlag aPreventDefaultFlag) {
    UpdateHitTestingTree();

    APZHandledPlace expectedPlace =
        aPreventDefaultFlag == PreventDefaultFlag::No
            ? APZHandledPlace::HandledByRoot
            : APZHandledPlace::HandledByContent;
    {
      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                         {CompositorHitTestFlags::eVisibleToHitTest,
                          CompositorHitTestFlags::eIrregularArea});
      auto [result, delayedHandledResult] =
          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
      EXPECT_EQ(result.GetHandledResult(), Nothing());
      EXPECT_EQ(
          delayedHandledResult,
          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
                            EitherScrollDirection}));
    }

    // overscroll-behavior: contain, contain.
    UpdateOverscrollBehavior(OverscrollBehavior::Contain,
                             OverscrollBehavior::Contain);
    {
      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                         {CompositorHitTestFlags::eVisibleToHitTest,
                          CompositorHitTestFlags::eIrregularArea});
      auto [result, delayedHandledResult] =
          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
      EXPECT_EQ(result.GetHandledResult(), Nothing());
      EXPECT_EQ(
          delayedHandledResult,
          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
                            ScrollDirections()}));
    }

    // overscroll-behavior: none, none.
    UpdateOverscrollBehavior(OverscrollBehavior::None,
                             OverscrollBehavior::None);
    {
      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                         {CompositorHitTestFlags::eVisibleToHitTest,
                          CompositorHitTestFlags::eIrregularArea});
      auto [result, delayedHandledResult] =
          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
      EXPECT_EQ(result.GetHandledResult(), Nothing());
      EXPECT_EQ(
          delayedHandledResult,
          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
                            ScrollDirections()}));
    }

    // overscroll-behavior: auto, none.
    UpdateOverscrollBehavior(OverscrollBehavior::Auto,
                             OverscrollBehavior::None);
    {
      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                         {CompositorHitTestFlags::eVisibleToHitTest,
                          CompositorHitTestFlags::eIrregularArea});
      auto [result, delayedHandledResult] =
          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
      EXPECT_EQ(result.GetHandledResult(), Nothing());
      EXPECT_EQ(
          delayedHandledResult,
          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
                            HorizontalScrollDirection}));
    }

    // overscroll-behavior: none, auto.
    UpdateOverscrollBehavior(OverscrollBehavior::None,
                             OverscrollBehavior::Auto);
    {
      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                         {CompositorHitTestFlags::eVisibleToHitTest,
                          CompositorHitTestFlags::eIrregularArea});
      auto [result, delayedHandledResult] =
          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
      EXPECT_EQ(result.GetHandledResult(), Nothing());
      EXPECT_EQ(
          delayedHandledResult,
          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
                            VerticalScrollDirection}));
    }
  }

  void ScrollableDirectionsWithEventHandlerTest(
      PreventDefaultFlag aPreventDefaultFlag) {
    UpdateHitTestingTree();

    APZHandledPlace expectedPlace =
        aPreventDefaultFlag == PreventDefaultFlag::No
            ? APZHandledPlace::HandledByRoot
            : APZHandledPlace::HandledByContent;
    {
      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                         {CompositorHitTestFlags::eVisibleToHitTest,
                          CompositorHitTestFlags::eIrregularArea});
      auto [result, delayedHandledResult] =
          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
      EXPECT_EQ(result.GetHandledResult(), Nothing());
      EXPECT_EQ(
          delayedHandledResult,
          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
                            EitherScrollDirection}));
    }

    // scroll down a bit.
    SetScrollOffsetOnMainThread(CSSPoint(0, 10));
    {
      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                         {CompositorHitTestFlags::eVisibleToHitTest,
                          CompositorHitTestFlags::eIrregularArea});
      auto [result, delayedHandledResult] =
          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
      EXPECT_EQ(result.GetHandledResult(), Nothing());
      EXPECT_EQ(delayedHandledResult,
                (APZHandledResult{
                    expectedPlace,
                    SideBits::eTop | SideBits::eBottom | SideBits::eRight,
                    EitherScrollDirection}));
    }

    // scroll to the bottom edge
    SetScrollOffsetOnMainThread(CSSPoint(0, 100));
    {
      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                         {CompositorHitTestFlags::eVisibleToHitTest,
                          CompositorHitTestFlags::eIrregularArea});
      auto [result, delayedHandledResult] =
          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
      EXPECT_EQ(result.GetHandledResult(), Nothing());
      EXPECT_EQ(
          delayedHandledResult,
          (APZHandledResult{expectedPlace, SideBits::eRight | SideBits::eTop,
                            EitherScrollDirection}));
    }

    // scroll to right a bit.
    SetScrollOffsetOnMainThread(CSSPoint(10, 100));
    {
      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                         {CompositorHitTestFlags::eVisibleToHitTest,
                          CompositorHitTestFlags::eIrregularArea});
      auto [result, delayedHandledResult] =
          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
      EXPECT_EQ(result.GetHandledResult(), Nothing());
      EXPECT_EQ(
          delayedHandledResult,
          (APZHandledResult{expectedPlace,
                            SideBits::eLeft | SideBits::eRight | SideBits::eTop,
                            EitherScrollDirection}));
    }

    // scroll to the right edge.
    SetScrollOffsetOnMainThread(CSSPoint(100, 100));
    {
      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                         {CompositorHitTestFlags::eVisibleToHitTest,
                          CompositorHitTestFlags::eIrregularArea});
      auto [result, delayedHandledResult] =
          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
      EXPECT_EQ(result.GetHandledResult(), Nothing());
      EXPECT_EQ(
          delayedHandledResult,
          (APZHandledResult{expectedPlace, SideBits::eTop | SideBits::eLeft,
                            EitherScrollDirection}));
    }
  }
};

TEST_F(APZEventResultTester, OverscrollDirections) {
  CreateScrollableRootLayer();

  TimeDuration tapDuration = TimeDuration::FromMilliseconds(100);

  // The default value of overscroll-behavior is auto.
  APZEventResult result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
  EXPECT_EQ(result.GetHandledResult()->mOverscrollDirections,
            EitherScrollDirection);

  // overscroll-behavior: contain, contain.
  UpdateOverscrollBehavior(OverscrollBehavior::Contain,
                           OverscrollBehavior::Contain);
  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
  EXPECT_EQ(result.GetHandledResult()->mOverscrollDirections,
            ScrollDirections());

  // overscroll-behavior: none, none.
  UpdateOverscrollBehavior(OverscrollBehavior::None, OverscrollBehavior::None);
  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
  EXPECT_EQ(result.GetHandledResult()->mOverscrollDirections,
            ScrollDirections());

  // overscroll-behavior: auto, none.
  UpdateOverscrollBehavior(OverscrollBehavior::Auto, OverscrollBehavior::None);
  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
  EXPECT_EQ(result.GetHandledResult()->mOverscrollDirections,
            HorizontalScrollDirection);

  // overscroll-behavior: none, auto.
  UpdateOverscrollBehavior(OverscrollBehavior::None, OverscrollBehavior::Auto);
  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
  EXPECT_EQ(result.GetHandledResult()->mOverscrollDirections,
            VerticalScrollDirection);
}

TEST_F(APZEventResultTester, ScrollableDirections) {
  CreateScrollableRootLayer();

  TimeDuration tapDuration = TimeDuration::FromMilliseconds(100);

  APZEventResult result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
  // scrollable to down/right.
  EXPECT_EQ(result.GetHandledResult()->mScrollableDirections,
            SideBits::eBottom | SideBits::eRight);

  // scroll down a bit.
  SetScrollOffsetOnMainThread(CSSPoint(0, 10));
  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
  // also scrollable toward top.
  EXPECT_EQ(result.GetHandledResult()->mScrollableDirections,
            SideBits::eTop | SideBits::eBottom | SideBits::eRight);

  // scroll to the bottom edge
  SetScrollOffsetOnMainThread(CSSPoint(0, 100));
  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
  EXPECT_EQ(result.GetHandledResult()->mScrollableDirections,
            SideBits::eRight | SideBits::eTop);

  // scroll to right a bit.
  SetScrollOffsetOnMainThread(CSSPoint(10, 100));
  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
  EXPECT_EQ(result.GetHandledResult()->mScrollableDirections,
            SideBits::eLeft | SideBits::eRight | SideBits::eTop);

  // scroll to the right edge.
  SetScrollOffsetOnMainThread(CSSPoint(100, 100));
  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
  EXPECT_EQ(result.GetHandledResult()->mScrollableDirections,
            SideBits::eLeft | SideBits::eTop);
}

class APZEventResultTesterMock : public APZEventResultTester {
 public:
  APZEventResultTesterMock() { CreateMockHitTester(); }
};

TEST_F(APZEventResultTesterMock, OverscrollDirectionsWithEventHandler) {
  CreateScrollableRootLayer();

  OverscrollDirectionsWithEventHandlerTest(PreventDefaultFlag::No);
}

TEST_F(APZEventResultTesterMock,
       OverscrollDirectionsWithPreventDefaultEventHandler) {
  CreateScrollableRootLayer();

  OverscrollDirectionsWithEventHandlerTest(PreventDefaultFlag::Yes);
}

TEST_F(APZEventResultTesterMock, ScrollableDirectionsWithEventHandler) {
  CreateScrollableRootLayer();

  ScrollableDirectionsWithEventHandlerTest(PreventDefaultFlag::No);
}

TEST_F(APZEventResultTesterMock,
       ScrollableDirectionsWithPreventDefaultEventHandler) {
  CreateScrollableRootLayer();

  ScrollableDirectionsWithEventHandlerTest(PreventDefaultFlag::Yes);
}

// Test that APZEventResult::GetHandledResult() is correctly
// populated.
TEST_F(APZEventResultTesterMock, HandledByRootApzcFlag) {
  // Create simple layer tree containing a dispatch-to-content region
  // that covers part but not all of its area.
  const char* treeShape = "x";
  LayerIntRect layerVisibleRects[] = {
      LayerIntRect(0, 0, 100, 100),
  };
  CreateScrollData(treeShape, layerVisibleRects);
  SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID,
                            CSSRect(0, 0, 100, 200));
  ModifyFrameMetrics(root, [](ScrollMetadata& sm, FrameMetrics& metrics) {
    metrics.SetIsRootContent(true);
  });
  // away from the scrolling container layer.
  registration = MakeUnique<ScopedLayerTreeRegistration>(LayersId{0}, mcc);
  UpdateHitTestingTree();

  // Tap the top half and check that we report that the event was
  // handled by the root APZC.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  APZEventResult result =
      TouchDown(manager, ScreenIntPoint(50, 25), mcc->Time());
  TouchUp(manager, ScreenIntPoint(50, 25), mcc->Time());
  EXPECT_EQ(result.GetHandledResult(),
            Some(APZHandledResult{APZHandledPlace::HandledByRoot,
                                  SideBits::eBottom, EitherScrollDirection}));

  // Tap the bottom half and check that we report that we're not
  // sure whether the event was handled by the root APZC.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                     {CompositorHitTestFlags::eVisibleToHitTest,
                      CompositorHitTestFlags::eIrregularArea});
  result = TouchDown(manager, ScreenIntPoint(50, 75), mcc->Time());
  TouchUp(manager, ScreenIntPoint(50, 75), mcc->Time());
  EXPECT_EQ(result.GetHandledResult(), Nothing());

  // Register an input block callback that will tell us the
  // delayed answer.
  APZHandledResult delayedAnswer{APZHandledPlace::Invalid, SideBits::eNone,
                                 ScrollDirections()};
  manager->AddInputBlockCallback(
      result.mInputBlockId, [&](uint64_t id, const APZHandledResult& answer) {
        EXPECT_EQ(id, result.mInputBlockId);
        delayedAnswer = answer;
      });

  // Send APZ the relevant notifications to allow it to process the
  // input block.
  manager->SetAllowedTouchBehavior(result.mInputBlockId,
                                   {AllowedTouchBehavior::VERTICAL_PAN});
  manager->SetTargetAPZC(result.mInputBlockId, {result.mTargetGuid});
  manager->ContentReceivedInputBlock(result.mInputBlockId,
                                     /*aPreventDefault=*/false);

  // Check that we received the delayed answer and it is what we expect.
  EXPECT_EQ(delayedAnswer,
            (APZHandledResult{APZHandledPlace::HandledByRoot, SideBits::eBottom,
                              EitherScrollDirection}));

  // Now repeat the tap on the bottom half, but simulate a prevent-default.
  // This time, we expect a delayed answer of `HandledByContent`.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                     {CompositorHitTestFlags::eVisibleToHitTest,
                      CompositorHitTestFlags::eIrregularArea});
  result = TouchDown(manager, ScreenIntPoint(50, 75), mcc->Time());
  TouchUp(manager, ScreenIntPoint(50, 75), mcc->Time());
  EXPECT_EQ(result.GetHandledResult(), Nothing());
  manager->AddInputBlockCallback(
      result.mInputBlockId, [&](uint64_t id, const APZHandledResult& answer) {
        EXPECT_EQ(id, result.mInputBlockId);
        delayedAnswer = answer;
      });
  manager->SetAllowedTouchBehavior(result.mInputBlockId,
                                   {AllowedTouchBehavior::VERTICAL_PAN});
  manager->SetTargetAPZC(result.mInputBlockId, {result.mTargetGuid});
  manager->ContentReceivedInputBlock(result.mInputBlockId,
                                     /*aPreventDefault=*/true);
  EXPECT_EQ(delayedAnswer,
            (APZHandledResult{APZHandledPlace::HandledByContent,
                              SideBits::eBottom, EitherScrollDirection}));

  // Shrink the scrollable area, now it's no longer scrollable.
  ModifyFrameMetrics(root, [](ScrollMetadata& sm, FrameMetrics& metrics) {
    metrics.SetScrollableRect(CSSRect(0, 0, 100, 100));
  });
  UpdateHitTestingTree();
  // Now repeat the tap on the bottom half with an event handler.
  // This time, we expect a delayed answer of `Unhandled`.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
                     {CompositorHitTestFlags::eVisibleToHitTest,
                      CompositorHitTestFlags::eIrregularArea});
  result = TouchDown(manager, ScreenIntPoint(50, 75), mcc->Time());
  TouchUp(manager, ScreenIntPoint(50, 75), mcc->Time());
  EXPECT_EQ(result.GetHandledResult(), Nothing());
  manager->AddInputBlockCallback(
      result.mInputBlockId, [&](uint64_t id, const APZHandledResult& answer) {
        EXPECT_EQ(id, result.mInputBlockId);
        delayedAnswer = answer;
      });
  manager->SetAllowedTouchBehavior(result.mInputBlockId,
                                   {AllowedTouchBehavior::VERTICAL_PAN});
  manager->SetTargetAPZC(result.mInputBlockId, {result.mTargetGuid});
  manager->ContentReceivedInputBlock(result.mInputBlockId,
                                     /*aPreventDefault=*/false);
  EXPECT_EQ(delayedAnswer,
            (APZHandledResult{APZHandledPlace::Unhandled, SideBits::eNone,
                              EitherScrollDirection}));

  // Repeat the tap on the bottom half, with no event handler.
  // Make sure we get an eager answer of `Unhandled`.
  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
  result = TouchDown(manager, ScreenIntPoint(50, 75), mcc->Time());
  TouchUp(manager, ScreenIntPoint(50, 75), mcc->Time());
  EXPECT_EQ(result.GetStatus(), nsEventStatus_eIgnore);
  EXPECT_EQ(result.GetHandledResult(),
            Some(APZHandledResult{APZHandledPlace::Unhandled, SideBits::eNone,
                                  EitherScrollDirection}));
}

Messung V0.5
C=94 H=94 G=93

¤ Dauer der Verarbeitung: 0.10 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.