OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/input/EventHandler.h" | 5 #include "core/input/EventHandler.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include "core/dom/ClientRect.h" | 8 #include "core/dom/ClientRect.h" |
9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
10 #include "core/dom/Range.h" | 10 #include "core/dom/Range.h" |
11 #include "core/editing/Editor.h" | 11 #include "core/editing/Editor.h" |
12 #include "core/editing/FrameSelection.h" | 12 #include "core/editing/FrameSelection.h" |
13 #include "core/frame/FrameView.h" | 13 #include "core/frame/FrameView.h" |
14 #include "core/frame/LocalFrame.h" | 14 #include "core/frame/LocalFrame.h" |
15 #include "core/frame/Settings.h" | 15 #include "core/frame/Settings.h" |
16 #include "core/layout/LayoutBox.h" | 16 #include "core/layout/LayoutBox.h" |
17 #include "core/loader/EmptyClients.h" | 17 #include "core/loader/EmptyClients.h" |
18 #include "core/page/AutoscrollController.h" | 18 #include "core/page/AutoscrollController.h" |
19 #include "core/page/Page.h" | 19 #include "core/page/Page.h" |
20 #include "core/paint/PaintLayerScrollableArea.h" | 20 #include "core/paint/PaintLayerScrollableArea.h" |
21 #include "core/testing/DummyPageHolder.h" | 21 #include "core/testing/DummyPageHolder.h" |
22 #include "platform/scroll/MainThreadScrollingReason.h" | 22 #include "platform/scroll/MainThreadScrollingReason.h" |
| 23 #include "platform/scroll/ScrollerSizeMetrics.h" |
23 #include "platform/testing/HistogramTester.h" | 24 #include "platform/testing/HistogramTester.h" |
24 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
25 | 26 |
26 #define EXPECT_WHEEL_BUCKET(reason, count) \ | 27 #define EXPECT_WHEEL_BUCKET(reason, count) \ |
27 histogram_tester.ExpectBucketCount( \ | 28 histogram_tester.ExpectBucketCount( \ |
28 "Renderer4.MainThreadWheelScrollReason", \ | 29 "Renderer4.MainThreadWheelScrollReason", \ |
29 GetBucketIndex(MainThreadScrollingReason::reason), count); | 30 GetBucketIndex(MainThreadScrollingReason::reason), count); |
30 | 31 |
31 #define EXPECT_TOUCH_BUCKET(reason, count) \ | 32 #define EXPECT_TOUCH_BUCKET(reason, count) \ |
32 histogram_tester.ExpectBucketCount( \ | 33 histogram_tester.ExpectBucketCount( \ |
(...skipping 12 matching lines...) Expand all Loading... |
45 | 46 |
46 class EventHandlerTest : public ::testing::Test { | 47 class EventHandlerTest : public ::testing::Test { |
47 protected: | 48 protected: |
48 void SetUp() override; | 49 void SetUp() override; |
49 | 50 |
50 Page& GetPage() const { return dummy_page_holder_->GetPage(); } | 51 Page& GetPage() const { return dummy_page_holder_->GetPage(); } |
51 Document& GetDocument() const { return dummy_page_holder_->GetDocument(); } | 52 Document& GetDocument() const { return dummy_page_holder_->GetDocument(); } |
52 FrameSelection& Selection() const { | 53 FrameSelection& Selection() const { |
53 return GetDocument().GetFrame()->Selection(); | 54 return GetDocument().GetFrame()->Selection(); |
54 } | 55 } |
55 | |
56 void SetHtmlInnerHTML(const char* html_content); | 56 void SetHtmlInnerHTML(const char* html_content); |
| 57 void Scroll(Element*, const WebGestureDevice); |
57 | 58 |
58 protected: | 59 protected: |
59 std::unique_ptr<DummyPageHolder> dummy_page_holder_; | 60 std::unique_ptr<DummyPageHolder> dummy_page_holder_; |
60 }; | 61 }; |
61 | 62 |
62 class NonCompositedMainThreadScrollingReasonRecordTest | 63 class NonCompositedMainThreadScrollingReasonRecordTest |
63 : public EventHandlerTest { | 64 : public EventHandlerTest { |
64 protected: | 65 protected: |
65 class ScrollBeginEventBuilder : public WebGestureEvent { | |
66 public: | |
67 ScrollBeginEventBuilder(IntPoint position, | |
68 FloatPoint delta, | |
69 WebGestureDevice device) | |
70 : WebGestureEvent() { | |
71 type_ = WebInputEvent::kGestureScrollBegin; | |
72 x = global_x = position.X(); | |
73 y = global_y = position.Y(); | |
74 data.scroll_begin.delta_y_hint = delta.Y(); | |
75 source_device = device; | |
76 frame_scale_ = 1; | |
77 } | |
78 }; | |
79 | |
80 class ScrollUpdateEventBuilder : public WebGestureEvent { | |
81 public: | |
82 ScrollUpdateEventBuilder() : WebGestureEvent() { | |
83 type_ = WebInputEvent::kGestureScrollUpdate; | |
84 data.scroll_update.delta_x = 0.0f; | |
85 data.scroll_update.delta_y = 1.0f; | |
86 data.scroll_update.velocity_x = 0; | |
87 data.scroll_update.velocity_y = 1; | |
88 frame_scale_ = 1; | |
89 } | |
90 }; | |
91 | |
92 class ScrollEndEventBuilder : public WebGestureEvent { | |
93 public: | |
94 ScrollEndEventBuilder() : WebGestureEvent() { | |
95 type_ = WebInputEvent::kGestureScrollEnd; | |
96 frame_scale_ = 1; | |
97 } | |
98 }; | |
99 | |
100 int GetBucketIndex(uint32_t reason); | 66 int GetBucketIndex(uint32_t reason); |
101 void Scroll(Element*, const WebGestureDevice); | |
102 }; | 67 }; |
103 | 68 |
104 class TapEventBuilder : public WebGestureEvent { | 69 class TapEventBuilder : public WebGestureEvent { |
105 public: | 70 public: |
106 TapEventBuilder(IntPoint position, int tap_count) | 71 TapEventBuilder(IntPoint position, int tap_count) |
107 : WebGestureEvent(WebInputEvent::kGestureTap, | 72 : WebGestureEvent(WebInputEvent::kGestureTap, |
108 WebInputEvent::kNoModifiers, | 73 WebInputEvent::kNoModifiers, |
109 TimeTicks::Now().InSeconds()) { | 74 TimeTicks::Now().InSeconds()) { |
110 x = global_x = position.X(); | 75 x = global_x = position.X(); |
111 y = global_y = position.Y(); | 76 y = global_y = position.Y(); |
(...skipping 27 matching lines...) Expand all Loading... |
139 WebInputEvent::kNoModifiers, | 104 WebInputEvent::kNoModifiers, |
140 TimeTicks::Now().InSeconds()) { | 105 TimeTicks::Now().InSeconds()) { |
141 click_count = click_count_param; | 106 click_count = click_count_param; |
142 button = button_param; | 107 button = button_param; |
143 SetPositionInWidget(position_param.X(), position_param.Y()); | 108 SetPositionInWidget(position_param.X(), position_param.Y()); |
144 SetPositionInScreen(position_param.X(), position_param.Y()); | 109 SetPositionInScreen(position_param.X(), position_param.Y()); |
145 frame_scale_ = 1; | 110 frame_scale_ = 1; |
146 } | 111 } |
147 }; | 112 }; |
148 | 113 |
| 114 class ScrollBeginEventBuilder : public WebGestureEvent { |
| 115 public: |
| 116 ScrollBeginEventBuilder(IntPoint position, |
| 117 FloatPoint delta, |
| 118 WebGestureDevice device) |
| 119 : WebGestureEvent() { |
| 120 type_ = WebInputEvent::kGestureScrollBegin; |
| 121 x = global_x = position.X(); |
| 122 y = global_y = position.Y(); |
| 123 data.scroll_begin.delta_y_hint = delta.Y(); |
| 124 source_device = device; |
| 125 frame_scale_ = 1; |
| 126 } |
| 127 }; |
| 128 |
| 129 class ScrollUpdateEventBuilder : public WebGestureEvent { |
| 130 public: |
| 131 ScrollUpdateEventBuilder() : WebGestureEvent() { |
| 132 type_ = WebInputEvent::kGestureScrollUpdate; |
| 133 data.scroll_update.delta_x = 0.0f; |
| 134 data.scroll_update.delta_y = 1.0f; |
| 135 data.scroll_update.velocity_x = 0; |
| 136 data.scroll_update.velocity_y = 1; |
| 137 frame_scale_ = 1; |
| 138 } |
| 139 }; |
| 140 |
| 141 class ScrollEndEventBuilder : public WebGestureEvent { |
| 142 public: |
| 143 ScrollEndEventBuilder() : WebGestureEvent() { |
| 144 type_ = WebInputEvent::kGestureScrollEnd; |
| 145 frame_scale_ = 1; |
| 146 } |
| 147 }; |
| 148 |
149 void EventHandlerTest::SetUp() { | 149 void EventHandlerTest::SetUp() { |
150 dummy_page_holder_ = DummyPageHolder::Create(IntSize(300, 400)); | 150 dummy_page_holder_ = DummyPageHolder::Create(IntSize(300, 400)); |
151 } | 151 } |
152 | 152 |
153 void EventHandlerTest::SetHtmlInnerHTML(const char* html_content) { | 153 void EventHandlerTest::SetHtmlInnerHTML(const char* html_content) { |
154 GetDocument().documentElement()->setInnerHTML(String::FromUTF8(html_content)); | 154 GetDocument().documentElement()->setInnerHTML(String::FromUTF8(html_content)); |
155 GetDocument().View()->UpdateAllLifecyclePhases(); | 155 GetDocument().View()->UpdateAllLifecyclePhases(); |
156 } | 156 } |
157 | 157 |
158 int NonCompositedMainThreadScrollingReasonRecordTest::GetBucketIndex( | 158 int NonCompositedMainThreadScrollingReasonRecordTest::GetBucketIndex( |
159 uint32_t reason) { | 159 uint32_t reason) { |
160 int index = 1; | 160 int index = 1; |
161 while (!(reason & 1)) { | 161 while (!(reason & 1)) { |
162 reason >>= 1; | 162 reason >>= 1; |
163 ++index; | 163 ++index; |
164 } | 164 } |
165 DCHECK_EQ(reason, 1u); | 165 DCHECK_EQ(reason, 1u); |
166 return index; | 166 return index; |
167 } | 167 } |
168 | 168 |
169 void NonCompositedMainThreadScrollingReasonRecordTest::Scroll( | 169 void EventHandlerTest::Scroll(Element* element, const WebGestureDevice device) { |
170 Element* element, | |
171 const WebGestureDevice device) { | |
172 DCHECK(element); | 170 DCHECK(element); |
173 DCHECK(element->getBoundingClientRect()); | 171 DCHECK(element->getBoundingClientRect()); |
174 ClientRect* rect = element->getBoundingClientRect(); | 172 ClientRect* rect = element->getBoundingClientRect(); |
175 ScrollBeginEventBuilder scroll_begin( | 173 ScrollBeginEventBuilder scroll_begin( |
176 IntPoint(rect->left() + rect->width() / 2, | 174 IntPoint(rect->left() + rect->width() / 2, |
177 rect->top() + rect->height() / 2), | 175 rect->top() + rect->height() / 2), |
178 FloatPoint(0.f, 1.f), device); | 176 FloatPoint(0.f, 1.f), device); |
179 ScrollUpdateEventBuilder scroll_update; | 177 ScrollUpdateEventBuilder scroll_update; |
180 ScrollEndEventBuilder scroll_end; | 178 ScrollEndEventBuilder scroll_end; |
181 GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_begin); | 179 GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_begin); |
182 GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_update); | 180 GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_update); |
183 GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_end); | 181 GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_end); |
| 182 ASSERT_GT(scroll_update.DeltaYInRootFrame(), 0); |
184 } | 183 } |
185 | 184 |
186 TEST_F(EventHandlerTest, dragSelectionAfterScroll) { | 185 TEST_F(EventHandlerTest, dragSelectionAfterScroll) { |
187 SetHtmlInnerHTML( | 186 SetHtmlInnerHTML( |
188 "<style> body { margin: 0px; } .upper { width: 300px; height: 400px; }" | 187 "<style> body { margin: 0px; } .upper { width: 300px; height: 400px; }" |
189 ".lower { margin: 0px; width: 300px; height: 400px; } .line { display: " | 188 ".lower { margin: 0px; width: 300px; height: 400px; } .line { display: " |
190 "block; width: 300px; height: 30px; } </style>" | 189 "block; width: 300px; height: 30px; } </style>" |
191 "<div class='upper'></div>" | 190 "<div class='upper'></div>" |
192 "<div class='lower'>" | 191 "<div class='lower'>" |
193 "<span class='line'>Line 1</span><span class='line'>Line 2</span><span " | 192 "<span class='line'>Line 1</span><span class='line'>Line 2</span><span " |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 WebInputEvent::kMouseUp, WebFloatPoint(100, 50), WebFloatPoint(200, 250), | 573 WebInputEvent::kMouseUp, WebFloatPoint(100, 50), WebFloatPoint(200, 250), |
575 WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers, | 574 WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers, |
576 TimeTicks::Now().InSeconds()); | 575 TimeTicks::Now().InSeconds()); |
577 mouse_up_event.SetFrameScale(1); | 576 mouse_up_event.SetFrameScale(1); |
578 GetDocument().GetFrame()->GetEventHandler().DragSourceEndedAt( | 577 GetDocument().GetFrame()->GetEventHandler().DragSourceEndedAt( |
579 mouse_up_event, kDragOperationNone); | 578 mouse_up_event, kDragOperationNone); |
580 | 579 |
581 // This test passes if it doesn't crash. | 580 // This test passes if it doesn't crash. |
582 } | 581 } |
583 | 582 |
| 583 TEST_F(EventHandlerTest, |
| 584 ScrollerSizeOfMainThreadScrollingHistogramRecordingTest) { |
| 585 SetHtmlInnerHTML( |
| 586 "<!DOCTYPE html>" |
| 587 "<style>" |
| 588 " .container { width: 200px; height: 200px; overflow: scroll; }" |
| 589 " .box { width: 100px; height: 100px; overflow: scroll; }" |
| 590 " .spacer { height: 1000px; }" |
| 591 " .target { width: 200px; height: 200px; }" |
| 592 " body { height: 2000px; }" |
| 593 "</style>" |
| 594 "<div class='container'>" |
| 595 " <div id='box' class='box'>" |
| 596 " <div id='content' class='spacer'></div>" |
| 597 " </div>" |
| 598 "</div>" |
| 599 "<div id='target' class='target'></div>"); |
| 600 |
| 601 Element* box = GetDocument().getElementById("box"); |
| 602 HistogramTester histogram_tester; |
| 603 |
| 604 // Test wheel scroll on the box. |
| 605 Scroll(box, kWebGestureDeviceTouchpad); |
| 606 histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnScroll_Wheel", |
| 607 10000, 1); |
| 608 // Only the first scrollable area is recorded. |
| 609 histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnScroll_Wheel", |
| 610 40000, 0); |
| 611 histogram_tester.ExpectTotalCount("Event.Scroll.ScrollerSize.OnScroll_Wheel", |
| 612 1); |
| 613 |
| 614 // Test touch scroll. |
| 615 Scroll(box, kWebGestureDeviceTouchscreen); |
| 616 histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnScroll_Touch", |
| 617 10000, 1); |
| 618 histogram_tester.ExpectTotalCount("Event.Scroll.ScrollerSize.OnScroll_Touch", |
| 619 1); |
| 620 |
| 621 // Scrolling the non-scrollable target leads to scroll the root layer which |
| 622 // doesn't add to count. |
| 623 Element* body_scroll_target = GetDocument().getElementById("target"); |
| 624 Scroll(body_scroll_target, kWebGestureDeviceTouchscreen); |
| 625 histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnScroll_Touch", |
| 626 kScrollerSizeLargestBucket, 0); |
| 627 histogram_tester.ExpectTotalCount("Event.Scroll.ScrollerSize.OnScroll_Touch", |
| 628 1); |
| 629 } |
| 630 |
584 class TooltipCapturingChromeClient : public EmptyChromeClient { | 631 class TooltipCapturingChromeClient : public EmptyChromeClient { |
585 public: | 632 public: |
586 TooltipCapturingChromeClient() {} | 633 TooltipCapturingChromeClient() {} |
587 | 634 |
588 void SetToolTip(LocalFrame&, const String& str, TextDirection) override { | 635 void SetToolTip(LocalFrame&, const String& str, TextDirection) override { |
589 last_tool_tip_ = str; | 636 last_tool_tip_ = str; |
590 } | 637 } |
591 | 638 |
592 String& LastToolTip() { return last_tool_tip_; } | 639 String& LastToolTip() { return last_tool_tip_; } |
593 | 640 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 // inner box itself has no reason because it's composited. Other scrollable | 823 // inner box itself has no reason because it's composited. Other scrollable |
777 // areas from the chain have corresponding reasons. | 824 // areas from the chain have corresponding reasons. |
778 EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1); | 825 EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1); |
779 EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1); | 826 EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1); |
780 EXPECT_WHEEL_BUCKET(kHasBorderRadius, 1); | 827 EXPECT_WHEEL_BUCKET(kHasBorderRadius, 1); |
781 EXPECT_WHEEL_BUCKET(kHasTransformAndLCDText, 0); | 828 EXPECT_WHEEL_BUCKET(kHasTransformAndLCDText, 0); |
782 EXPECT_WHEEL_TOTAL(3); | 829 EXPECT_WHEEL_TOTAL(3); |
783 } | 830 } |
784 | 831 |
785 } // namespace blink | 832 } // namespace blink |
OLD | NEW |