Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(572)

Side by Side Diff: content/renderer/render_widget_unittest.cc

Issue 1888163003: Articulate the cancel behavior in the WebTouchEvent. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Modify PlatformTouchEvent and address comments in patch set 1 Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/renderer/render_widget.h" 5 #include "content/renderer/render_widget.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/test/histogram_tester.h"
10 #include "content/common/input/synthetic_web_input_event_builders.h" 11 #include "content/common/input/synthetic_web_input_event_builders.h"
11 #include "content/common/input/web_input_event_traits.h" 12 #include "content/common/input/web_input_event_traits.h"
12 #include "content/common/input_messages.h" 13 #include "content/common/input_messages.h"
13 #include "content/public/test/mock_render_thread.h" 14 #include "content/public/test/mock_render_thread.h"
14 #include "content/test/fake_compositor_dependencies.h" 15 #include "content/test/fake_compositor_dependencies.h"
15 #include "content/test/mock_render_process.h" 16 #include "content/test/mock_render_process.h"
16 #include "ipc/ipc_test_sink.h" 17 #include "ipc/ipc_test_sink.h"
18 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/WebKit/public/web/WebInputEvent.h" 20 #include "third_party/WebKit/public/web/WebInputEvent.h"
19 #include "ui/gfx/geometry/rect.h" 21 #include "ui/gfx/geometry/rect.h"
20 22
21 namespace content { 23 namespace content {
22 24
25 namespace {
26
27 const char* EVENT_LISTENER_RESULT_HISTOGRAM = "Event.PassiveListeners";
28
29 enum {
30 PASSIVE_LISTENER_UMA_ENUM_PASSIVE,
31 PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE,
32 PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED,
33 PASSIVE_LISTENER_UMA_ENUM_CANCELABLE,
34 PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED,
35 PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING,
36 PASSIVE_LISTENER_UMA_ENUM_COUNT
37 };
38
39 class MockWebWidget : public blink::WebWidget {
40 public:
41 MOCK_METHOD1(handleInputEvent,
42 blink::WebInputEventResult(const blink::WebInputEvent&));
43 };
44
45 } // namespace
46
23 class InteractiveRenderWidget : public RenderWidget { 47 class InteractiveRenderWidget : public RenderWidget {
24 public: 48 public:
25 explicit InteractiveRenderWidget(CompositorDependencies* compositor_deps) 49 explicit InteractiveRenderWidget(CompositorDependencies* compositor_deps)
26 : RenderWidget(compositor_deps, 50 : RenderWidget(compositor_deps,
27 blink::WebPopupTypeNone, 51 blink::WebPopupTypeNone,
28 blink::WebScreenInfo(), 52 blink::WebScreenInfo(),
29 false, 53 false,
30 false, 54 false,
31 false), 55 false),
32 always_overscroll_(false) { 56 always_overscroll_(false) {
57 webwidget_ = &mock_webwidget_;
33 // A RenderWidget is not fully initialized until it has a routing ID. 58 // A RenderWidget is not fully initialized until it has a routing ID.
34 SetRoutingID(++next_routing_id_); 59 SetRoutingID(++next_routing_id_);
35 } 60 }
36 61
37 void SetTouchRegion(const std::vector<gfx::Rect>& rects) { 62 void SetTouchRegion(const std::vector<gfx::Rect>& rects) {
38 rects_ = rects; 63 rects_ = rects;
39 } 64 }
40 65
41 void SendInputEvent(const blink::WebInputEvent& event) { 66 void SendInputEvent(const blink::WebInputEvent& event) {
42 OnHandleInputEvent( 67 OnHandleInputEvent(
43 &event, ui::LatencyInfo(), 68 &event, ui::LatencyInfo(),
44 WebInputEventTraits::ShouldBlockEventStream(event) 69 WebInputEventTraits::ShouldBlockEventStream(event)
45 ? InputEventDispatchType::DISPATCH_TYPE_BLOCKING 70 ? InputEventDispatchType::DISPATCH_TYPE_BLOCKING
46 : InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING); 71 : InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING);
47 } 72 }
48 73
49 void set_always_overscroll(bool overscroll) { 74 void set_always_overscroll(bool overscroll) {
50 always_overscroll_ = overscroll; 75 always_overscroll_ = overscroll;
51 } 76 }
52 77
53 IPC::TestSink* sink() { return &sink_; } 78 IPC::TestSink* sink() { return &sink_; }
54 79
80 MockWebWidget& mock_webwidget() { return mock_webwidget_; }
81
55 protected: 82 protected:
56 ~InteractiveRenderWidget() override {} 83 ~InteractiveRenderWidget() override { webwidget_ = NULL; }
57 84
58 // Overridden from RenderWidget: 85 // Overridden from RenderWidget:
59 bool HasTouchEventHandlersAt(const gfx::Point& point) const override { 86 bool HasTouchEventHandlersAt(const gfx::Point& point) const override {
60 for (std::vector<gfx::Rect>::const_iterator iter = rects_.begin(); 87 for (std::vector<gfx::Rect>::const_iterator iter = rects_.begin();
61 iter != rects_.end(); ++iter) { 88 iter != rects_.end(); ++iter) {
62 if ((*iter).Contains(point)) 89 if ((*iter).Contains(point))
63 return true; 90 return true;
64 } 91 }
65 return false; 92 return false;
66 } 93 }
(...skipping 17 matching lines...) Expand all
84 bool Send(IPC::Message* msg) override { 111 bool Send(IPC::Message* msg) override {
85 sink_.OnMessageReceived(*msg); 112 sink_.OnMessageReceived(*msg);
86 delete msg; 113 delete msg;
87 return true; 114 return true;
88 } 115 }
89 116
90 private: 117 private:
91 std::vector<gfx::Rect> rects_; 118 std::vector<gfx::Rect> rects_;
92 IPC::TestSink sink_; 119 IPC::TestSink sink_;
93 bool always_overscroll_; 120 bool always_overscroll_;
121 MockWebWidget mock_webwidget_;
94 static int next_routing_id_; 122 static int next_routing_id_;
95 123
96 DISALLOW_COPY_AND_ASSIGN(InteractiveRenderWidget); 124 DISALLOW_COPY_AND_ASSIGN(InteractiveRenderWidget);
97 }; 125 };
98 126
99 int InteractiveRenderWidget::next_routing_id_ = 0; 127 int InteractiveRenderWidget::next_routing_id_ = 0;
100 128
101 class RenderWidgetUnittest : public testing::Test { 129 class RenderWidgetUnittest : public testing::Test {
102 public: 130 public:
103 RenderWidgetUnittest() 131 RenderWidgetUnittest()
104 : widget_(new InteractiveRenderWidget(&compositor_deps_)) {} 132 : widget_(new InteractiveRenderWidget(&compositor_deps_)) {}
105 ~RenderWidgetUnittest() override {} 133 ~RenderWidgetUnittest() override {}
106 134
107 InteractiveRenderWidget* widget() const { return widget_.get(); } 135 InteractiveRenderWidget* widget() const { return widget_.get(); }
108 136
137 const base::HistogramTester& histogram_tester() const {
138 return histogram_tester_;
139 }
140
109 private: 141 private:
110 MockRenderProcess render_process_; 142 MockRenderProcess render_process_;
111 MockRenderThread render_thread_; 143 MockRenderThread render_thread_;
112 FakeCompositorDependencies compositor_deps_; 144 FakeCompositorDependencies compositor_deps_;
113 scoped_refptr<InteractiveRenderWidget> widget_; 145 scoped_refptr<InteractiveRenderWidget> widget_;
146 base::HistogramTester histogram_tester_;
114 147
115 DISALLOW_COPY_AND_ASSIGN(RenderWidgetUnittest); 148 DISALLOW_COPY_AND_ASSIGN(RenderWidgetUnittest);
116 }; 149 };
117 150
118 TEST_F(RenderWidgetUnittest, TouchHitTestSinglePoint) { 151 TEST_F(RenderWidgetUnittest, TouchHitTestSinglePoint) {
119 SyntheticWebTouchEvent touch; 152 SyntheticWebTouchEvent touch;
120 touch.PressPoint(10, 10); 153 touch.PressPoint(10, 10);
121 154
155 EXPECT_CALL(widget()->mock_webwidget(), handleInputEvent(::testing::_))
tdresser 2016/04/18 19:40:45 Feel free to "using testing::_".
dtapuska 2016/04/18 20:09:09 Done.
156 .WillRepeatedly(
157 ::testing::Return(blink::WebInputEventResult::NotHandled));
158
122 widget()->SendInputEvent(touch); 159 widget()->SendInputEvent(touch);
123 ASSERT_EQ(1u, widget()->sink()->message_count()); 160 ASSERT_EQ(1u, widget()->sink()->message_count());
124 161
125 // Since there's currently no touch-event handling region, the response should 162 // Since there's currently no touch-event handling region, the response should
126 // be 'no consumer exists'. 163 // be 'no consumer exists'.
127 const IPC::Message* message = widget()->sink()->GetMessageAt(0); 164 const IPC::Message* message = widget()->sink()->GetMessageAt(0);
128 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type()); 165 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
129 InputHostMsg_HandleInputEvent_ACK::Param params; 166 InputHostMsg_HandleInputEvent_ACK::Param params;
130 InputHostMsg_HandleInputEvent_ACK::Read(message, &params); 167 InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
131 InputEventAckState ack_state = base::get<0>(params).state; 168 InputEventAckState ack_state = base::get<0>(params).state;
132 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state); 169 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state);
133 widget()->sink()->ClearMessages(); 170 widget()->sink()->ClearMessages();
134 171
135 std::vector<gfx::Rect> rects; 172 std::vector<gfx::Rect> rects;
136 rects.push_back(gfx::Rect(0, 0, 20, 20)); 173 rects.push_back(gfx::Rect(0, 0, 20, 20));
137 rects.push_back(gfx::Rect(25, 0, 10, 10)); 174 rects.push_back(gfx::Rect(25, 0, 10, 10));
138 widget()->SetTouchRegion(rects); 175 widget()->SetTouchRegion(rects);
139 176
177 EXPECT_CALL(widget()->mock_webwidget(), handleInputEvent(::testing::_))
178 .WillRepeatedly(
179 ::testing::Return(blink::WebInputEventResult::NotHandled));
180
140 widget()->SendInputEvent(touch); 181 widget()->SendInputEvent(touch);
141 ASSERT_EQ(1u, widget()->sink()->message_count()); 182 ASSERT_EQ(1u, widget()->sink()->message_count());
142 message = widget()->sink()->GetMessageAt(0); 183 message = widget()->sink()->GetMessageAt(0);
143 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type()); 184 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
144 InputHostMsg_HandleInputEvent_ACK::Read(message, &params); 185 InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
145 ack_state = base::get<0>(params).state; 186 ack_state = base::get<0>(params).state;
146 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state); 187 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state);
147 widget()->sink()->ClearMessages(); 188 widget()->sink()->ClearMessages();
148 } 189 }
149 190
150 TEST_F(RenderWidgetUnittest, TouchHitTestMultiplePoints) { 191 TEST_F(RenderWidgetUnittest, TouchHitTestMultiplePoints) {
151 std::vector<gfx::Rect> rects; 192 std::vector<gfx::Rect> rects;
152 rects.push_back(gfx::Rect(0, 0, 20, 20)); 193 rects.push_back(gfx::Rect(0, 0, 20, 20));
153 rects.push_back(gfx::Rect(25, 0, 10, 10)); 194 rects.push_back(gfx::Rect(25, 0, 10, 10));
154 widget()->SetTouchRegion(rects); 195 widget()->SetTouchRegion(rects);
155 196
156 SyntheticWebTouchEvent touch; 197 SyntheticWebTouchEvent touch;
157 touch.PressPoint(25, 25); 198 touch.PressPoint(25, 25);
158 199
200 EXPECT_CALL(widget()->mock_webwidget(), handleInputEvent(::testing::_))
201 .WillRepeatedly(
202 ::testing::Return(blink::WebInputEventResult::NotHandled));
203
159 widget()->SendInputEvent(touch); 204 widget()->SendInputEvent(touch);
160 ASSERT_EQ(1u, widget()->sink()->message_count()); 205 ASSERT_EQ(1u, widget()->sink()->message_count());
161 206
162 // Since there's currently no touch-event handling region, the response should 207 // Since there's currently no touch-event handling region, the response should
163 // be 'no consumer exists'. 208 // be 'no consumer exists'.
164 const IPC::Message* message = widget()->sink()->GetMessageAt(0); 209 const IPC::Message* message = widget()->sink()->GetMessageAt(0);
165 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type()); 210 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
166 InputHostMsg_HandleInputEvent_ACK::Param params; 211 InputHostMsg_HandleInputEvent_ACK::Param params;
167 InputHostMsg_HandleInputEvent_ACK::Read(message, &params); 212 InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
168 InputEventAckState ack_state = base::get<0>(params).state; 213 InputEventAckState ack_state = base::get<0>(params).state;
169 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state); 214 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state);
170 widget()->sink()->ClearMessages(); 215 widget()->sink()->ClearMessages();
171 216
172 // Press a second touch point. This time, on a touch-handling region. 217 // Press a second touch point. This time, on a touch-handling region.
173 touch.PressPoint(10, 10); 218 touch.PressPoint(10, 10);
174 widget()->SendInputEvent(touch); 219 widget()->SendInputEvent(touch);
175 ASSERT_EQ(1u, widget()->sink()->message_count()); 220 ASSERT_EQ(1u, widget()->sink()->message_count());
176 message = widget()->sink()->GetMessageAt(0); 221 message = widget()->sink()->GetMessageAt(0);
177 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type()); 222 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
178 InputHostMsg_HandleInputEvent_ACK::Read(message, &params); 223 InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
179 ack_state = base::get<0>(params).state; 224 ack_state = base::get<0>(params).state;
180 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state); 225 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state);
181 widget()->sink()->ClearMessages(); 226 widget()->sink()->ClearMessages();
182 } 227 }
183 228
184 TEST_F(RenderWidgetUnittest, EventOverscroll) { 229 TEST_F(RenderWidgetUnittest, EventOverscroll) {
185 widget()->set_always_overscroll(true); 230 widget()->set_always_overscroll(true);
186 231
232 EXPECT_CALL(widget()->mock_webwidget(), handleInputEvent(::testing::_))
233 .WillRepeatedly(
234 ::testing::Return(blink::WebInputEventResult::NotHandled));
235
187 blink::WebGestureEvent scroll; 236 blink::WebGestureEvent scroll;
188 scroll.type = blink::WebInputEvent::GestureScrollUpdate; 237 scroll.type = blink::WebInputEvent::GestureScrollUpdate;
189 scroll.x = -10; 238 scroll.x = -10;
190 scroll.data.scrollUpdate.deltaY = 10; 239 scroll.data.scrollUpdate.deltaY = 10;
191 widget()->SendInputEvent(scroll); 240 widget()->SendInputEvent(scroll);
192 241
193 // Overscroll notifications received while handling an input event should 242 // Overscroll notifications received while handling an input event should
194 // be bundled with the event ack IPC. 243 // be bundled with the event ack IPC.
195 ASSERT_EQ(1u, widget()->sink()->message_count()); 244 ASSERT_EQ(1u, widget()->sink()->message_count());
196 const IPC::Message* message = widget()->sink()->GetMessageAt(0); 245 const IPC::Message* message = widget()->sink()->GetMessageAt(0);
(...skipping 22 matching lines...) Expand all
219 InputHostMsg_DidOverscroll::Param params; 268 InputHostMsg_DidOverscroll::Param params;
220 InputHostMsg_DidOverscroll::Read(message, &params); 269 InputHostMsg_DidOverscroll::Read(message, &params);
221 const DidOverscrollParams& overscroll = base::get<0>(params); 270 const DidOverscrollParams& overscroll = base::get<0>(params);
222 EXPECT_EQ(gfx::Vector2dF(10, 5), overscroll.latest_overscroll_delta); 271 EXPECT_EQ(gfx::Vector2dF(10, 5), overscroll.latest_overscroll_delta);
223 EXPECT_EQ(gfx::Vector2dF(5, 5), overscroll.accumulated_overscroll); 272 EXPECT_EQ(gfx::Vector2dF(5, 5), overscroll.accumulated_overscroll);
224 EXPECT_EQ(gfx::PointF(1, 1), overscroll.causal_event_viewport_point); 273 EXPECT_EQ(gfx::PointF(1, 1), overscroll.causal_event_viewport_point);
225 EXPECT_EQ(gfx::Vector2dF(-10, -5), overscroll.current_fling_velocity); 274 EXPECT_EQ(gfx::Vector2dF(-10, -5), overscroll.current_fling_velocity);
226 widget()->sink()->ClearMessages(); 275 widget()->sink()->ClearMessages();
227 } 276 }
228 277
278 TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
tdresser 2016/04/18 19:40:45 Thanks for the test - this is great.
dtapuska 2016/04/18 20:09:09 Acknowledged.
279 SyntheticWebTouchEvent touch;
280 touch.PressPoint(10, 10);
281
282 EXPECT_CALL(widget()->mock_webwidget(), handleInputEvent(::testing::_))
283 .Times(4)
284 .WillRepeatedly(
285 ::testing::Return(blink::WebInputEventResult::NotHandled));
286
287 widget()->SendInputEvent(touch);
288 histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM,
289 PASSIVE_LISTENER_UMA_ENUM_CANCELABLE, 1);
290
291 touch.dispatchType = blink::WebInputEvent::DispatchType::EventNonBlocking;
292 widget()->SendInputEvent(touch);
293 histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM,
294 PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE,
295 1);
296
297 touch.dispatchType =
298 blink::WebInputEvent::DispatchType::ListenersNonBlockingPassive;
299 widget()->SendInputEvent(touch);
300 histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM,
301 PASSIVE_LISTENER_UMA_ENUM_PASSIVE, 1);
302
303 touch.dispatchType =
304 blink::WebInputEvent::DispatchType::ListenersForcedNonBlockingPassive;
305 widget()->SendInputEvent(touch);
306 histogram_tester().ExpectBucketCount(
307 EVENT_LISTENER_RESULT_HISTOGRAM,
308 PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING, 1);
309
310 EXPECT_CALL(widget()->mock_webwidget(), handleInputEvent(::testing::_))
311 .WillOnce(
312 ::testing::Return(blink::WebInputEventResult::HandledSuppressed));
313 touch.dispatchType = blink::WebInputEvent::DispatchType::Blocking;
314 widget()->SendInputEvent(touch);
315 histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM,
316 PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED, 1);
317
318 EXPECT_CALL(widget()->mock_webwidget(), handleInputEvent(::testing::_))
319 .WillOnce(
320 ::testing::Return(blink::WebInputEventResult::HandledApplication));
321 touch.dispatchType = blink::WebInputEvent::DispatchType::Blocking;
322 widget()->SendInputEvent(touch);
323 histogram_tester().ExpectBucketCount(
324 EVENT_LISTENER_RESULT_HISTOGRAM,
325 PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED, 1);
326 }
327
229 } // namespace content 328 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698