diff options
Diffstat (limited to 'gfx/layers/apz/test/gtest/TestTransformNotifications.cpp')
-rw-r--r-- | gfx/layers/apz/test/gtest/TestTransformNotifications.cpp | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/gfx/layers/apz/test/gtest/TestTransformNotifications.cpp b/gfx/layers/apz/test/gtest/TestTransformNotifications.cpp new file mode 100644 index 0000000000..c3f53105fa --- /dev/null +++ b/gfx/layers/apz/test/gtest/TestTransformNotifications.cpp @@ -0,0 +1,461 @@ +/* -*- 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 "APZCBasicTester.h" +#include "APZCTreeManagerTester.h" +#include "APZTestCommon.h" +#include "mozilla/layers/WebRenderScrollDataWrapper.h" + +#include "InputUtils.h" + +class APZCTransformNotificationTester : public APZCTreeManagerTester { + public: + explicit APZCTransformNotificationTester() { CreateMockHitTester(); } + + UniquePtr<ScopedLayerTreeRegistration> mRegistration; + + RefPtr<TestAsyncPanZoomController> mRootApzc; + + void SetupBasicTest() { + const char* treeShape = "x"; + LayerIntRegion layerVisibleRegion[] = { + LayerIntRect(0, 0, 100, 100), + }; + CreateScrollData(treeShape, layerVisibleRegion); + SetScrollableFrameMetrics(root, ScrollableLayerGuid::START_SCROLL_ID, + CSSRect(0, 0, 500, 500)); + + mRegistration = MakeUnique<ScopedLayerTreeRegistration>(LayersId{0}, mcc); + + UpdateHitTestingTree(); + + mRootApzc = ApzcOf(root); + } +}; + +TEST_F(APZCTransformNotificationTester, PanningTransformNotifications) { + SCOPED_GFX_PREF_BOOL("apz.overscroll.enabled", true); + + SetupBasicTest(); + + // Scroll down by 25 px. Ensure we only get one set of + // state change notifications. + // + // Then, scroll back up by 20px, this time flinging after. + // The fling should cover the remaining 5 px of room to scroll, then + // go into overscroll, and finally snap-back to recover from overscroll. + // Again, ensure we only get one set of state change notifications for + // this entire procedure. + + MockFunction<void(std::string checkPointName)> check; + { + InSequence s; + EXPECT_CALL(check, Call("Simple pan")); + EXPECT_CALL(*mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eStartTouch, _)) + .Times(1); + EXPECT_CALL( + *mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformBegin, _)) + .Times(1); + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eStartPanning, _)) + .Times(1); + EXPECT_CALL(*mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eEndTouch, _)) + .Times(1); + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformEnd, _)) + .Times(1); + EXPECT_CALL(check, Call("Complex pan")); + EXPECT_CALL(*mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eStartTouch, _)) + .Times(1); + EXPECT_CALL( + *mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformBegin, _)) + .Times(1); + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eStartPanning, _)) + .Times(1); + EXPECT_CALL(*mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eEndTouch, _)) + .Times(1); + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformEnd, _)) + .Times(1); + EXPECT_CALL(check, Call("Done")); + } + + check.Call("Simple pan"); + Pan(mRootApzc, 50, 25, PanOptions::NoFling); + check.Call("Complex pan"); + Pan(mRootApzc, 25, 45); + mRootApzc->AdvanceAnimationsUntilEnd(); + check.Call("Done"); +} + +TEST_F(APZCTransformNotificationTester, PanWithMomentumTransformNotifications) { + SetupBasicTest(); + + MockFunction<void(std::string checkPointName)> check; + { + InSequence s; + EXPECT_CALL(check, Call("Pan Start")); + EXPECT_CALL( + *mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformBegin, _)) + .Times(1); + + EXPECT_CALL(check, Call("Panning")); + EXPECT_CALL(check, Call("Pan End")); + EXPECT_CALL(check, Call("Momentum Start")); + + EXPECT_CALL(check, Call("Momentum Pan")); + EXPECT_CALL(check, Call("Momentum End")); + // The TransformEnd should only be sent after the momentum pan. + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformEnd, _)) + .Times(1); + + EXPECT_CALL(check, Call("Done")); + } + + check.Call("Pan Start"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50), + ScreenIntPoint(1, 2), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Panning"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_PAN, mRootApzc, ScreenIntPoint(50, 50), + ScreenPoint(15, 30), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Pan End"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50), + ScreenPoint(0, 0), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Momentum Start"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_MOMENTUMSTART, manager, + ScreenIntPoint(50, 50), ScreenPoint(30, 90), mcc->Time()); + mcc->AdvanceByMillis(10); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Momentum Pan"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_MOMENTUMPAN, manager, + ScreenIntPoint(50, 50), ScreenPoint(10, 30), mcc->Time()); + mcc->AdvanceByMillis(10); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Momentum End"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_MOMENTUMEND, manager, + ScreenIntPoint(50, 50), ScreenPoint(0, 0), mcc->Time()); + mcc->AdvanceByMillis(10); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Done"); +} + +TEST_F(APZCTransformNotificationTester, + PanWithoutMomentumTransformNotifications) { + // Ensure that the TransformEnd delay is 100ms. + SCOPED_GFX_PREF_INT("apz.scrollend-event.content.delay_ms", 100); + + SetupBasicTest(); + + MockFunction<void(std::string checkPointName)> check; + { + InSequence s; + EXPECT_CALL(check, Call("Pan Start")); + EXPECT_CALL( + *mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformBegin, _)) + .Times(1); + + EXPECT_CALL(check, Call("Panning")); + EXPECT_CALL(check, Call("Pan End")); + EXPECT_CALL(check, Call("TransformEnd delay")); + // The TransformEnd should only be sent after the pan gesture and 100ms + // timer fire. + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformEnd, _)) + .Times(1); + + EXPECT_CALL(check, Call("Done")); + } + + check.Call("Pan Start"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50), + ScreenIntPoint(1, 2), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Panning"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_PAN, mRootApzc, ScreenIntPoint(50, 50), + ScreenPoint(15, 30), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Pan End"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50), + ScreenPoint(0, 0), mcc->Time()); + mcc->AdvanceByMillis(55); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("TransformEnd delay"); + mcc->AdvanceByMillis(55); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Done"); +} + +TEST_F(APZCTransformNotificationTester, + PanFollowedByNewPanTransformNotifications) { + // Ensure that the TransformEnd delay is 100ms. + SCOPED_GFX_PREF_INT("apz.scrollend-event.content.delay_ms", 100); + + SetupBasicTest(); + + MockFunction<void(std::string checkPointName)> check; + { + InSequence s; + EXPECT_CALL(check, Call("Pan Start")); + EXPECT_CALL( + *mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformBegin, _)) + .Times(1); + + EXPECT_CALL(check, Call("Panning")); + EXPECT_CALL(check, Call("Pan End")); + // The TransformEnd delay should be cut short and delivered before the + // new pan gesture begins. + EXPECT_CALL(check, Call("New Pan Start")); + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformEnd, _)) + .Times(1); + EXPECT_CALL( + *mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformBegin, _)) + .Times(1); + EXPECT_CALL(check, Call("New Pan End")); + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformEnd, _)) + .Times(1); + + EXPECT_CALL(check, Call("Done")); + } + + check.Call("Pan Start"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50), + ScreenIntPoint(1, 2), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Panning"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_PAN, mRootApzc, ScreenIntPoint(50, 50), + ScreenPoint(15, 30), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Pan End"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50), + ScreenPoint(0, 0), mcc->Time()); + mcc->AdvanceByMillis(55); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("New Pan Start"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50), + ScreenIntPoint(1, 2), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_PAN, mRootApzc, ScreenIntPoint(50, 50), + ScreenPoint(15, 30), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("New Pan End"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50), + ScreenPoint(0, 0), mcc->Time()); + mcc->AdvanceByMillis(105); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Done"); +} + +TEST_F(APZCTransformNotificationTester, + PanFollowedByWheelTransformNotifications) { + // Ensure that the TransformEnd delay is 100ms. + SCOPED_GFX_PREF_INT("apz.scrollend-event.content.delay_ms", 100); + + SetupBasicTest(); + + MockFunction<void(std::string checkPointName)> check; + { + InSequence s; + EXPECT_CALL(check, Call("Pan Start")); + EXPECT_CALL( + *mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformBegin, _)) + .Times(1); + + EXPECT_CALL(check, Call("Panning")); + EXPECT_CALL(check, Call("Pan End")); + // The TransformEnd delay should be cut short and delivered before the + // new wheel event begins. + EXPECT_CALL(check, Call("Wheel Start")); + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformEnd, _)) + .Times(1); + EXPECT_CALL( + *mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformBegin, _)) + .Times(1); + EXPECT_CALL(check, Call("Wheel End")); + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformEnd, _)) + .Times(1); + EXPECT_CALL(check, Call("Done")); + } + + check.Call("Pan Start"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50), + ScreenIntPoint(1, 2), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Panning"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_PAN, mRootApzc, ScreenIntPoint(50, 50), + ScreenPoint(15, 30), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Pan End"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50), + ScreenPoint(0, 0), mcc->Time()); + mcc->AdvanceByMillis(55); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Wheel Start"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + SmoothWheel(manager, ScreenIntPoint(50, 50), ScreenPoint(10, 10), + mcc->Time()); + mcc->AdvanceByMillis(10); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Wheel End"); + + mRootApzc->AdvanceAnimationsUntilEnd(); + + check.Call("Done"); +} + +#ifndef MOZ_WIDGET_ANDROID // Currently fails on Android +TEST_F(APZCTransformNotificationTester, PanOverscrollTransformNotifications) { + SCOPED_GFX_PREF_BOOL("apz.overscroll.enabled", true); + + SetupBasicTest(); + + MockFunction<void(std::string checkPointName)> check; + { + InSequence s; + EXPECT_CALL(check, Call("Pan Start")); + EXPECT_CALL( + *mcc, + NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformBegin, _)) + .Times(1); + + EXPECT_CALL(check, Call("Panning Into Overscroll")); + EXPECT_CALL(check, Call("Pan End")); + EXPECT_CALL(check, Call("Overscroll Animation End")); + // The TransformEnd should only be sent after the overscroll animation + // completes. + EXPECT_CALL( + *mcc, NotifyAPZStateChange( + _, GeckoContentController::APZStateChange::eTransformEnd, _)) + .Times(1); + EXPECT_CALL(check, Call("Done")); + } + + check.Call("Pan Start"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_START, manager, ScreenIntPoint(50, 50), + ScreenIntPoint(1, 2), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + check.Call("Panning Into Overscroll"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_PAN, mRootApzc, ScreenIntPoint(50, 50), + ScreenPoint(15, -30), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + // Ensure that we have overscrolled. + EXPECT_TRUE(mRootApzc->IsOverscrolled()); + + check.Call("Pan End"); + QueueMockHitResult(ScrollableLayerGuid::START_SCROLL_ID); + PanGesture(PanGestureInput::PANGESTURE_END, manager, ScreenIntPoint(50, 50), + ScreenPoint(0, 0), mcc->Time()); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimations(mcc->GetSampleTime()); + + // Wait for the overscroll animation to complete and the TransformEnd + // notification to be sent. + check.Call("Overscroll Animation End"); + mcc->AdvanceByMillis(5); + mRootApzc->AdvanceAnimationsUntilEnd(); + EXPECT_FALSE(mRootApzc->IsOverscrolled()); + + check.Call("Done"); +} +#endif |