Chromium Code Reviews| Index: third_party/WebKit/Source/core/input/EventHandlerTest.cpp |
| diff --git a/third_party/WebKit/Source/core/input/EventHandlerTest.cpp b/third_party/WebKit/Source/core/input/EventHandlerTest.cpp |
| index d71e2f1f94d0deec3185ed2c1d920ee3b7623f4e..df007785dbd6b7b87f12e451de634f3c09014482 100644 |
| --- a/third_party/WebKit/Source/core/input/EventHandlerTest.cpp |
| +++ b/third_party/WebKit/Source/core/input/EventHandlerTest.cpp |
| @@ -5,6 +5,7 @@ |
| #include "core/input/EventHandler.h" |
| #include <memory> |
| +#include "core/dom/ClientRect.h" |
| #include "core/dom/Document.h" |
| #include "core/dom/Range.h" |
| #include "core/editing/Editor.h" |
| @@ -12,12 +13,34 @@ |
| #include "core/frame/FrameView.h" |
| #include "core/frame/LocalFrame.h" |
| #include "core/frame/Settings.h" |
| +#include "core/layout/LayoutBox.h" |
| #include "core/loader/EmptyClients.h" |
| #include "core/page/AutoscrollController.h" |
| #include "core/page/Page.h" |
| +#include "core/paint/PaintLayerScrollableArea.h" |
| #include "core/testing/DummyPageHolder.h" |
| +#include "platform/scroll/MainThreadScrollingReason.h" |
| +#include "platform/testing/HistogramTester.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| +#define EXPECT_WHEEL_BUCKET(reason, count) \ |
| + histogram_tester.ExpectBucketCount( \ |
| + "Renderer4.MainThreadWheelScrollReason", \ |
| + GetBucketIndex(MainThreadScrollingReason::reason), count); |
| + |
| +#define EXPECT_TOUCH_BUCKET(reason, count) \ |
| + histogram_tester.ExpectBucketCount( \ |
| + "Renderer4.MainThreadGestureScrollReason", \ |
| + GetBucketIndex(MainThreadScrollingReason::reason), count); |
| + |
| +#define EXPECT_WHEEL_TOTAL(count) \ |
| + histogram_tester.ExpectTotalCount("Renderer4.MainThreadWheelScrollReason", \ |
| + count); |
| + |
| +#define EXPECT_TOUCH_TOTAL(count) \ |
| + histogram_tester.ExpectTotalCount("Renderer4.MainThreadGestureScrollReason", \ |
| + count); |
|
tdresser
2017/04/11 18:50:47
I'm not sure it's worth factoring these out.
Could
bokan
2017/04/11 19:23:26
I asked for this so I'll explain my reasoning. I l
tdresser
2017/04/11 20:33:27
In general, use of macros like this is discouraged
yigu
2017/04/11 21:28:10
Macros help to locate the exact line that causes c
bokan
2017/04/11 22:27:16
Yes, histogram_tester is unfortunate in this way.
|
| + |
| namespace blink { |
| class EventHandlerTest : public ::testing::Test { |
| @@ -36,6 +59,48 @@ class EventHandlerTest : public ::testing::Test { |
| std::unique_ptr<DummyPageHolder> dummy_page_holder_; |
| }; |
| +class NonCompositedMainThreadScrollingReasonRecordTest |
| + : public EventHandlerTest { |
| + protected: |
| + class ScrollBeginEventBuilder : public WebGestureEvent { |
| + public: |
| + ScrollBeginEventBuilder(IntPoint position, |
| + FloatPoint delta, |
| + WebGestureDevice device) |
| + : WebGestureEvent() { |
| + type_ = WebInputEvent::kGestureScrollBegin; |
| + x = global_x = position.X(); |
| + y = global_y = position.Y(); |
| + data.scroll_begin.delta_y_hint = delta.Y(); |
| + source_device = device; |
| + frame_scale_ = 1; |
| + } |
| + }; |
| + |
| + class ScrollUpdateEventBuilder : public WebGestureEvent { |
| + public: |
| + ScrollUpdateEventBuilder() : WebGestureEvent() { |
| + type_ = WebInputEvent::kGestureScrollUpdate; |
| + data.scroll_update.delta_x = 0.0f; |
| + data.scroll_update.delta_y = 1.0f; |
| + data.scroll_update.velocity_x = 0; |
| + data.scroll_update.velocity_y = 1; |
| + frame_scale_ = 1; |
| + } |
| + }; |
| + |
| + class ScrollEndEventBuilder : public WebGestureEvent { |
| + public: |
| + ScrollEndEventBuilder() : WebGestureEvent() { |
| + type_ = WebInputEvent::kGestureScrollEnd; |
| + frame_scale_ = 1; |
| + } |
| + }; |
| + |
| + int GetBucketIndex(uint32_t reason); |
| + void Scroll(Element*, const WebGestureDevice); |
| +}; |
| + |
| class TapEventBuilder : public WebGestureEvent { |
| public: |
| TapEventBuilder(IntPoint position, int tap_count) |
| @@ -90,6 +155,34 @@ void EventHandlerTest::SetHtmlInnerHTML(const char* html_content) { |
| GetDocument().View()->UpdateAllLifecyclePhases(); |
| } |
| +int NonCompositedMainThreadScrollingReasonRecordTest::GetBucketIndex( |
| + uint32_t reason) { |
| + int index = 1; |
| + while (!(reason & 1)) { |
| + reason >>= 1; |
| + ++index; |
| + } |
| + DCHECK_EQ(reason, 1u); |
| + return index; |
| +} |
| + |
| +void NonCompositedMainThreadScrollingReasonRecordTest::Scroll( |
| + Element* element, |
| + const WebGestureDevice device) { |
| + DCHECK(element); |
| + DCHECK(element->getBoundingClientRect()); |
| + ClientRect* rect = element->getBoundingClientRect(); |
| + ScrollBeginEventBuilder scroll_begin( |
| + IntPoint(rect->left() + rect->width() / 2, |
| + rect->top() + rect->height() / 2), |
| + FloatPoint(0.f, 1.f), device); |
| + ScrollUpdateEventBuilder scroll_update; |
| + ScrollEndEventBuilder scroll_end; |
| + GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_begin); |
| + GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_update); |
| + GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_end); |
| +} |
| + |
| TEST_F(EventHandlerTest, dragSelectionAfterScroll) { |
| SetHtmlInnerHTML( |
| "<style> body { margin: 0px; } .upper { width: 300px; height: 400px; }" |
| @@ -548,4 +641,144 @@ TEST_F(EventHandlerTooltipTest, mouseLeaveClearsTooltip) { |
| EXPECT_EQ(WTF::String(), LastToolTip()); |
| } |
| +TEST_F(NonCompositedMainThreadScrollingReasonRecordTest, |
| + TouchAndWheelGeneralTest) { |
| + SetHtmlInnerHTML( |
| + "<style>" |
| + " .box { overflow:scroll; width: 100px; height: 100px; }" |
| + " .translucent { opacity: 0.5; }" |
| + " .spacer { height: 1000px; }" |
| + "</style>" |
| + "<div id='box' class='translucent box'>" |
| + " <div class='spacer'></div>" |
| + "</div>"); |
| + |
| + GetDocument().View()->UpdateAllLifecyclePhases(); |
| + |
| + Element* box = GetDocument().getElementById("box"); |
| + HistogramTester histogram_tester; |
| + |
| + // Test touch scroll. |
| + Scroll(box, kWebGestureDeviceTouchscreen); |
| + EXPECT_TOUCH_BUCKET(kHasOpacityAndLCDText, 1); |
| + EXPECT_TOUCH_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1); |
| + |
| + Scroll(box, kWebGestureDeviceTouchscreen); |
| + EXPECT_TOUCH_BUCKET(kHasOpacityAndLCDText, 2); |
| + EXPECT_TOUCH_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 2); |
| + EXPECT_TOUCH_TOTAL(4); |
| + |
| + // Test wheel scroll. |
| + Scroll(box, kWebGestureDeviceTouchpad); |
| + EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1); |
| + EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1); |
| + EXPECT_WHEEL_TOTAL(2); |
| +} |
| + |
| +TEST_F(NonCompositedMainThreadScrollingReasonRecordTest, |
| + CompositedScrollableAreaTest) { |
| + SetHtmlInnerHTML( |
| + "<style>" |
| + " .box { overflow:scroll; width: 100px; height: 100px; }" |
| + " .translucent { opacity: 0.5; }" |
| + " .composited { will-change: transform; }" |
| + " .spacer { height: 1000px; }" |
| + "</style>" |
| + "<div id='box' class='translucent box'>" |
| + " <div class='spacer'></div>" |
| + "</div>"); |
| + |
| + GetPage().GetSettings().SetAcceleratedCompositingEnabled(true); |
| + GetDocument().View()->SetParentVisible(true); |
| + GetDocument().View()->SetSelfVisible(true); |
| + GetDocument().View()->UpdateAllLifecyclePhases(); |
| + |
| + Element* box = GetDocument().getElementById("box"); |
| + HistogramTester histogram_tester; |
| + |
| + Scroll(box, kWebGestureDeviceTouchpad); |
| + EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1); |
| + EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1); |
| + EXPECT_WHEEL_TOTAL(2); |
| + |
| + box->setAttribute("class", "composited translucent box"); |
| + GetDocument().View()->UpdateAllLifecyclePhases(); |
| + Scroll(box, kWebGestureDeviceTouchpad); |
| + EXPECT_FALSE(ToLayoutBox(box->GetLayoutObject()) |
| + ->GetScrollableArea() |
| + ->GetNonCompositedMainThreadScrollingReasons()); |
| + EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1); |
| + EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1); |
| + EXPECT_WHEEL_TOTAL(2); |
| +} |
| + |
| +TEST_F(NonCompositedMainThreadScrollingReasonRecordTest, |
| + NotScrollableAreaTest) { |
| + SetHtmlInnerHTML( |
| + "<style>.box { overflow:scroll; width: 100px; height: 100px; }" |
| + " .translucent { opacity: 0.5; }" |
| + " .hidden { overflow: hidden; }" |
| + " .spacer { height: 1000px; }" |
| + "</style>" |
| + "<div id='box' class='translucent box'>" |
| + " <div class='spacer'></div>" |
| + "</div>"); |
| + |
| + GetDocument().View()->UpdateAllLifecyclePhases(); |
| + |
| + Element* box = GetDocument().getElementById("box"); |
| + HistogramTester histogram_tester; |
| + |
| + Scroll(box, kWebGestureDeviceTouchpad); |
| + EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1); |
| + EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1); |
| + EXPECT_WHEEL_TOTAL(2); |
| + |
| + box->setAttribute("class", "hidden translucent box"); |
| + GetDocument().View()->UpdateAllLifecyclePhases(); |
| + Scroll(box, kWebGestureDeviceTouchpad); |
| + EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1); |
| + EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1); |
| + EXPECT_WHEEL_TOTAL(2); |
| +} |
| + |
| +TEST_F(NonCompositedMainThreadScrollingReasonRecordTest, NestedScrollersTest) { |
| + SetHtmlInnerHTML( |
| + "<style>" |
| + " .container { overflow:scroll; width: 200px; height: 200px; }" |
| + " .box { overflow:scroll; width: 100px; height: 100px; }" |
| + " .translucent { opacity: 0.5; }" |
| + " .transform { transform: scale(0.8); }" |
| + " .with-border-radius { border: 5px solid; border-radius: 5px; }" |
| + " .spacer { height: 1000px; }" |
| + " .composited { will-change: transform; }" |
| + "</style>" |
| + "<div id='container' class='container with-border-radius'>" |
| + " <div class='translucent box'>" |
| + " <div id='inner' class='composited transform box'>" |
| + " <div class='spacer'></div>" |
| + " </div>" |
| + " </div>" |
| + " <div class='spacer'></div>" |
| + "</div>"); |
| + |
| + GetPage().GetSettings().SetAcceleratedCompositingEnabled(true); |
| + GetDocument().View()->SetParentVisible(true); |
| + GetDocument().View()->SetSelfVisible(true); |
| + GetDocument().View()->UpdateAllLifecyclePhases(); |
| + |
| + Element* box = GetDocument().getElementById("inner"); |
| + HistogramTester histogram_tester; |
| + |
| + Scroll(box, kWebGestureDeviceTouchpad); |
| + // Scrolling the inner box will gather reasons from the scrolling chain. The |
| + // inner box itself has no reason because it's composited. Other scrollable |
| + // areas from the chain have corresponding reasons. |
| + EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1); |
| + EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1); |
| + EXPECT_WHEEL_BUCKET(kHasBorderRadius, 1); |
| + EXPECT_WHEEL_BUCKET(kHasTransformAndLCDText, 0); |
| + EXPECT_WHEEL_TOTAL(3); |
| +} |
| + |
| } // namespace blink |