Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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, ¶ms); | 167 InputHostMsg_HandleInputEvent_ACK::Read(message, ¶ms); |
| 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, ¶ms); | 185 InputHostMsg_HandleInputEvent_ACK::Read(message, ¶ms); |
| 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, ¶ms); | 212 InputHostMsg_HandleInputEvent_ACK::Read(message, ¶ms); |
| 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, ¶ms); | 223 InputHostMsg_HandleInputEvent_ACK::Read(message, ¶ms); |
| 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 Loading... | |
| 219 InputHostMsg_DidOverscroll::Param params; | 268 InputHostMsg_DidOverscroll::Param params; |
| 220 InputHostMsg_DidOverscroll::Read(message, ¶ms); | 269 InputHostMsg_DidOverscroll::Read(message, ¶ms); |
| 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 |
| OLD | NEW |