TEST_F(APZHitTestingTester, Bug1148350) { CreateBug1148350LayerTree(); ScopedLayerTreeRegistration registration(manager, 0, root, mcc); manager->UpdateHitTestingTree(nullptr, root, false, 0, 0); MockFunction<void(std::string checkPointName)> check; { InSequence s; EXPECT_CALL(*mcc, HandleTap(TapType::eSingleTap, LayoutDevicePoint(100, 100), 0, ApzcOf(layers[1])->GetGuid(), _)).Times(1); EXPECT_CALL(check, Call("Tapped without transform")); EXPECT_CALL(*mcc, HandleTap(TapType::eSingleTap, LayoutDevicePoint(100, 100), 0, ApzcOf(layers[1])->GetGuid(), _)).Times(1); EXPECT_CALL(check, Call("Tapped with interleaved transform")); } Tap(manager, ScreenIntPoint(100, 100), TimeDuration::FromMilliseconds(100)); mcc->RunThroughDelayedTasks(); check.Call("Tapped without transform"); uint64_t blockId; TouchDown(manager, ScreenIntPoint(100, 100), mcc->Time(), &blockId); if (gfxPrefs::TouchActionEnabled()) { SetDefaultAllowedTouchBehavior(manager, blockId); } mcc->AdvanceByMillis(100); layers[0]->SetVisibleRegion(LayerIntRegion(LayerIntRect(0,50,200,150))); layers[0]->SetBaseTransform(Matrix4x4::Translation(0, 50, 0)); manager->UpdateHitTestingTree(nullptr, root, false, 0, 0); TouchUp(manager, ScreenIntPoint(100, 100), mcc->Time()); mcc->RunThroughDelayedTasks(); check.Call("Tapped with interleaved transform"); }
void DoLongPressTest(uint32_t aBehavior) { MakeApzcUnzoomable(); uint64_t blockId = 0; nsEventStatus status = TouchDown(apzc, ScreenIntPoint(10, 10), mcc->Time(), &blockId); EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status); if (gfxPrefs::TouchActionEnabled() && status != nsEventStatus_eConsumeNoDefault) { // SetAllowedTouchBehavior() must be called after sending touch-start. nsTArray<uint32_t> allowedTouchBehaviors; allowedTouchBehaviors.AppendElement(aBehavior); apzc->SetAllowedTouchBehavior(blockId, allowedTouchBehaviors); } // Have content "respond" to the touchstart apzc->ContentReceivedInputBlock(blockId, false); MockFunction<void(std::string checkPointName)> check; { InSequence s; EXPECT_CALL(check, Call("preHandleLongTap")); blockId++; EXPECT_CALL(*mcc, HandleTap(TapType::eLongTap, LayoutDevicePoint(10, 10), 0, apzc->GetGuid(), blockId)).Times(1); EXPECT_CALL(check, Call("postHandleLongTap")); EXPECT_CALL(check, Call("preHandleLongTapUp")); EXPECT_CALL(*mcc, HandleTap(TapType::eLongTapUp, LayoutDevicePoint(10, 10), 0, apzc->GetGuid(), _)).Times(1); EXPECT_CALL(check, Call("postHandleLongTapUp")); } // Manually invoke the longpress while the touch is currently down. check.Call("preHandleLongTap"); mcc->RunThroughDelayedTasks(); check.Call("postHandleLongTap"); // Dispatching the longpress event starts a new touch block, which // needs a new content response and also has a pending timeout task // in the queue. Deal with those here. We do the content response first // with preventDefault=false, and then we run the timeout task which // "loses the race" and does nothing. apzc->ContentReceivedInputBlock(blockId, false); mcc->AdvanceByMillis(1000); // Finally, simulate lifting the finger. Since the long-press wasn't // prevent-defaulted, we should get a long-tap-up event. check.Call("preHandleLongTapUp"); status = TouchUp(apzc, ScreenIntPoint(10, 10), mcc->Time()); mcc->RunThroughDelayedTasks(); EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status); check.Call("postHandleLongTapUp"); apzc->AssertStateIsReset(); }
TEST_F(APZCGestureDetectorTester, TapFollowedByMultipleTouches) { MakeApzcZoomable(); EXPECT_CALL(*mcc, HandleTap(TapType::eSingleTap, LayoutDevicePoint(10, 10), 0, apzc->GetGuid(), _)).Times(1); Tap(apzc, ScreenIntPoint(10, 10), TimeDuration::FromMilliseconds(100)); int inputId = 0; MultiTouchInput mti; mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_START, mcc->Time()); mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0)); apzc->ReceiveInputEvent(mti, nullptr); mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_START, mcc->Time()); mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0)); mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ParentLayerPoint(10, 10), ScreenSize(0, 0), 0, 0)); apzc->ReceiveInputEvent(mti, nullptr); mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_END, mcc->Time()); mti.mTouches.AppendElement(SingleTouchData(inputId, ParentLayerPoint(20, 20), ScreenSize(0, 0), 0, 0)); mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ParentLayerPoint(10, 10), ScreenSize(0, 0), 0, 0)); apzc->ReceiveInputEvent(mti, nullptr); apzc->AssertStateIsReset(); }
TEST_F(APZCGestureDetectorTester, DoubleTapPreventDefaultBoth) { MakeApzcWaitForMainThread(); MakeApzcZoomable(); EXPECT_CALL(*mcc, HandleTap(TapType::eSingleTap, LayoutDevicePoint(10, 10), 0, apzc->GetGuid(), _)).Times(0); EXPECT_CALL(*mcc, HandleTap(TapType::eDoubleTap, LayoutDevicePoint(10, 10), 0, apzc->GetGuid(), _)).Times(0); uint64_t blockIds[2]; DoubleTapAndCheckStatus(apzc, ScreenIntPoint(10, 10), &blockIds); // responses to the two touchstarts apzc->ContentReceivedInputBlock(blockIds[0], true); apzc->ContentReceivedInputBlock(blockIds[1], true); apzc->AssertStateIsReset(); }
nsIntPoint APZCCallbackHelper::ApplyCallbackTransform(const nsIntPoint& aPoint, const ScrollableLayerGuid& aGuid, const CSSToLayoutDeviceScale& aScale) { LayoutDevicePoint point = LayoutDevicePoint(aPoint.x, aPoint.y); point = ApplyCallbackTransform(point / aScale, aGuid) * aScale; LayoutDeviceIntPoint ret = gfx::RoundedToInt(point); return nsIntPoint(ret.x, ret.y); }
LayoutDeviceIntPoint APZCCallbackHelper::ApplyCallbackTransform(const LayoutDeviceIntPoint& aPoint, const ScrollableLayerGuid& aGuid, const CSSToLayoutDeviceScale& aScale, float aPresShellResolution) { LayoutDevicePoint point = LayoutDevicePoint(aPoint.x, aPoint.y); point = ApplyCallbackTransform(point / aScale, aGuid, aPresShellResolution) * aScale; return gfx::RoundedToInt(point); }
TEST_F(APZCGestureDetectorTester, MediumPress) { MakeApzcUnzoomable(); MockFunction<void(std::string checkPointName)> check; { InSequence s; // This verifies that the single tap notification is sent after the // touchup is fully processed. The ordering here is important. EXPECT_CALL(check, Call("pre-tap")); EXPECT_CALL(check, Call("post-tap")); EXPECT_CALL(*mcc, HandleTap(TapType::eSingleTap, LayoutDevicePoint(10, 10), 0, apzc->GetGuid(), _)).Times(1); } check.Call("pre-tap"); TapAndCheckStatus(apzc, ScreenIntPoint(10, 10), TimeDuration::FromMilliseconds(400)); check.Call("post-tap"); apzc->AssertStateIsReset(); }
TEST_F(APZEventRegionsTester, Bug1117712) { CreateBug1117712LayerTree(); TestAsyncPanZoomController* apzc2 = ApzcOf(layers[2]); // These touch events should hit the dispatch-to-content region of layers[3] // and so get queued with that APZC as the tentative target. uint64_t inputBlockId = 0; Tap(manager, ScreenIntPoint(55, 5), TimeDuration::FromMilliseconds(100), nullptr, &inputBlockId); // But now we tell the APZ that really it hit layers[2], and expect the tap // to be delivered at the correct coordinates. EXPECT_CALL(*mcc, HandleTap(TapType::eSingleTap, LayoutDevicePoint(55, 5), 0, apzc2->GetGuid(), _)) .Times(1); nsTArray<ScrollableLayerGuid> targets; targets.AppendElement(apzc2->GetGuid()); manager->SetTargetAPZC(inputBlockId, targets); }
TEST_F(APZCGestureDetectorTester, TapTimeoutInterruptedByWheel) { // In this test, even though the wheel block comes right after the tap, the // tap should still be dispatched because it completes fully before the wheel // block arrived. EXPECT_CALL(*mcc, HandleTap(TapType::eSingleTap, LayoutDevicePoint(10, 10), 0, apzc->GetGuid(), _)).Times(1); // We make the APZC zoomable so the gesture detector needs to wait to // distinguish between tap and double-tap. During that timeout is when we // insert the wheel event. MakeApzcZoomable(); uint64_t touchBlockId = 0; uint64_t wheelBlockId = 0; Tap(apzc, ScreenIntPoint(10, 10), TimeDuration::FromMilliseconds(100), nullptr, &touchBlockId); mcc->AdvanceByMillis(10); Wheel(apzc, ScreenIntPoint(10, 10), ScreenPoint(0, -10), mcc->Time(), &wheelBlockId); EXPECT_NE(touchBlockId, wheelBlockId); while (mcc->RunThroughDelayedTasks()); }
void DoLongPressPreventDefaultTest(uint32_t aBehavior) { MakeApzcUnzoomable(); EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(0); int touchX = 10, touchStartY = 10, touchEndY = 50; uint64_t blockId = 0; nsEventStatus status = TouchDown(apzc, ScreenIntPoint(touchX, touchStartY), mcc->Time(), &blockId); EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status); if (gfxPrefs::TouchActionEnabled() && status != nsEventStatus_eConsumeNoDefault) { // SetAllowedTouchBehavior() must be called after sending touch-start. nsTArray<uint32_t> allowedTouchBehaviors; allowedTouchBehaviors.AppendElement(aBehavior); apzc->SetAllowedTouchBehavior(blockId, allowedTouchBehaviors); } // Have content "respond" to the touchstart apzc->ContentReceivedInputBlock(blockId, false); MockFunction<void(std::string checkPointName)> check; { InSequence s; EXPECT_CALL(check, Call("preHandleLongTap")); blockId++; EXPECT_CALL(*mcc, HandleTap(TapType::eLongTap, LayoutDevicePoint(touchX, touchStartY), 0, apzc->GetGuid(), blockId)).Times(1); EXPECT_CALL(check, Call("postHandleLongTap")); } // Manually invoke the longpress while the touch is currently down. check.Call("preHandleLongTap"); mcc->RunThroughDelayedTasks(); check.Call("postHandleLongTap"); // There should be a TimeoutContentResponse task in the queue still, // waiting for the response from the longtap event dispatched above. // Send the signal that content has handled the long-tap, and then run // the timeout task (it will be a no-op because the content "wins" the // race. This takes the place of the "contextmenu" event. apzc->ContentReceivedInputBlock(blockId, true); mcc->AdvanceByMillis(1000); MultiTouchInput mti = CreateMultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, mcc->Time()); mti.mTouches.AppendElement(SingleTouchData(0, ParentLayerPoint(touchX, touchEndY), ScreenSize(0, 0), 0, 0)); status = apzc->ReceiveInputEvent(mti, nullptr); EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status); EXPECT_CALL(*mcc, HandleTap(TapType::eSingleTap, LayoutDevicePoint(touchX, touchEndY), 0, apzc->GetGuid(), _)).Times(0); status = TouchUp(apzc, ScreenIntPoint(touchX, touchEndY), mcc->Time()); EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status); ParentLayerPoint pointOut; AsyncTransform viewTransformOut; apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut); EXPECT_EQ(ParentLayerPoint(), pointOut); EXPECT_EQ(AsyncTransform(), viewTransformOut); apzc->AssertStateIsReset(); }