tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestEventResult.cpp (20616B)


      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 "APZCTreeManagerTester.h"
      8 #include "APZTestCommon.h"
      9 #include "InputUtils.h"
     10 #include "mozilla/EventForwards.h"
     11 #include "mozilla/layers/LayersTypes.h"
     12 #include <tuple>
     13 
     14 using LayersUpdateFlags = AsyncPanZoomController::LayersUpdateFlags;
     15 
     16 class APZEventResultTester : public APZCTreeManagerTester {
     17 protected:
     18  UniquePtr<ScopedLayerTreeRegistration> registration;
     19 
     20  void UpdateOverscrollBehavior(OverscrollBehavior aX, OverscrollBehavior aY) {
     21    ModifyFrameMetrics(root, [aX, aY](ScrollMetadata& sm, FrameMetrics& _) {
     22      OverscrollBehaviorInfo overscroll;
     23      overscroll.mBehaviorX = aX;
     24      overscroll.mBehaviorY = aY;
     25      sm.SetOverscrollBehavior(overscroll);
     26    });
     27    UpdateHitTestingTree();
     28  }
     29 
     30  void SetScrollOffsetOnMainThread(const CSSPoint& aPoint) {
     31    RefPtr<TestAsyncPanZoomController> apzc = ApzcOf(root);
     32 
     33    ScrollMetadata metadata = apzc->GetScrollMetadata();
     34    metadata.GetMetrics().SetLayoutScrollOffset(aPoint);
     35    nsTArray<ScrollPositionUpdate> scrollUpdates;
     36    scrollUpdates.AppendElement(ScrollPositionUpdate::NewScroll(
     37        ScrollOrigin::Other, CSSPoint::ToAppUnits(aPoint)));
     38    metadata.SetScrollUpdates(scrollUpdates);
     39    metadata.GetMetrics().SetScrollGeneration(
     40        scrollUpdates.LastElement().GetGeneration());
     41    apzc->NotifyLayersUpdated(metadata,
     42                              LayersUpdateFlags{.mIsFirstPaint = false,
     43                                                .mThisLayerTreeUpdated = true});
     44  }
     45 
     46  void CreateScrollableRootLayer() {
     47    const char* treeShape = "x";
     48    LayerIntRect layerVisibleRects[] = {
     49        LayerIntRect(0, 0, 100, 100),
     50    };
     51    CreateScrollData(treeShape, layerVisibleRects);
     52    SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID,
     53                              CSSRect(0, 0, 200, 200));
     54    ModifyFrameMetrics(root, [](ScrollMetadata& sm, FrameMetrics& metrics) {
     55      metrics.SetIsRootContent(true);
     56    });
     57    registration = MakeUnique<ScopedLayerTreeRegistration>(LayersId{0}, mcc);
     58    UpdateHitTestingTree();
     59  }
     60 
     61  enum class PreventDefaultFlag { No, Yes };
     62  std::tuple<APZEventResult, APZHandledResult> TapDispatchToContent(
     63      const ScreenIntPoint& aPoint, PreventDefaultFlag aPreventDefaultFlag) {
     64    APZEventResult result =
     65        Tap(manager, aPoint, TimeDuration::FromMilliseconds(100));
     66 
     67    APZHandledResult delayedAnswer{APZHandledPlace::Invalid, SideBits::eNone,
     68                                   ScrollDirections()};
     69    manager->AddInputBlockCallback(
     70        result.mInputBlockId, [&](uint64_t id, const APZHandledResult& answer) {
     71          EXPECT_EQ(id, result.mInputBlockId);
     72          delayedAnswer = answer;
     73        });
     74    manager->SetAllowedTouchBehavior(result.mInputBlockId,
     75                                     {AllowedTouchBehavior::VERTICAL_PAN});
     76    manager->SetTargetAPZC(result.mInputBlockId, {result.mTargetGuid});
     77    manager->ContentReceivedInputBlock(
     78        result.mInputBlockId, aPreventDefaultFlag == PreventDefaultFlag::Yes);
     79    return {result, delayedAnswer};
     80  }
     81 
     82  void OverscrollDirectionsWithEventHandlerTest(
     83      PreventDefaultFlag aPreventDefaultFlag) {
     84    UpdateHitTestingTree();
     85 
     86    APZHandledPlace expectedPlace =
     87        aPreventDefaultFlag == PreventDefaultFlag::No
     88            ? APZHandledPlace::HandledByRoot
     89            : APZHandledPlace::HandledByContent;
     90    {
     91      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
     92                         {CompositorHitTestFlags::eVisibleToHitTest,
     93                          CompositorHitTestFlags::eIrregularArea});
     94      auto [result, delayedHandledResult] =
     95          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
     96      EXPECT_EQ(result.GetHandledResult(), Nothing());
     97      EXPECT_EQ(
     98          delayedHandledResult,
     99          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
    100                            EitherScrollDirection}));
    101    }
    102 
    103    // overscroll-behavior: contain, contain.
    104    UpdateOverscrollBehavior(OverscrollBehavior::Contain,
    105                             OverscrollBehavior::Contain);
    106    {
    107      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    108                         {CompositorHitTestFlags::eVisibleToHitTest,
    109                          CompositorHitTestFlags::eIrregularArea});
    110      auto [result, delayedHandledResult] =
    111          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
    112      EXPECT_EQ(result.GetHandledResult(), Nothing());
    113      EXPECT_EQ(
    114          delayedHandledResult,
    115          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
    116                            ScrollDirections()}));
    117    }
    118 
    119    // overscroll-behavior: none, none.
    120    UpdateOverscrollBehavior(OverscrollBehavior::None,
    121                             OverscrollBehavior::None);
    122    {
    123      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    124                         {CompositorHitTestFlags::eVisibleToHitTest,
    125                          CompositorHitTestFlags::eIrregularArea});
    126      auto [result, delayedHandledResult] =
    127          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
    128      EXPECT_EQ(result.GetHandledResult(), Nothing());
    129      EXPECT_EQ(
    130          delayedHandledResult,
    131          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
    132                            ScrollDirections()}));
    133    }
    134 
    135    // overscroll-behavior: auto, none.
    136    UpdateOverscrollBehavior(OverscrollBehavior::Auto,
    137                             OverscrollBehavior::None);
    138    {
    139      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    140                         {CompositorHitTestFlags::eVisibleToHitTest,
    141                          CompositorHitTestFlags::eIrregularArea});
    142      auto [result, delayedHandledResult] =
    143          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
    144      EXPECT_EQ(result.GetHandledResult(), Nothing());
    145      EXPECT_EQ(
    146          delayedHandledResult,
    147          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
    148                            HorizontalScrollDirection}));
    149    }
    150 
    151    // overscroll-behavior: none, auto.
    152    UpdateOverscrollBehavior(OverscrollBehavior::None,
    153                             OverscrollBehavior::Auto);
    154    {
    155      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    156                         {CompositorHitTestFlags::eVisibleToHitTest,
    157                          CompositorHitTestFlags::eIrregularArea});
    158      auto [result, delayedHandledResult] =
    159          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
    160      EXPECT_EQ(result.GetHandledResult(), Nothing());
    161      EXPECT_EQ(
    162          delayedHandledResult,
    163          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
    164                            VerticalScrollDirection}));
    165    }
    166  }
    167 
    168  void ScrollableDirectionsWithEventHandlerTest(
    169      PreventDefaultFlag aPreventDefaultFlag) {
    170    UpdateHitTestingTree();
    171 
    172    APZHandledPlace expectedPlace =
    173        aPreventDefaultFlag == PreventDefaultFlag::No
    174            ? APZHandledPlace::HandledByRoot
    175            : APZHandledPlace::HandledByContent;
    176    {
    177      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    178                         {CompositorHitTestFlags::eVisibleToHitTest,
    179                          CompositorHitTestFlags::eIrregularArea});
    180      auto [result, delayedHandledResult] =
    181          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
    182      EXPECT_EQ(result.GetHandledResult(), Nothing());
    183      EXPECT_EQ(
    184          delayedHandledResult,
    185          (APZHandledResult{expectedPlace, SideBits::eBottom | SideBits::eRight,
    186                            EitherScrollDirection}));
    187    }
    188 
    189    // scroll down a bit.
    190    SetScrollOffsetOnMainThread(CSSPoint(0, 10));
    191    {
    192      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    193                         {CompositorHitTestFlags::eVisibleToHitTest,
    194                          CompositorHitTestFlags::eIrregularArea});
    195      auto [result, delayedHandledResult] =
    196          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
    197      EXPECT_EQ(result.GetHandledResult(), Nothing());
    198      EXPECT_EQ(delayedHandledResult,
    199                (APZHandledResult{
    200                    expectedPlace,
    201                    SideBits::eTop | SideBits::eBottom | SideBits::eRight,
    202                    EitherScrollDirection}));
    203    }
    204 
    205    // scroll to the bottom edge
    206    SetScrollOffsetOnMainThread(CSSPoint(0, 100));
    207    {
    208      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    209                         {CompositorHitTestFlags::eVisibleToHitTest,
    210                          CompositorHitTestFlags::eIrregularArea});
    211      auto [result, delayedHandledResult] =
    212          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
    213      EXPECT_EQ(result.GetHandledResult(), Nothing());
    214      EXPECT_EQ(
    215          delayedHandledResult,
    216          (APZHandledResult{expectedPlace, SideBits::eRight | SideBits::eTop,
    217                            EitherScrollDirection}));
    218    }
    219 
    220    // scroll to right a bit.
    221    SetScrollOffsetOnMainThread(CSSPoint(10, 100));
    222    {
    223      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    224                         {CompositorHitTestFlags::eVisibleToHitTest,
    225                          CompositorHitTestFlags::eIrregularArea});
    226      auto [result, delayedHandledResult] =
    227          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
    228      EXPECT_EQ(result.GetHandledResult(), Nothing());
    229      EXPECT_EQ(
    230          delayedHandledResult,
    231          (APZHandledResult{expectedPlace,
    232                            SideBits::eLeft | SideBits::eRight | SideBits::eTop,
    233                            EitherScrollDirection}));
    234    }
    235 
    236    // scroll to the right edge.
    237    SetScrollOffsetOnMainThread(CSSPoint(100, 100));
    238    {
    239      QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    240                         {CompositorHitTestFlags::eVisibleToHitTest,
    241                          CompositorHitTestFlags::eIrregularArea});
    242      auto [result, delayedHandledResult] =
    243          TapDispatchToContent(ScreenIntPoint(50, 50), aPreventDefaultFlag);
    244      EXPECT_EQ(result.GetHandledResult(), Nothing());
    245      EXPECT_EQ(
    246          delayedHandledResult,
    247          (APZHandledResult{expectedPlace, SideBits::eTop | SideBits::eLeft,
    248                            EitherScrollDirection}));
    249    }
    250  }
    251 };
    252 
    253 TEST_F(APZEventResultTester, OverscrollDirections) {
    254  CreateScrollableRootLayer();
    255 
    256  TimeDuration tapDuration = TimeDuration::FromMilliseconds(100);
    257 
    258  // The default value of overscroll-behavior is auto.
    259  APZEventResult result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
    260  EXPECT_EQ(result.GetHandledResult()->mOverscrollDirections,
    261            EitherScrollDirection);
    262 
    263  // overscroll-behavior: contain, contain.
    264  UpdateOverscrollBehavior(OverscrollBehavior::Contain,
    265                           OverscrollBehavior::Contain);
    266  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
    267  EXPECT_EQ(result.GetHandledResult()->mOverscrollDirections,
    268            ScrollDirections());
    269 
    270  // overscroll-behavior: none, none.
    271  UpdateOverscrollBehavior(OverscrollBehavior::None, OverscrollBehavior::None);
    272  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
    273  EXPECT_EQ(result.GetHandledResult()->mOverscrollDirections,
    274            ScrollDirections());
    275 
    276  // overscroll-behavior: auto, none.
    277  UpdateOverscrollBehavior(OverscrollBehavior::Auto, OverscrollBehavior::None);
    278  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
    279  EXPECT_EQ(result.GetHandledResult()->mOverscrollDirections,
    280            HorizontalScrollDirection);
    281 
    282  // overscroll-behavior: none, auto.
    283  UpdateOverscrollBehavior(OverscrollBehavior::None, OverscrollBehavior::Auto);
    284  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
    285  EXPECT_EQ(result.GetHandledResult()->mOverscrollDirections,
    286            VerticalScrollDirection);
    287 }
    288 
    289 TEST_F(APZEventResultTester, ScrollableDirections) {
    290  CreateScrollableRootLayer();
    291 
    292  TimeDuration tapDuration = TimeDuration::FromMilliseconds(100);
    293 
    294  APZEventResult result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
    295  // scrollable to down/right.
    296  EXPECT_EQ(result.GetHandledResult()->mScrollableDirections,
    297            SideBits::eBottom | SideBits::eRight);
    298 
    299  // scroll down a bit.
    300  SetScrollOffsetOnMainThread(CSSPoint(0, 10));
    301  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
    302  // also scrollable toward top.
    303  EXPECT_EQ(result.GetHandledResult()->mScrollableDirections,
    304            SideBits::eTop | SideBits::eBottom | SideBits::eRight);
    305 
    306  // scroll to the bottom edge
    307  SetScrollOffsetOnMainThread(CSSPoint(0, 100));
    308  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
    309  EXPECT_EQ(result.GetHandledResult()->mScrollableDirections,
    310            SideBits::eRight | SideBits::eTop);
    311 
    312  // scroll to right a bit.
    313  SetScrollOffsetOnMainThread(CSSPoint(10, 100));
    314  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
    315  EXPECT_EQ(result.GetHandledResult()->mScrollableDirections,
    316            SideBits::eLeft | SideBits::eRight | SideBits::eTop);
    317 
    318  // scroll to the right edge.
    319  SetScrollOffsetOnMainThread(CSSPoint(100, 100));
    320  result = Tap(manager, ScreenIntPoint(50, 50), tapDuration);
    321  EXPECT_EQ(result.GetHandledResult()->mScrollableDirections,
    322            SideBits::eLeft | SideBits::eTop);
    323 }
    324 
    325 class APZEventResultTesterMock : public APZEventResultTester {
    326 public:
    327  APZEventResultTesterMock() { CreateMockHitTester(); }
    328 };
    329 
    330 TEST_F(APZEventResultTesterMock, OverscrollDirectionsWithEventHandler) {
    331  CreateScrollableRootLayer();
    332 
    333  OverscrollDirectionsWithEventHandlerTest(PreventDefaultFlag::No);
    334 }
    335 
    336 TEST_F(APZEventResultTesterMock,
    337       OverscrollDirectionsWithPreventDefaultEventHandler) {
    338  CreateScrollableRootLayer();
    339 
    340  OverscrollDirectionsWithEventHandlerTest(PreventDefaultFlag::Yes);
    341 }
    342 
    343 TEST_F(APZEventResultTesterMock, ScrollableDirectionsWithEventHandler) {
    344  CreateScrollableRootLayer();
    345 
    346  ScrollableDirectionsWithEventHandlerTest(PreventDefaultFlag::No);
    347 }
    348 
    349 TEST_F(APZEventResultTesterMock,
    350       ScrollableDirectionsWithPreventDefaultEventHandler) {
    351  CreateScrollableRootLayer();
    352 
    353  ScrollableDirectionsWithEventHandlerTest(PreventDefaultFlag::Yes);
    354 }
    355 
    356 // Test that APZEventResult::GetHandledResult() is correctly
    357 // populated.
    358 TEST_F(APZEventResultTesterMock, HandledByRootApzcFlag) {
    359  // Create simple layer tree containing a dispatch-to-content region
    360  // that covers part but not all of its area.
    361  const char* treeShape = "x";
    362  LayerIntRect layerVisibleRects[] = {
    363      LayerIntRect(0, 0, 100, 100),
    364  };
    365  CreateScrollData(treeShape, layerVisibleRects);
    366  SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID,
    367                            CSSRect(0, 0, 100, 200));
    368  ModifyFrameMetrics(root, [](ScrollMetadata& sm, FrameMetrics& metrics) {
    369    metrics.SetIsRootContent(true);
    370  });
    371  // away from the scrolling container layer.
    372  registration = MakeUnique<ScopedLayerTreeRegistration>(LayersId{0}, mcc);
    373  UpdateHitTestingTree();
    374 
    375  // Tap the top half and check that we report that the event was
    376  // handled by the root APZC.
    377  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
    378  APZEventResult result =
    379      TouchDown(manager, ScreenIntPoint(50, 25), mcc->Time());
    380  TouchUp(manager, ScreenIntPoint(50, 25), mcc->Time());
    381  EXPECT_EQ(result.GetHandledResult(),
    382            Some(APZHandledResult{APZHandledPlace::HandledByRoot,
    383                                  SideBits::eBottom, EitherScrollDirection}));
    384 
    385  // Tap the bottom half and check that we report that we're not
    386  // sure whether the event was handled by the root APZC.
    387  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    388                     {CompositorHitTestFlags::eVisibleToHitTest,
    389                      CompositorHitTestFlags::eIrregularArea});
    390  result = TouchDown(manager, ScreenIntPoint(50, 75), mcc->Time());
    391  TouchUp(manager, ScreenIntPoint(50, 75), mcc->Time());
    392  EXPECT_EQ(result.GetHandledResult(), Nothing());
    393 
    394  // Register an input block callback that will tell us the
    395  // delayed answer.
    396  APZHandledResult delayedAnswer{APZHandledPlace::Invalid, SideBits::eNone,
    397                                 ScrollDirections()};
    398  manager->AddInputBlockCallback(
    399      result.mInputBlockId, [&](uint64_t id, const APZHandledResult& answer) {
    400        EXPECT_EQ(id, result.mInputBlockId);
    401        delayedAnswer = answer;
    402      });
    403 
    404  // Send APZ the relevant notifications to allow it to process the
    405  // input block.
    406  manager->SetAllowedTouchBehavior(result.mInputBlockId,
    407                                   {AllowedTouchBehavior::VERTICAL_PAN});
    408  manager->SetTargetAPZC(result.mInputBlockId, {result.mTargetGuid});
    409  manager->ContentReceivedInputBlock(result.mInputBlockId,
    410                                     /*aPreventDefault=*/false);
    411 
    412  // Check that we received the delayed answer and it is what we expect.
    413  EXPECT_EQ(delayedAnswer,
    414            (APZHandledResult{APZHandledPlace::HandledByRoot, SideBits::eBottom,
    415                              EitherScrollDirection}));
    416 
    417  // Now repeat the tap on the bottom half, but simulate a prevent-default.
    418  // This time, we expect a delayed answer of `HandledByContent`.
    419  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    420                     {CompositorHitTestFlags::eVisibleToHitTest,
    421                      CompositorHitTestFlags::eIrregularArea});
    422  result = TouchDown(manager, ScreenIntPoint(50, 75), mcc->Time());
    423  TouchUp(manager, ScreenIntPoint(50, 75), mcc->Time());
    424  EXPECT_EQ(result.GetHandledResult(), Nothing());
    425  manager->AddInputBlockCallback(
    426      result.mInputBlockId, [&](uint64_t id, const APZHandledResult& answer) {
    427        EXPECT_EQ(id, result.mInputBlockId);
    428        delayedAnswer = answer;
    429      });
    430  manager->SetAllowedTouchBehavior(result.mInputBlockId,
    431                                   {AllowedTouchBehavior::VERTICAL_PAN});
    432  manager->SetTargetAPZC(result.mInputBlockId, {result.mTargetGuid});
    433  manager->ContentReceivedInputBlock(result.mInputBlockId,
    434                                     /*aPreventDefault=*/true);
    435  EXPECT_EQ(delayedAnswer,
    436            (APZHandledResult{APZHandledPlace::HandledByContent,
    437                              SideBits::eBottom, EitherScrollDirection}));
    438 
    439  // Shrink the scrollable area, now it's no longer scrollable.
    440  ModifyFrameMetrics(root, [](ScrollMetadata& sm, FrameMetrics& metrics) {
    441    metrics.SetScrollableRect(CSSRect(0, 0, 100, 100));
    442  });
    443  UpdateHitTestingTree();
    444  // Now repeat the tap on the bottom half with an event handler.
    445  // This time, we expect a delayed answer of `Unhandled`.
    446  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID,
    447                     {CompositorHitTestFlags::eVisibleToHitTest,
    448                      CompositorHitTestFlags::eIrregularArea});
    449  result = TouchDown(manager, ScreenIntPoint(50, 75), mcc->Time());
    450  TouchUp(manager, ScreenIntPoint(50, 75), mcc->Time());
    451  EXPECT_EQ(result.GetHandledResult(), Nothing());
    452  manager->AddInputBlockCallback(
    453      result.mInputBlockId, [&](uint64_t id, const APZHandledResult& answer) {
    454        EXPECT_EQ(id, result.mInputBlockId);
    455        delayedAnswer = answer;
    456      });
    457  manager->SetAllowedTouchBehavior(result.mInputBlockId,
    458                                   {AllowedTouchBehavior::VERTICAL_PAN});
    459  manager->SetTargetAPZC(result.mInputBlockId, {result.mTargetGuid});
    460  manager->ContentReceivedInputBlock(result.mInputBlockId,
    461                                     /*aPreventDefault=*/false);
    462  EXPECT_EQ(delayedAnswer,
    463            (APZHandledResult{APZHandledPlace::Unhandled, SideBits::eNone,
    464                              EitherScrollDirection}));
    465 
    466  // Repeat the tap on the bottom half, with no event handler.
    467  // Make sure we get an eager answer of `Unhandled`.
    468  QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID);
    469  result = TouchDown(manager, ScreenIntPoint(50, 75), mcc->Time());
    470  TouchUp(manager, ScreenIntPoint(50, 75), mcc->Time());
    471  EXPECT_EQ(result.GetStatus(), nsEventStatus_eIgnore);
    472  EXPECT_EQ(result.GetHandledResult(),
    473            Some(APZHandledResult{APZHandledPlace::Unhandled, SideBits::eNone,
    474                                  EitherScrollDirection}));
    475 }