1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/input/input_router_impl.h"
6
7 #include <math.h>
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <memory>
12 #include <tuple>
13 #include <vector>
14
15 #include "base/command_line.h"
16 #include "base/location.h"
17 #include "base/run_loop.h"
18 #include "base/single_thread_task_runner.h"
19 #include "base/stl_util.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/test/scoped_feature_list.h"
22 #include "base/test/task_environment.h"
23 #include "base/threading/thread_task_runner_handle.h"
24 #include "build/build_config.h"
25 #include "cc/input/touch_action.h"
26 #include "content/browser/renderer_host/input/gesture_event_queue.h"
27 #include "content/browser/renderer_host/input/input_router_client.h"
28 #include "content/browser/renderer_host/input/mock_input_disposition_handler.h"
29 #include "content/browser/renderer_host/input/mock_input_router_client.h"
30 #include "content/common/content_constants_internal.h"
31 #include "content/common/input_messages.h"
32 #include "content/public/common/content_features.h"
33 #include "content/public/common/content_switches.h"
34 #include "content/public/test/mock_render_process_host.h"
35 #include "content/public/test/test_browser_context.h"
36 #include "content/test/mock_widget_input_handler.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 #include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h"
39 #include "third_party/blink/public/mojom/input/touch_event.mojom.h"
40 #include "ui/events/base_event_utils.h"
41 #include "ui/events/blink/blink_features.h"
42 #include "ui/events/blink/web_input_event_traits.h"
43 #include "ui/events/keycodes/keyboard_codes.h"
44
45 #if defined(USE_AURA)
46 #include "content/browser/renderer_host/ui_events_helper.h"
47 #include "ui/events/event.h"
48 #endif
49
50 #if defined(OS_WIN)
51 #include "ui/display/win/test/scoped_screen_win.h"
52 #endif
53
54 using blink::SyntheticWebGestureEventBuilder;
55 using blink::SyntheticWebMouseEventBuilder;
56 using blink::SyntheticWebMouseWheelEventBuilder;
57 using blink::SyntheticWebTouchEvent;
58 using blink::WebGestureDevice;
59 using blink::WebGestureEvent;
60 using blink::WebInputEvent;
61 using blink::WebKeyboardEvent;
62 using blink::WebMouseEvent;
63 using blink::WebMouseWheelEvent;
64 using blink::WebTouchEvent;
65 using blink::WebTouchPoint;
66 using ui::DidOverscrollParams;
67 using ui::WebInputEventTraits;
68
69 namespace content {
70
71 namespace {
72
ShouldBlockEventStream(const blink::WebInputEvent & event)73 bool ShouldBlockEventStream(const blink::WebInputEvent& event) {
74 return ui::WebInputEventTraits::ShouldBlockEventStream(event);
75 }
76
GetEventWithType(WebInputEvent::Type type)77 WebInputEvent& GetEventWithType(WebInputEvent::Type type) {
78 WebInputEvent* event = nullptr;
79 if (WebInputEvent::IsMouseEventType(type)) {
80 static WebMouseEvent mouse;
81 event = &mouse;
82 } else if (WebInputEvent::IsTouchEventType(type)) {
83 static WebTouchEvent touch;
84 event = &touch;
85 } else if (WebInputEvent::IsKeyboardEventType(type)) {
86 static WebKeyboardEvent key;
87 event = &key;
88 } else if (WebInputEvent::IsGestureEventType(type)) {
89 static WebGestureEvent gesture;
90 event = &gesture;
91 } else if (type == WebInputEvent::Type::kMouseWheel) {
92 static WebMouseWheelEvent wheel;
93 event = &wheel;
94 }
95 CHECK(event);
96 event->SetType(type);
97 return *event;
98 }
99
100 } // namespace
101
102 // TODO(dtapuska): Remove this class when we don't have multiple implementations
103 // of InputRouters.
104 class MockInputRouterImplClient : public InputRouterImplClient {
105 public:
GetWidgetInputHandler()106 blink::mojom::WidgetInputHandler* GetWidgetInputHandler() override {
107 return &widget_input_handler_;
108 }
109
OnImeCompositionRangeChanged(const gfx::Range & range,const std::vector<gfx::Rect> & character_bounds)110 void OnImeCompositionRangeChanged(
111 const gfx::Range& range,
112 const std::vector<gfx::Rect>& character_bounds) override {}
113
OnImeCancelComposition()114 void OnImeCancelComposition() override {}
115
SetMouseCapture(bool capture)116 void SetMouseCapture(bool capture) override {}
117
RequestMouseLock(bool from_user_gesture,bool unadjusted_movement,blink::mojom::WidgetInputHandlerHost::RequestMouseLockCallback response)118 void RequestMouseLock(
119 bool from_user_gesture,
120 bool unadjusted_movement,
121 blink::mojom::WidgetInputHandlerHost::RequestMouseLockCallback response)
122 override {}
123
GetRootWidgetViewportSize()124 gfx::Size GetRootWidgetViewportSize() override {
125 return gfx::Size(1920, 1080);
126 }
127
OnInvalidInputEventSource()128 void OnInvalidInputEventSource() override {}
129
GetAndResetDispatchedMessages()130 MockWidgetInputHandler::MessageVector GetAndResetDispatchedMessages() {
131 return widget_input_handler_.GetAndResetDispatchedMessages();
132 }
133
FilterInputEvent(const blink::WebInputEvent & input_event,const ui::LatencyInfo & latency_info)134 blink::mojom::InputEventResultState FilterInputEvent(
135 const blink::WebInputEvent& input_event,
136 const ui::LatencyInfo& latency_info) override {
137 return input_router_client_.FilterInputEvent(input_event, latency_info);
138 }
139
IncrementInFlightEventCount()140 void IncrementInFlightEventCount() override {
141 input_router_client_.IncrementInFlightEventCount();
142 }
143
DecrementInFlightEventCount(blink::mojom::InputEventResultSource ack_source)144 void DecrementInFlightEventCount(
145 blink::mojom::InputEventResultSource ack_source) override {
146 input_router_client_.DecrementInFlightEventCount(ack_source);
147 }
148
DidOverscroll(const ui::DidOverscrollParams & params)149 void DidOverscroll(const ui::DidOverscrollParams& params) override {
150 input_router_client_.DidOverscroll(params);
151 }
152
DidStartScrollingViewport()153 void DidStartScrollingViewport() override {
154 input_router_client_.DidStartScrollingViewport();
155 }
156
ForwardWheelEventWithLatencyInfo(const blink::WebMouseWheelEvent & wheel_event,const ui::LatencyInfo & latency_info)157 void ForwardWheelEventWithLatencyInfo(
158 const blink::WebMouseWheelEvent& wheel_event,
159 const ui::LatencyInfo& latency_info) override {
160 input_router_client_.ForwardWheelEventWithLatencyInfo(wheel_event,
161 latency_info);
162 }
163
ForwardGestureEventWithLatencyInfo(const blink::WebGestureEvent & gesture_event,const ui::LatencyInfo & latency_info)164 void ForwardGestureEventWithLatencyInfo(
165 const blink::WebGestureEvent& gesture_event,
166 const ui::LatencyInfo& latency_info) override {
167 input_router_client_.ForwardGestureEventWithLatencyInfo(gesture_event,
168 latency_info);
169 }
170
IsWheelScrollInProgress()171 bool IsWheelScrollInProgress() override {
172 return input_router_client_.IsWheelScrollInProgress();
173 }
174
IsAutoscrollInProgress()175 bool IsAutoscrollInProgress() override {
176 return input_router_client_.IsAutoscrollInProgress();
177 }
178
OnSetCompositorAllowedTouchAction(cc::TouchAction touch_action)179 void OnSetCompositorAllowedTouchAction(
180 cc::TouchAction touch_action) override {
181 input_router_client_.OnSetCompositorAllowedTouchAction(touch_action);
182 }
183
GetAndResetFilterEventCalled()184 bool GetAndResetFilterEventCalled() {
185 return input_router_client_.GetAndResetFilterEventCalled();
186 }
187
GetAndResetOverscroll()188 ui::DidOverscrollParams GetAndResetOverscroll() {
189 return input_router_client_.GetAndResetOverscroll();
190 }
191
GetAndResetCompositorAllowedTouchAction()192 cc::TouchAction GetAndResetCompositorAllowedTouchAction() {
193 return input_router_client_.GetAndResetCompositorAllowedTouchAction();
194 }
195
set_input_router(InputRouter * input_router)196 void set_input_router(InputRouter* input_router) {
197 input_router_client_.set_input_router(input_router);
198 }
199
set_filter_state(blink::mojom::InputEventResultState filter_state)200 void set_filter_state(blink::mojom::InputEventResultState filter_state) {
201 input_router_client_.set_filter_state(filter_state);
202 }
in_flight_event_count() const203 int in_flight_event_count() const {
204 return input_router_client_.in_flight_event_count();
205 }
last_in_flight_event_type() const206 blink::WebInputEvent::Type last_in_flight_event_type() const {
207 return input_router_client_.last_in_flight_event_type();
208 }
set_allow_send_event(bool allow)209 void set_allow_send_event(bool allow) {
210 input_router_client_.set_allow_send_event(allow);
211 }
last_filter_event() const212 const blink::WebInputEvent* last_filter_event() const {
213 return input_router_client_.last_filter_event();
214 }
215
216 MockInputRouterClient input_router_client_;
217 MockWidgetInputHandler widget_input_handler_;
218 };
219
220 class InputRouterImplTestBase : public testing::Test {
221 public:
InputRouterImplTestBase()222 InputRouterImplTestBase()
223 : task_environment_(
224 base::test::SingleThreadTaskEnvironment::MainThreadType::UI) {}
225
~InputRouterImplTestBase()226 ~InputRouterImplTestBase() override {}
227
228 protected:
229 using DispatchedMessages = MockWidgetInputHandler::MessageVector;
230 // testing::Test
SetUp()231 void SetUp() override {
232 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
233 command_line->AppendSwitch(switches::kValidateInputEventStream);
234 client_.reset(new MockInputRouterImplClient());
235 disposition_handler_.reset(new MockInputDispositionHandler());
236 input_router_.reset(
237 new InputRouterImpl(client_.get(), disposition_handler_.get(),
238 &client_->input_router_client_, config_));
239
240 client_->set_input_router(input_router());
241 disposition_handler_->set_input_router(input_router());
242 }
243
TearDown()244 void TearDown() override {
245 // Process all pending tasks to avoid leaks.
246 base::RunLoop().RunUntilIdle();
247
248 input_router_.reset();
249 client_.reset();
250 }
251
SetUpForTouchAckTimeoutTest(int desktop_timeout_ms,int mobile_timeout_ms)252 void SetUpForTouchAckTimeoutTest(int desktop_timeout_ms,
253 int mobile_timeout_ms) {
254 config_.touch_config.desktop_touch_ack_timeout_delay =
255 base::TimeDelta::FromMilliseconds(desktop_timeout_ms);
256 config_.touch_config.mobile_touch_ack_timeout_delay =
257 base::TimeDelta::FromMilliseconds(mobile_timeout_ms);
258 config_.touch_config.touch_ack_timeout_supported = true;
259 TearDown();
260 SetUp();
261 input_router()->NotifySiteIsMobileOptimized(false);
262 }
263
SimulateKeyboardEvent(WebInputEvent::Type type)264 void SimulateKeyboardEvent(WebInputEvent::Type type) {
265 NativeWebKeyboardEventWithLatencyInfo key_event(
266 type, WebInputEvent::kNoModifiers, ui::EventTimeForNow(),
267 ui::LatencyInfo());
268 input_router_->SendKeyboardEvent(
269 key_event, disposition_handler_->CreateKeyboardEventCallback());
270 }
271
SimulateWheelEvent(float x,float y,float dX,float dY,int modifiers,bool precise,WebMouseWheelEvent::Phase phase)272 void SimulateWheelEvent(float x,
273 float y,
274 float dX,
275 float dY,
276 int modifiers,
277 bool precise,
278 WebMouseWheelEvent::Phase phase) {
279 WebMouseWheelEvent wheel_event = SyntheticWebMouseWheelEventBuilder::Build(
280 x, y, dX, dY, modifiers,
281 precise ? ui::ScrollGranularity::kScrollByPrecisePixel
282 : ui::ScrollGranularity::kScrollByPixel);
283 wheel_event.phase = phase;
284 input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(wheel_event));
285 }
286
SimulateWheelEvent(WebMouseWheelEvent::Phase phase)287 void SimulateWheelEvent(WebMouseWheelEvent::Phase phase) {
288 input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
289 SyntheticWebMouseWheelEventBuilder::Build(phase)));
290 }
291
SimulateMouseEvent(WebInputEvent::Type type,int x,int y)292 void SimulateMouseEvent(WebInputEvent::Type type, int x, int y) {
293 input_router_->SendMouseEvent(
294 MouseEventWithLatencyInfo(
295 SyntheticWebMouseEventBuilder::Build(type, x, y, 0)),
296 disposition_handler_->CreateMouseEventCallback());
297 }
298
SimulateGestureEvent(WebGestureEvent gesture)299 void SimulateGestureEvent(WebGestureEvent gesture) {
300 if (gesture.GetType() == WebInputEvent::Type::kGestureScrollBegin &&
301 gesture.SourceDevice() == blink::WebGestureDevice::kTouchscreen &&
302 !gesture.data.scroll_begin.delta_x_hint &&
303 !gesture.data.scroll_begin.delta_y_hint) {
304 // Ensure non-zero scroll-begin offset-hint to make the event sane,
305 // prevents unexpected filtering at TouchActionFilter.
306 gesture.data.scroll_begin.delta_y_hint = 2.f;
307 } else if (gesture.GetType() == WebInputEvent::Type::kGestureFlingStart &&
308 gesture.SourceDevice() ==
309 blink::WebGestureDevice::kTouchscreen &&
310 !gesture.data.fling_start.velocity_x &&
311 !gesture.data.fling_start.velocity_y) {
312 // Ensure non-zero touchscreen fling velocities, as the router will
313 // validate against such. The velocity should be large enough to make
314 // sure that the fling is still active while sending the GFC.
315 gesture.data.fling_start.velocity_x = 500.f;
316 } else if (gesture.GetType() == WebInputEvent::Type::kGestureFlingCancel) {
317 // Set prevent boosting to make sure that the GFC cancels the active
318 // fling.
319 gesture.data.fling_cancel.prevent_boosting = true;
320 }
321
322 input_router_->SendGestureEvent(GestureEventWithLatencyInfo(gesture));
323 }
324
SimulateGestureEvent(WebInputEvent::Type type,WebGestureDevice source_device)325 void SimulateGestureEvent(WebInputEvent::Type type,
326 WebGestureDevice source_device) {
327 SimulateGestureEvent(
328 SyntheticWebGestureEventBuilder::Build(type, source_device));
329 }
330
SimulateGestureScrollUpdateEvent(float dX,float dY,int modifiers,WebGestureDevice source_device)331 void SimulateGestureScrollUpdateEvent(float dX,
332 float dY,
333 int modifiers,
334 WebGestureDevice source_device) {
335 SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildScrollUpdate(
336 dX, dY, modifiers, source_device));
337 }
338
SimulateGesturePinchUpdateEvent(float scale,float anchor_x,float anchor_y,int modifiers,WebGestureDevice source_device)339 void SimulateGesturePinchUpdateEvent(float scale,
340 float anchor_x,
341 float anchor_y,
342 int modifiers,
343 WebGestureDevice source_device) {
344 SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildPinchUpdate(
345 scale, anchor_x, anchor_y, modifiers, source_device));
346 }
347
SimulateTouchpadGesturePinchEventWithoutWheel(WebInputEvent::Type type,float scale,float anchor_x,float anchor_y,int modifiers)348 void SimulateTouchpadGesturePinchEventWithoutWheel(WebInputEvent::Type type,
349 float scale,
350 float anchor_x,
351 float anchor_y,
352 int modifiers) {
353 DCHECK(blink::WebInputEvent::IsPinchGestureEventType(type));
354 WebGestureEvent event =
355 (type == blink::WebInputEvent::Type::kGesturePinchUpdate
356 ? SyntheticWebGestureEventBuilder::BuildPinchUpdate(
357 scale, anchor_x, anchor_y, modifiers,
358 blink::WebGestureDevice::kTouchpad)
359 : SyntheticWebGestureEventBuilder::Build(
360 type, blink::WebGestureDevice::kTouchpad));
361 // For touchpad pinch, we first send wheel events to the renderer. Only
362 // after these have been acknowledged do we send the actual gesture pinch
363 // events to the renderer. We indicate here that the wheel sending phase is
364 // done for the purpose of testing the sending of the gesture events
365 // themselves.
366 event.SetNeedsWheelEvent(false);
367 SimulateGestureEvent(event);
368 }
369
SimulateGestureFlingStartEvent(float velocity_x,float velocity_y,WebGestureDevice source_device)370 void SimulateGestureFlingStartEvent(float velocity_x,
371 float velocity_y,
372 WebGestureDevice source_device) {
373 SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildFling(
374 velocity_x, velocity_y, source_device));
375 }
376
SetTouchTimestamp(base::TimeTicks timestamp)377 void SetTouchTimestamp(base::TimeTicks timestamp) {
378 touch_event_.SetTimestamp(timestamp);
379 }
380
SendTouchEvent()381 uint32_t SendTouchEvent() {
382 uint32_t touch_event_id = touch_event_.unique_touch_event_id;
383 input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch_event_));
384 touch_event_.ResetPoints();
385 return touch_event_id;
386 }
387
PressTouchPoint(int x,int y)388 int PressTouchPoint(int x, int y) {
389 return touch_event_.PressPoint(x, y, radius_x_, radius_y_);
390 }
391
MoveTouchPoint(int index,int x,int y)392 void MoveTouchPoint(int index, int x, int y) {
393 touch_event_.MovePoint(index, x, y, radius_x_, radius_y_);
394 }
395
ReleaseTouchPoint(int index)396 void ReleaseTouchPoint(int index) { touch_event_.ReleasePoint(index); }
397
CancelTouchPoint(int index)398 void CancelTouchPoint(int index) { touch_event_.CancelPoint(index); }
399
input_router() const400 InputRouterImpl* input_router() const { return input_router_.get(); }
401
TouchEventQueueEmpty() const402 bool TouchEventQueueEmpty() const {
403 return input_router()->touch_event_queue_.Empty();
404 }
405
TouchEventTimeoutEnabled() const406 bool TouchEventTimeoutEnabled() const {
407 return input_router()->touch_event_queue_.IsAckTimeoutEnabled();
408 }
409
HasPendingEvents() const410 bool HasPendingEvents() const { return input_router_->HasPendingEvents(); }
411
HasTouchEventHandlers(bool has_handlers)412 bool HasTouchEventHandlers(bool has_handlers) { return has_handlers; }
HasHitTestableScrollbar(bool has_scrollbar)413 bool HasHitTestableScrollbar(bool has_scrollbar) { return has_scrollbar; }
414
OnHasTouchEventConsumers(blink::mojom::TouchEventConsumersPtr consumers)415 void OnHasTouchEventConsumers(
416 blink::mojom::TouchEventConsumersPtr consumers) {
417 input_router_->OnHasTouchEventConsumers(std::move(consumers));
418 }
419
CancelTouchTimeout()420 void CancelTouchTimeout() {
421 // InputRouterImpl::SetTouchActionFromMain calls
422 // InputRouterImpl::UpdateTouchAckTimeoutEnabled and that will cancel the
423 // touch timeout when the touch action is None.
424 input_router_->SetTouchActionFromMain(cc::TouchAction::kNone);
425 }
426
ResetTouchAction()427 void ResetTouchAction() {
428 input_router_->touch_action_filter_.ResetTouchAction();
429 }
430
GetAndResetDispatchedMessages()431 DispatchedMessages GetAndResetDispatchedMessages() {
432 return client_->GetAndResetDispatchedMessages();
433 }
434
RunTasksAndWait(base::TimeDelta delay)435 static void RunTasksAndWait(base::TimeDelta delay) {
436 base::RunLoop run_loop;
437 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
438 FROM_HERE, run_loop.QuitClosure(), delay);
439 run_loop.Run();
440 }
441
PressAndSetTouchActionAuto()442 void PressAndSetTouchActionAuto() {
443 PressTouchPoint(1, 1);
444 SendTouchEvent();
445 input_router_->SetTouchActionFromMain(cc::TouchAction::kAuto);
446 GetAndResetDispatchedMessages();
447 disposition_handler_->GetAndResetAckCount();
448 }
449
TouchActionSetFromMainNotOverridden()450 void TouchActionSetFromMainNotOverridden() {
451 input_router_->SetTouchActionFromMain(cc::TouchAction::kAuto);
452 ASSERT_TRUE(input_router_->AllowedTouchAction().has_value());
453 EXPECT_EQ(input_router_->AllowedTouchAction().value(),
454 cc::TouchAction::kAuto);
455 input_router_->TouchEventHandled(
456 TouchEventWithLatencyInfo(touch_event_),
457 blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(),
458 blink::mojom::InputEventResultState::kNoConsumerExists, nullptr,
459 blink::mojom::TouchActionOptional::New(cc::TouchAction::kPanY));
460 EXPECT_EQ(input_router_->AllowedTouchAction().value(),
461 cc::TouchAction::kAuto);
462 }
463
ActiveTouchSequenceCountTest(blink::mojom::TouchActionOptionalPtr touch_action,blink::mojom::InputEventResultState state)464 void ActiveTouchSequenceCountTest(
465 blink::mojom::TouchActionOptionalPtr touch_action,
466 blink::mojom::InputEventResultState state) {
467 PressTouchPoint(1, 1);
468 input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch_event_));
469 input_router_->TouchEventHandled(
470 TouchEventWithLatencyInfo(touch_event_),
471 blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(),
472 state, nullptr, std::move(touch_action));
473 EXPECT_EQ(input_router_->touch_action_filter_.num_of_active_touches_, 1);
474 ReleaseTouchPoint(0);
475 input_router_->OnTouchEventAck(
476 TouchEventWithLatencyInfo(touch_event_),
477 blink::mojom::InputEventResultSource::kMainThread, state);
478 EXPECT_EQ(input_router_->touch_action_filter_.num_of_active_touches_, 0);
479 }
480
StopTimeoutMonitorTest()481 void StopTimeoutMonitorTest() {
482 ResetTouchAction();
483 PressTouchPoint(1, 1);
484 input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch_event_));
485 EXPECT_TRUE(input_router_->touch_event_queue_.IsTimeoutRunningForTesting());
486 input_router_->TouchEventHandled(
487 TouchEventWithLatencyInfo(touch_event_),
488 blink::mojom::InputEventResultSource::kCompositorThread,
489 ui::LatencyInfo(), blink::mojom::InputEventResultState::kNotConsumed,
490 nullptr, blink::mojom::TouchActionOptional::New(cc::TouchAction::kPan));
491 EXPECT_TRUE(input_router_->touch_event_queue_.IsTimeoutRunningForTesting());
492 input_router_->SetTouchActionFromMain(cc::TouchAction::kPan);
493 EXPECT_FALSE(
494 input_router_->touch_event_queue_.IsTimeoutRunningForTesting());
495 }
496
OnTouchEventAckWithAckState(blink::mojom::InputEventResultSource source,blink::mojom::InputEventResultState ack_state,base::Optional<cc::TouchAction> expected_touch_action,base::Optional<cc::TouchAction> expected_allowed_touch_action)497 void OnTouchEventAckWithAckState(
498 blink::mojom::InputEventResultSource source,
499 blink::mojom::InputEventResultState ack_state,
500 base::Optional<cc::TouchAction> expected_touch_action,
501 base::Optional<cc::TouchAction> expected_allowed_touch_action) {
502 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
503 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
504 input_router_->OnHasTouchEventConsumers(std::move(touch_event_consumers));
505 EXPECT_FALSE(input_router_->AllowedTouchAction().has_value());
506 PressTouchPoint(1, 1);
507 input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch_event_));
508 input_router_->OnTouchEventAck(TouchEventWithLatencyInfo(touch_event_),
509 source, ack_state);
510 EXPECT_EQ(input_router_->AllowedTouchAction(), expected_touch_action);
511 EXPECT_EQ(
512 input_router_->touch_action_filter_.compositor_allowed_touch_action(),
513 expected_allowed_touch_action.value());
514 }
515
516 const float radius_x_ = 20.0f;
517 const float radius_y_ = 20.0f;
518 InputRouter::Config config_;
519 std::unique_ptr<MockInputRouterImplClient> client_;
520 std::unique_ptr<InputRouterImpl> input_router_;
521 std::unique_ptr<MockInputDispositionHandler> disposition_handler_;
522
523 private:
524 base::test::SingleThreadTaskEnvironment task_environment_;
525 SyntheticWebTouchEvent touch_event_;
526 };
527
528 class InputRouterImplTest : public InputRouterImplTestBase {
529 public:
530 InputRouterImplTest() = default;
531
AllowedTouchAction()532 base::Optional<cc::TouchAction> AllowedTouchAction() {
533 return input_router_->touch_action_filter_.allowed_touch_action_;
534 }
535
CompositorAllowedTouchAction()536 cc::TouchAction CompositorAllowedTouchAction() {
537 return input_router_->touch_action_filter_.compositor_allowed_touch_action_;
538 }
539 };
540
TEST_F(InputRouterImplTest,HandledInputEvent)541 TEST_F(InputRouterImplTest, HandledInputEvent) {
542 client_->set_filter_state(blink::mojom::InputEventResultState::kConsumed);
543
544 // Simulate a keyboard event.
545 SimulateKeyboardEvent(WebInputEvent::Type::kRawKeyDown);
546
547 // Make sure no input event is sent to the renderer.
548 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
549 EXPECT_EQ(0u, dispatched_messages.size());
550
551 // OnKeyboardEventAck should be triggered without actual ack.
552 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
553 }
554
TEST_F(InputRouterImplTest,ClientCanceledKeyboardEvent)555 TEST_F(InputRouterImplTest, ClientCanceledKeyboardEvent) {
556 client_->set_filter_state(
557 blink::mojom::InputEventResultState::kNoConsumerExists);
558
559 // Simulate a keyboard event that has no consumer.
560 SimulateKeyboardEvent(WebInputEvent::Type::kRawKeyDown);
561
562 // Make sure no input event is sent to the renderer.
563 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
564 EXPECT_EQ(0u, dispatched_messages.size());
565 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
566
567 // Simulate a keyboard event that should be dropped.
568 client_->set_filter_state(blink::mojom::InputEventResultState::kUnknown);
569 SimulateKeyboardEvent(WebInputEvent::Type::kRawKeyDown);
570
571 // Make sure no input event is sent to the renderer, and no ack is sent.
572 dispatched_messages = GetAndResetDispatchedMessages();
573 EXPECT_EQ(0u, dispatched_messages.size());
574 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
575 }
576
577 // Tests ported from RenderWidgetHostTest --------------------------------------
578
TEST_F(InputRouterImplTest,HandleKeyEventsWeSent)579 TEST_F(InputRouterImplTest, HandleKeyEventsWeSent) {
580 // Simulate a keyboard event.
581 SimulateKeyboardEvent(WebInputEvent::Type::kRawKeyDown);
582
583 // Make sure we sent the input event to the renderer.
584 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
585 ASSERT_EQ(1u, dispatched_messages.size());
586 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
587 dispatched_messages[0]->ToEvent()->CallCallback(
588 blink::mojom::InputEventResultState::kNotConsumed);
589 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
590 EXPECT_EQ(WebInputEvent::Type::kRawKeyDown,
591 disposition_handler_->acked_keyboard_event().GetType());
592 }
593
TEST_F(InputRouterImplTest,CoalescesWheelEvents)594 TEST_F(InputRouterImplTest, CoalescesWheelEvents) {
595 // Simulate wheel events.
596 SimulateWheelEvent(0, 0, 0, -5, 0, false,
597 WebMouseWheelEvent::kPhaseBegan); // sent directly
598 SimulateWheelEvent(0, 0, 0, -10, 0, false,
599 WebMouseWheelEvent::kPhaseChanged); // enqueued
600 SimulateWheelEvent(
601 0, 0, 8, -6, 0, false,
602 WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
603 SimulateWheelEvent(
604 0, 0, 9, -7, 1, false,
605 WebMouseWheelEvent::kPhaseChanged); // enqueued, different modifiers
606 SimulateWheelEvent(
607 0, 0, 0, -10, 0, false,
608 WebMouseWheelEvent::kPhaseChanged); // enqueued, different modifiers
609 // Explicitly verify that PhaseEnd isn't coalesced to avoid bugs like
610 // https://crbug.com/154740.
611 SimulateWheelEvent(WebMouseWheelEvent::kPhaseEnded); // enqueued
612
613 // Check that only the first event was sent.
614 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
615 ASSERT_EQ(1u, dispatched_messages.size());
616 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
617 ASSERT_EQ(WebInputEvent::Type::kMouseWheel,
618 dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
619 const WebMouseWheelEvent* wheel_event =
620 static_cast<const WebMouseWheelEvent*>(
621 &dispatched_messages[0]->ToEvent()->Event()->Event());
622 EXPECT_EQ(0, wheel_event->delta_x);
623 EXPECT_EQ(-5, wheel_event->delta_y);
624
625 // Check that the ACK sends the second message immediately.
626 dispatched_messages[0]->ToEvent()->CallCallback(
627 blink::mojom::InputEventResultState::kConsumed);
628 // The coalesced events can queue up a delayed ack
629 // so that additional input events can be processed before
630 // we turn off coalescing.
631 base::RunLoop().RunUntilIdle();
632 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
633 dispatched_messages = GetAndResetDispatchedMessages();
634 ASSERT_EQ(1u, dispatched_messages.size());
635 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
636 ASSERT_EQ(WebInputEvent::Type::kMouseWheel,
637 dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
638 wheel_event = static_cast<const WebMouseWheelEvent*>(
639 &dispatched_messages[0]->ToEvent()->Event()->Event());
640 EXPECT_EQ(8, wheel_event->delta_x);
641 EXPECT_EQ(-10 + -6, wheel_event->delta_y); // coalesced
642
643 // Ack the second event (which had the third coalesced into it).
644 dispatched_messages[0]->ToEvent()->CallCallback(
645 blink::mojom::InputEventResultState::kConsumed);
646 base::RunLoop().RunUntilIdle();
647 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
648 dispatched_messages = GetAndResetDispatchedMessages();
649 ASSERT_EQ(1u, dispatched_messages.size());
650 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
651 ASSERT_EQ(WebInputEvent::Type::kMouseWheel,
652 dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
653 wheel_event = static_cast<const WebMouseWheelEvent*>(
654 &dispatched_messages[0]->ToEvent()->Event()->Event());
655 EXPECT_EQ(9, wheel_event->delta_x);
656 EXPECT_EQ(-7, wheel_event->delta_y);
657
658 // Ack the fourth event.
659 dispatched_messages[0]->ToEvent()->CallCallback(
660 blink::mojom::InputEventResultState::kConsumed);
661 base::RunLoop().RunUntilIdle();
662 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
663 dispatched_messages = GetAndResetDispatchedMessages();
664 ASSERT_EQ(1u, dispatched_messages.size());
665 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
666 ASSERT_EQ(WebInputEvent::Type::kMouseWheel,
667 dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
668 wheel_event = static_cast<const WebMouseWheelEvent*>(
669 &dispatched_messages[0]->ToEvent()->Event()->Event());
670 EXPECT_EQ(0, wheel_event->delta_x);
671 EXPECT_EQ(-10, wheel_event->delta_y);
672
673 // Ack the fifth event.
674 dispatched_messages[0]->ToEvent()->CallCallback(
675 blink::mojom::InputEventResultState::kConsumed);
676 base::RunLoop().RunUntilIdle();
677 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
678 dispatched_messages = GetAndResetDispatchedMessages();
679 ASSERT_EQ(1u, dispatched_messages.size());
680 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
681 ASSERT_EQ(WebInputEvent::Type::kMouseWheel,
682 dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
683 wheel_event = static_cast<const WebMouseWheelEvent*>(
684 &dispatched_messages[0]->ToEvent()->Event()->Event());
685 EXPECT_EQ(0, wheel_event->delta_x);
686 EXPECT_EQ(0, wheel_event->delta_y);
687 EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase);
688
689 // After the final ack, the queue should be empty.
690 dispatched_messages[0]->ToEvent()->CallCallback(
691 blink::mojom::InputEventResultState::kConsumed);
692 base::RunLoop().RunUntilIdle();
693 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
694 dispatched_messages = GetAndResetDispatchedMessages();
695 EXPECT_EQ(0u, dispatched_messages.size());
696 }
697
698 // Test that the active touch sequence count increment when the touch start is
699 // not ACKed from the main thread.
TEST_F(InputRouterImplTest,ActiveTouchSequenceCountWithoutTouchAction)700 TEST_F(InputRouterImplTest, ActiveTouchSequenceCountWithoutTouchAction) {
701 ActiveTouchSequenceCountTest(
702 nullptr, blink::mojom::InputEventResultState::kSetNonBlocking);
703 }
704
TEST_F(InputRouterImplTest,ActiveTouchSequenceCountWithoutTouchActionNoConsumer)705 TEST_F(InputRouterImplTest,
706 ActiveTouchSequenceCountWithoutTouchActionNoConsumer) {
707 ActiveTouchSequenceCountTest(
708 nullptr, blink::mojom::InputEventResultState::kNoConsumerExists);
709 }
710
711 // Test that the active touch sequence count increment when the touch start is
712 // ACKed from the main thread.
TEST_F(InputRouterImplTest,ActiveTouchSequenceCountWithTouchAction)713 TEST_F(InputRouterImplTest, ActiveTouchSequenceCountWithTouchAction) {
714 ActiveTouchSequenceCountTest(
715 blink::mojom::TouchActionOptional::New(cc::TouchAction::kPanY),
716 blink::mojom::InputEventResultState::kSetNonBlocking);
717 }
718
TEST_F(InputRouterImplTest,ActiveTouchSequenceCountWithTouchActionNoConsumer)719 TEST_F(InputRouterImplTest, ActiveTouchSequenceCountWithTouchActionNoConsumer) {
720 ActiveTouchSequenceCountTest(
721 blink::mojom::TouchActionOptional::New(cc::TouchAction::kPanY),
722 blink::mojom::InputEventResultState::kNoConsumerExists);
723 }
724
725 // Test that after touch action is set from the main thread, the touch action
726 // won't be overridden by the call to TouchEventHandled.
TEST_F(InputRouterImplTest,TouchActionSetFromMainNotOverridden)727 TEST_F(InputRouterImplTest, TouchActionSetFromMainNotOverridden) {
728 TouchActionSetFromMainNotOverridden();
729 }
730
TEST_F(InputRouterImplTest,TouchActionAutoWithAckStateConsumed)731 TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateConsumed) {
732 base::Optional<cc::TouchAction> expected_touch_action;
733 OnTouchEventAckWithAckState(
734 blink::mojom::InputEventResultSource::kCompositorThread,
735 blink::mojom::InputEventResultState::kConsumed, expected_touch_action,
736 cc::TouchAction::kAuto);
737 }
738
TEST_F(InputRouterImplTest,TouchActionAutoWithAckStateNotConsumed)739 TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateNotConsumed) {
740 base::Optional<cc::TouchAction> expected_touch_action;
741 OnTouchEventAckWithAckState(
742 blink::mojom::InputEventResultSource::kCompositorThread,
743 blink::mojom::InputEventResultState::kNotConsumed, expected_touch_action,
744 cc::TouchAction::kAuto);
745 }
746
TEST_F(InputRouterImplTest,TouchActionAutoWithAckStateConsumedShouldBubble)747 TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateConsumedShouldBubble) {
748 base::Optional<cc::TouchAction> expected_touch_action;
749 OnTouchEventAckWithAckState(
750 blink::mojom::InputEventResultSource::kCompositorThread,
751 blink::mojom::InputEventResultState::kConsumedShouldBubble,
752 expected_touch_action, cc::TouchAction::kAuto);
753 }
754
TEST_F(InputRouterImplTest,TouchActionAutoWithAckStateNoConsumerExists)755 TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateNoConsumerExists) {
756 base::Optional<cc::TouchAction> expected_touch_action;
757 OnTouchEventAckWithAckState(
758 blink::mojom::InputEventResultSource::kCompositorThread,
759 blink::mojom::InputEventResultState::kNoConsumerExists,
760 expected_touch_action, cc::TouchAction::kAuto);
761 }
762
TEST_F(InputRouterImplTest,TouchActionAutoWithAckStateIgnored)763 TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateIgnored) {
764 base::Optional<cc::TouchAction> expected_touch_action;
765 OnTouchEventAckWithAckState(
766 blink::mojom::InputEventResultSource::kCompositorThread,
767 blink::mojom::InputEventResultState::kIgnored, expected_touch_action,
768 cc::TouchAction::kAuto);
769 }
770
TEST_F(InputRouterImplTest,TouchActionAutoWithAckStateNonBlocking)771 TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateNonBlocking) {
772 base::Optional<cc::TouchAction> expected_touch_action;
773 OnTouchEventAckWithAckState(
774 blink::mojom::InputEventResultSource::kCompositorThread,
775 blink::mojom::InputEventResultState::kSetNonBlocking,
776 expected_touch_action, cc::TouchAction::kAuto);
777 }
778
TEST_F(InputRouterImplTest,TouchActionAutoWithAckStateNonBlockingDueToFling)779 TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateNonBlockingDueToFling) {
780 base::Optional<cc::TouchAction> expected_touch_action;
781 OnTouchEventAckWithAckState(
782 blink::mojom::InputEventResultSource::kCompositorThread,
783 blink::mojom::InputEventResultState::kSetNonBlockingDueToFling,
784 expected_touch_action, cc::TouchAction::kAuto);
785 }
786
787 // Tests that touch-events are sent properly.
TEST_F(InputRouterImplTest,TouchEventQueue)788 TEST_F(InputRouterImplTest, TouchEventQueue) {
789 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
790 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
791 OnHasTouchEventConsumers(std::move(touch_event_consumers));
792
793 PressTouchPoint(1, 1);
794 SendTouchEvent();
795 input_router_->SetTouchActionFromMain(cc::TouchAction::kAuto);
796 EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
797 DispatchedMessages touch_start_event = GetAndResetDispatchedMessages();
798 ASSERT_EQ(1U, touch_start_event.size());
799 ASSERT_TRUE(touch_start_event[0]->ToEvent());
800 EXPECT_FALSE(TouchEventQueueEmpty());
801
802 // The second touch should be sent right away.
803 MoveTouchPoint(0, 5, 5);
804 SendTouchEvent();
805 DispatchedMessages touch_move_event = GetAndResetDispatchedMessages();
806 EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
807 ASSERT_EQ(1U, touch_move_event.size());
808 ASSERT_TRUE(touch_move_event[0]->ToEvent());
809 EXPECT_FALSE(TouchEventQueueEmpty());
810
811 // Receive an ACK for the first touch-event.
812 touch_start_event[0]->ToEvent()->CallCallback(
813 blink::mojom::InputEventResultState::kConsumed);
814 EXPECT_FALSE(TouchEventQueueEmpty());
815 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
816 EXPECT_EQ(WebInputEvent::Type::kTouchStart,
817 disposition_handler_->acked_touch_event().event.GetType());
818 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
819
820 touch_move_event[0]->ToEvent()->CallCallback(
821 blink::mojom::InputEventResultState::kConsumed);
822 EXPECT_TRUE(TouchEventQueueEmpty());
823 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
824 EXPECT_EQ(WebInputEvent::Type::kTouchMove,
825 disposition_handler_->acked_touch_event().event.GetType());
826 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
827 }
828
829 // Tests that the touch-queue is emptied after a page stops listening for touch
830 // events and the outstanding ack is received.
TEST_F(InputRouterImplTest,TouchEventQueueFlush)831 TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
832 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
833 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
834 OnHasTouchEventConsumers(std::move(touch_event_consumers));
835 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
836 EXPECT_TRUE(TouchEventQueueEmpty());
837
838 // Send a touch-press event.
839 PressTouchPoint(1, 1);
840 SendTouchEvent();
841 MoveTouchPoint(0, 2, 2);
842 MoveTouchPoint(0, 3, 3);
843 EXPECT_FALSE(TouchEventQueueEmpty());
844 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
845 ASSERT_EQ(1U, dispatched_messages.size());
846 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
847
848 // The page stops listening for touch-events. Note that flushing is deferred
849 // until the outstanding ack is received.
850 touch_event_consumers = blink::mojom::TouchEventConsumers::New(
851 HasTouchEventHandlers(false), HasHitTestableScrollbar(false));
852 OnHasTouchEventConsumers(std::move(touch_event_consumers));
853 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
854 EXPECT_FALSE(TouchEventQueueEmpty());
855
856 // After the ack, the touch-event queue should be empty, and none of the
857 // flushed touch-events should have been sent to the renderer.
858 dispatched_messages[0]->ToEvent()->CallCallback(
859 blink::mojom::InputEventResultState::kConsumed);
860 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
861 EXPECT_TRUE(TouchEventQueueEmpty());
862 }
863
TEST_F(InputRouterImplTest,UnhandledWheelEvent)864 TEST_F(InputRouterImplTest, UnhandledWheelEvent) {
865 // Simulate wheel events.
866 SimulateWheelEvent(0, 0, 0, -5, 0, false, WebMouseWheelEvent::kPhaseBegan);
867 SimulateWheelEvent(0, 0, 0, -10, 0, false, WebMouseWheelEvent::kPhaseChanged);
868
869 // Check that only the first event was sent.
870 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
871 ASSERT_EQ(1U, dispatched_messages.size());
872 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
873
874 // Indicate that the wheel event was unhandled.
875 dispatched_messages[0]->ToEvent()->CallCallback(
876 blink::mojom::InputEventResultState::kNotConsumed);
877
878 // There should be a ScrollBegin, ScrollUpdate, second MouseWheel, and second
879 // ScrollUpdate sent.
880 dispatched_messages = GetAndResetDispatchedMessages();
881 ASSERT_EQ(4U, dispatched_messages.size());
882 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
883 ASSERT_TRUE(dispatched_messages[1]->ToEvent());
884 ASSERT_TRUE(dispatched_messages[2]->ToEvent());
885 ASSERT_TRUE(dispatched_messages[3]->ToEvent());
886 ASSERT_EQ(WebInputEvent::Type::kGestureScrollBegin,
887 dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
888 ASSERT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
889 dispatched_messages[1]->ToEvent()->Event()->Event().GetType());
890 ASSERT_EQ(WebInputEvent::Type::kMouseWheel,
891 dispatched_messages[2]->ToEvent()->Event()->Event().GetType());
892 ASSERT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
893 dispatched_messages[3]->ToEvent()->Event()->Event().GetType());
894
895 // Indicate that the GestureScrollBegin event was consumed.
896 dispatched_messages[0]->ToEvent()->CallCallback(
897 blink::mojom::InputEventResultState::kConsumed);
898
899 // Check that the ack for the first MouseWheel, ScrollBegin, and the second
900 // MouseWheel were processed.
901 EXPECT_EQ(3U, disposition_handler_->GetAndResetAckCount());
902
903 // The last acked wheel event should be the second one since the input router
904 // has already sent the immediate ack for the second wheel event.
905 EXPECT_EQ(disposition_handler_->acked_wheel_event().delta_y, -10);
906 EXPECT_EQ(blink::mojom::InputEventResultState::kIgnored,
907 disposition_handler_->acked_wheel_event_state());
908
909 // Ack the first gesture scroll update.
910 dispatched_messages[1]->ToEvent()->CallCallback(
911 blink::mojom::InputEventResultState::kConsumed);
912
913 // Check that the ack for the first ScrollUpdate were processed.
914 EXPECT_EQ(
915 -5,
916 disposition_handler_->acked_gesture_event().data.scroll_update.delta_y);
917 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
918
919 // Ack the second gesture scroll update.
920 dispatched_messages[3]->ToEvent()->CallCallback(
921 blink::mojom::InputEventResultState::kConsumed);
922
923 // Check that the ack for the second ScrollUpdate were processed.
924 EXPECT_EQ(
925 -10,
926 disposition_handler_->acked_gesture_event().data.scroll_update.delta_y);
927 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
928 }
929
TEST_F(InputRouterImplTest,TouchTypesIgnoringAck)930 TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
931 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
932 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
933 OnHasTouchEventConsumers(std::move(touch_event_consumers));
934 // Only acks for TouchCancel should always be ignored.
935 ASSERT_TRUE(ShouldBlockEventStream(
936 GetEventWithType(WebInputEvent::Type::kTouchStart)));
937 ASSERT_TRUE(ShouldBlockEventStream(
938 GetEventWithType(WebInputEvent::Type::kTouchMove)));
939 ASSERT_TRUE(
940 ShouldBlockEventStream(GetEventWithType(WebInputEvent::Type::kTouchEnd)));
941
942 // Precede the TouchCancel with an appropriate TouchStart;
943 PressTouchPoint(1, 1);
944 SendTouchEvent();
945 input_router_->SetTouchActionFromMain(cc::TouchAction::kAuto);
946 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
947 ASSERT_EQ(1U, dispatched_messages.size());
948 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
949 dispatched_messages[0]->ToEvent()->CallCallback(
950 blink::mojom::InputEventResultState::kConsumed);
951 ASSERT_EQ(1U, disposition_handler_->GetAndResetAckCount());
952 ASSERT_EQ(0, client_->in_flight_event_count());
953
954 // The TouchCancel has no callback.
955 CancelTouchPoint(0);
956 SendTouchEvent();
957 dispatched_messages = GetAndResetDispatchedMessages();
958 ASSERT_EQ(1U, dispatched_messages.size());
959 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
960 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
961 EXPECT_EQ(0, client_->in_flight_event_count());
962 EXPECT_FALSE(HasPendingEvents());
963 EXPECT_FALSE(dispatched_messages[0]->ToEvent()->HasCallback());
964 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
965 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
966 EXPECT_FALSE(HasPendingEvents());
967 }
968
969 // TODO(https://crbug.com/866946): Test is flaky, especially on Mac & Fuchsia.
TEST_F(InputRouterImplTest,DISABLED_GestureTypesIgnoringAck)970 TEST_F(InputRouterImplTest, DISABLED_GestureTypesIgnoringAck) {
971 // We test every gesture type, ensuring that the stream of gestures is valid.
972
973 #if defined(OS_WIN)
974 display::win::test::ScopedScreenWin scoped_screen_win_;
975 #endif
976 const WebInputEvent::Type eventTypes[] = {
977 WebInputEvent::Type::kGestureTapDown,
978 WebInputEvent::Type::kGestureShowPress,
979 WebInputEvent::Type::kGestureTapCancel,
980 WebInputEvent::Type::kGestureScrollBegin,
981 WebInputEvent::Type::kGestureFlingStart,
982 WebInputEvent::Type::kGestureFlingCancel,
983 WebInputEvent::Type::kGestureTapDown,
984 WebInputEvent::Type::kGestureTap,
985 WebInputEvent::Type::kGestureTapDown,
986 WebInputEvent::Type::kGestureLongPress,
987 WebInputEvent::Type::kGestureTapCancel,
988 WebInputEvent::Type::kGestureLongTap,
989 WebInputEvent::Type::kGestureTapDown,
990 WebInputEvent::Type::kGestureTapUnconfirmed,
991 WebInputEvent::Type::kGestureTapCancel,
992 WebInputEvent::Type::kGestureTapDown,
993 WebInputEvent::Type::kGestureDoubleTap,
994 WebInputEvent::Type::kGestureTapDown,
995 WebInputEvent::Type::kGestureTapCancel,
996 WebInputEvent::Type::kGestureTwoFingerTap,
997 WebInputEvent::Type::kGestureTapDown,
998 WebInputEvent::Type::kGestureTapCancel,
999 WebInputEvent::Type::kGestureScrollBegin,
1000 WebInputEvent::Type::kGestureScrollUpdate,
1001 WebInputEvent::Type::kGesturePinchBegin,
1002 WebInputEvent::Type::kGesturePinchUpdate,
1003 WebInputEvent::Type::kGesturePinchEnd,
1004 WebInputEvent::Type::kGestureScrollEnd};
1005 for (size_t i = 0; i < base::size(eventTypes); ++i) {
1006 WebInputEvent::Type type = eventTypes[i];
1007 if (type == WebInputEvent::Type::kGestureFlingStart ||
1008 type == WebInputEvent::Type::kGestureFlingCancel) {
1009 SimulateGestureEvent(type, blink::WebGestureDevice::kTouchscreen);
1010 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1011
1012 if (type == WebInputEvent::Type::kGestureFlingCancel) {
1013 // The fling controller generates and sends a GSE while handling the
1014 // GFC.
1015 EXPECT_EQ(1U, dispatched_messages.size());
1016 EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
1017 } else {
1018 EXPECT_EQ(0U, dispatched_messages.size());
1019 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1020 }
1021
1022 EXPECT_EQ(0, client_->in_flight_event_count());
1023 EXPECT_FALSE(HasPendingEvents());
1024 } else if (ShouldBlockEventStream(GetEventWithType(type))) {
1025 PressAndSetTouchActionAuto();
1026 SimulateGestureEvent(type, blink::WebGestureDevice::kTouchscreen);
1027 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1028
1029 if (type == WebInputEvent::Type::kGestureScrollUpdate) {
1030 // TouchScrollStarted is also dispatched.
1031 EXPECT_EQ(2U, dispatched_messages.size());
1032 } else {
1033 EXPECT_EQ(1U, dispatched_messages.size());
1034 }
1035 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1036 EXPECT_EQ(1, client_->in_flight_event_count());
1037 EXPECT_TRUE(HasPendingEvents());
1038 ASSERT_TRUE(
1039 dispatched_messages[dispatched_messages.size() - 1]->ToEvent());
1040
1041 dispatched_messages[dispatched_messages.size() - 1]
1042 ->ToEvent()
1043 ->CallCallback(blink::mojom::InputEventResultState::kNotConsumed);
1044
1045 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1046 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1047 EXPECT_EQ(0, client_->in_flight_event_count());
1048 EXPECT_FALSE(HasPendingEvents());
1049 } else {
1050 SimulateGestureEvent(type, blink::WebGestureDevice::kTouchscreen);
1051 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1052 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1053 EXPECT_EQ(0, client_->in_flight_event_count());
1054 EXPECT_FALSE(HasPendingEvents());
1055 }
1056 }
1057 }
1058
TEST_F(InputRouterImplTest,MouseTypesIgnoringAck)1059 TEST_F(InputRouterImplTest, MouseTypesIgnoringAck) {
1060 int start_type = static_cast<int>(WebInputEvent::Type::kMouseDown);
1061 int end_type = static_cast<int>(WebInputEvent::Type::kContextMenu);
1062 ASSERT_LT(start_type, end_type);
1063 for (int i = start_type; i <= end_type; ++i) {
1064 WebInputEvent::Type type = static_cast<WebInputEvent::Type>(i);
1065
1066 SimulateMouseEvent(type, 0, 0);
1067 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1068 ASSERT_EQ(1U, dispatched_messages.size());
1069 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1070
1071 if (ShouldBlockEventStream(GetEventWithType(type))) {
1072 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1073 EXPECT_EQ(1, client_->in_flight_event_count());
1074
1075 dispatched_messages[0]->ToEvent()->CallCallback(
1076 blink::mojom::InputEventResultState::kNotConsumed);
1077 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1078 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1079 EXPECT_EQ(0, client_->in_flight_event_count());
1080 } else {
1081 // Note: events which don't block the event stream immediately receive
1082 // synthetic ACKs.
1083 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1084 EXPECT_EQ(0, client_->in_flight_event_count());
1085 }
1086 }
1087 }
1088
1089 // Guard against breaking changes to the list of ignored event ack types in
1090 // |WebInputEventTraits::ShouldBlockEventStream|.
TEST_F(InputRouterImplTest,RequiredEventAckTypes)1091 TEST_F(InputRouterImplTest, RequiredEventAckTypes) {
1092 const WebInputEvent::Type kRequiredEventAckTypes[] = {
1093 WebInputEvent::Type::kMouseMove,
1094 WebInputEvent::Type::kMouseWheel,
1095 WebInputEvent::Type::kRawKeyDown,
1096 WebInputEvent::Type::kKeyDown,
1097 WebInputEvent::Type::kKeyUp,
1098 WebInputEvent::Type::kChar,
1099 WebInputEvent::Type::kGestureScrollBegin,
1100 WebInputEvent::Type::kGestureScrollUpdate,
1101 WebInputEvent::Type::kTouchStart,
1102 WebInputEvent::Type::kTouchMove};
1103 for (size_t i = 0; i < base::size(kRequiredEventAckTypes); ++i) {
1104 const WebInputEvent::Type required_ack_type = kRequiredEventAckTypes[i];
1105 ASSERT_TRUE(ShouldBlockEventStream(GetEventWithType(required_ack_type)))
1106 << WebInputEvent::GetName(required_ack_type);
1107 }
1108 }
1109
TEST_F(InputRouterImplTest,GestureTypesIgnoringAckInterleaved)1110 TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
1111 // Interleave a few events that do and do not ignore acks. All gesture events
1112 // should be dispatched immediately, but the acks will be blocked on blocking
1113 // events.
1114 PressAndSetTouchActionAuto();
1115 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin,
1116 blink::WebGestureDevice::kTouchscreen);
1117 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1118 ASSERT_EQ(1U, dispatched_messages.size());
1119 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1120 dispatched_messages[0]->ToEvent()->CallCallback(
1121 blink::mojom::InputEventResultState::kConsumed);
1122 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1123 EXPECT_EQ(0, client_->in_flight_event_count());
1124
1125 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
1126 blink::WebGestureDevice::kTouchscreen);
1127 dispatched_messages = GetAndResetDispatchedMessages();
1128 // Should have sent |kTouchScrollStarted| and |kGestureScrollUpdate|.
1129 EXPECT_EQ(2U, dispatched_messages.size());
1130 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1131 EXPECT_EQ(1, client_->in_flight_event_count());
1132 EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
1133 client_->last_in_flight_event_type());
1134
1135 SimulateGestureEvent(WebInputEvent::Type::kGestureTapDown,
1136 blink::WebGestureDevice::kTouchscreen);
1137 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1138 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1139 EXPECT_EQ(1, client_->in_flight_event_count());
1140 EXPECT_EQ(WebInputEvent::Type::kGestureTapDown,
1141 client_->last_in_flight_event_type());
1142
1143 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
1144 blink::WebGestureDevice::kTouchscreen);
1145 DispatchedMessages temp_dispatched_messages = GetAndResetDispatchedMessages();
1146 EXPECT_EQ(1U, temp_dispatched_messages.size());
1147 dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
1148 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1149
1150 SimulateGestureEvent(WebInputEvent::Type::kGestureShowPress,
1151 blink::WebGestureDevice::kTouchscreen);
1152 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1153 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1154 EXPECT_EQ(2, client_->in_flight_event_count());
1155 EXPECT_EQ(WebInputEvent::Type::kGestureShowPress,
1156 client_->last_in_flight_event_type());
1157
1158 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
1159 blink::WebGestureDevice::kTouchscreen);
1160 temp_dispatched_messages = GetAndResetDispatchedMessages();
1161 EXPECT_EQ(1U, temp_dispatched_messages.size());
1162 dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
1163 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1164 EXPECT_EQ(3, client_->in_flight_event_count());
1165 EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
1166 client_->last_in_flight_event_type());
1167
1168 SimulateGestureEvent(WebInputEvent::Type::kGestureTapCancel,
1169 blink::WebGestureDevice::kTouchscreen);
1170 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1171 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1172 EXPECT_EQ(3, client_->in_flight_event_count());
1173 EXPECT_EQ(WebInputEvent::Type::kGestureTapCancel,
1174 client_->last_in_flight_event_type());
1175
1176 // Now ack each ack-respecting event. Should see in-flight event count
1177 // decreasing and additional acks coming back.
1178 // Ack the first GestureScrollUpdate, note that |at(0)| is TouchScrollStarted.
1179 ASSERT_EQ(4U, dispatched_messages.size());
1180 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1181 ASSERT_TRUE(dispatched_messages[1]->ToEvent());
1182 ASSERT_TRUE(dispatched_messages[2]->ToEvent());
1183 ASSERT_TRUE(dispatched_messages[3]->ToEvent());
1184 dispatched_messages[1]->ToEvent()->CallCallback(
1185 blink::mojom::InputEventResultState::kNotConsumed);
1186 EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
1187 EXPECT_EQ(2, client_->in_flight_event_count());
1188
1189 // Ack the second GestureScrollUpdate
1190 dispatched_messages[2]->ToEvent()->CallCallback(
1191 blink::mojom::InputEventResultState::kNotConsumed);
1192 EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
1193 EXPECT_EQ(1, client_->in_flight_event_count());
1194
1195 // Ack the last GestureScrollUpdate
1196 dispatched_messages[3]->ToEvent()->CallCallback(
1197 blink::mojom::InputEventResultState::kNotConsumed);
1198 EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
1199 EXPECT_EQ(0, client_->in_flight_event_count());
1200
1201 ReleaseTouchPoint(0);
1202 SendTouchEvent();
1203 }
1204
1205 // Test that GestureShowPress events don't get out of order due to
1206 // ignoring their acks.
TEST_F(InputRouterImplTest,GestureShowPressIsInOrder)1207 TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
1208 PressAndSetTouchActionAuto();
1209 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin,
1210 blink::WebGestureDevice::kTouchscreen);
1211 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1212 EXPECT_EQ(1U, dispatched_messages.size());
1213 dispatched_messages[0]->ToEvent()->CallCallback(
1214 blink::mojom::InputEventResultState::kConsumed);
1215 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1216
1217 // GesturePinchBegin ignores its ack.
1218 SimulateGestureEvent(WebInputEvent::Type::kGesturePinchBegin,
1219 blink::WebGestureDevice::kTouchscreen);
1220 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1221 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1222
1223 // GesturePinchUpdate ignores its ack.
1224 // This also verifies that GesturePinchUpdates for touchscreen are sent
1225 // to the renderer (in contrast to the TrackpadPinchUpdate test).
1226 SimulateGestureEvent(WebInputEvent::Type::kGesturePinchUpdate,
1227 blink::WebGestureDevice::kTouchscreen);
1228 dispatched_messages = GetAndResetDispatchedMessages();
1229 EXPECT_EQ(1U, dispatched_messages.size());
1230 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1231 EXPECT_EQ(0, client_->in_flight_event_count());
1232 EXPECT_EQ(WebInputEvent::Type::kGesturePinchUpdate,
1233 client_->last_in_flight_event_type());
1234
1235 // GestureScrollUpdate waits for an ack.
1236 // This dispatches TouchScrollStarted and GestureScrollUpdate.
1237 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
1238 blink::WebGestureDevice::kTouchscreen);
1239 dispatched_messages = GetAndResetDispatchedMessages();
1240 EXPECT_EQ(2U, dispatched_messages.size());
1241 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1242 EXPECT_EQ(1, client_->in_flight_event_count());
1243 EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
1244 client_->last_in_flight_event_type());
1245
1246 // GestureShowPress will be sent immediately since GestureEventQueue allows
1247 // multiple in-flight events. However the acks will be blocked on outstanding
1248 // in-flight events.
1249 SimulateGestureEvent(WebInputEvent::Type::kGestureShowPress,
1250 blink::WebGestureDevice::kTouchscreen);
1251 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1252 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1253 EXPECT_EQ(1, client_->in_flight_event_count());
1254 EXPECT_EQ(WebInputEvent::Type::kGestureShowPress,
1255 client_->last_in_flight_event_type());
1256
1257 SimulateGestureEvent(WebInputEvent::Type::kGestureShowPress,
1258 blink::WebGestureDevice::kTouchscreen);
1259 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1260 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1261 EXPECT_EQ(1, client_->in_flight_event_count());
1262 EXPECT_EQ(WebInputEvent::Type::kGestureShowPress,
1263 client_->last_in_flight_event_type());
1264
1265 // Ack the GestureScrollUpdate to release the two GestureShowPress acks.
1266 dispatched_messages[1]->ToEvent()->CallCallback(
1267 blink::mojom::InputEventResultState::kNotConsumed);
1268 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1269 EXPECT_EQ(3U, disposition_handler_->GetAndResetAckCount());
1270 EXPECT_EQ(0, client_->in_flight_event_count());
1271
1272 ReleaseTouchPoint(0);
1273 SendTouchEvent();
1274 }
1275
1276 // Test that touch ack timeout behavior is properly configured for
1277 // mobile-optimized sites and allowed touch actions.
TEST_F(InputRouterImplTest,TouchAckTimeoutConfigured)1278 TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
1279 const int kDesktopTimeoutMs = 1;
1280 const int kMobileTimeoutMs = 0;
1281 SetUpForTouchAckTimeoutTest(kDesktopTimeoutMs, kMobileTimeoutMs);
1282 ASSERT_TRUE(TouchEventTimeoutEnabled());
1283
1284 // Verify that the touch ack timeout fires upon the delayed ack.
1285 PressTouchPoint(1, 1);
1286 SendTouchEvent();
1287 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1288 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1289 ASSERT_EQ(1U, dispatched_messages.size());
1290 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1291 RunTasksAndWait(base::TimeDelta::FromMilliseconds(kDesktopTimeoutMs + 1));
1292
1293 // The timed-out event should have been ack'ed.
1294 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1295 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1296
1297 // Ack'ing the timed-out event should fire a TouchCancel.
1298 dispatched_messages[0]->ToEvent()->CallCallback(
1299 blink::mojom::InputEventResultState::kConsumed);
1300 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1301 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1302
1303 // The remainder of the touch sequence should be forwarded.
1304 ReleaseTouchPoint(0);
1305 SendTouchEvent();
1306 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1307
1308 PressAndSetTouchActionAuto();
1309 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1310 ASSERT_TRUE(TouchEventTimeoutEnabled());
1311
1312 // A mobile-optimized site should use the mobile timeout. For this test that
1313 // timeout value is 0, which disables the timeout.
1314 input_router()->NotifySiteIsMobileOptimized(true);
1315 EXPECT_FALSE(TouchEventTimeoutEnabled());
1316
1317 input_router()->NotifySiteIsMobileOptimized(false);
1318 EXPECT_TRUE(TouchEventTimeoutEnabled());
1319
1320 // TouchAction::kNone (and no other touch-action) should disable the timeout.
1321 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
1322 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
1323 OnHasTouchEventConsumers(std::move(touch_event_consumers));
1324 PressTouchPoint(1, 1);
1325 SendTouchEvent();
1326 DispatchedMessages touch_press_event2 = GetAndResetDispatchedMessages();
1327 EXPECT_EQ(1U, touch_press_event2.size());
1328 EXPECT_TRUE(TouchEventTimeoutEnabled());
1329 ReleaseTouchPoint(0);
1330 SendTouchEvent();
1331 DispatchedMessages touch_release_event2 = GetAndResetDispatchedMessages();
1332 ASSERT_EQ(1U, touch_release_event2.size());
1333 ASSERT_TRUE(touch_release_event2[0]->ToEvent());
1334 touch_press_event2[0]->ToEvent()->CallCallback(
1335 blink::mojom::InputEventResultState::kConsumed);
1336 touch_release_event2[0]->ToEvent()->CallCallback(
1337 blink::mojom::InputEventResultState::kConsumed);
1338
1339 PressTouchPoint(1, 1);
1340 SendTouchEvent();
1341 input_router_->SetTouchActionFromMain(cc::TouchAction::kNone);
1342 DispatchedMessages touch_press_event3 = GetAndResetDispatchedMessages();
1343 ASSERT_EQ(1u, touch_press_event3.size());
1344 ASSERT_TRUE(touch_press_event3[0]->ToEvent());
1345 CancelTouchTimeout();
1346 EXPECT_FALSE(TouchEventTimeoutEnabled());
1347 ReleaseTouchPoint(0);
1348 SendTouchEvent();
1349 DispatchedMessages touch_release_event3 = GetAndResetDispatchedMessages();
1350 ASSERT_EQ(1u, touch_release_event3.size());
1351 ASSERT_TRUE(touch_release_event3[0]->ToEvent());
1352 touch_press_event3[0]->ToEvent()->CallCallback(
1353 blink::mojom::InputEventResultState::kConsumed);
1354 touch_release_event3[0]->ToEvent()->CallCallback(
1355 blink::mojom::InputEventResultState::kConsumed);
1356
1357 // As the touch-action is reset by a new touch sequence, the timeout behavior
1358 // should be restored.
1359 PressTouchPoint(1, 1);
1360 SendTouchEvent();
1361 ResetTouchAction();
1362 input_router_->SetTouchActionFromMain(cc::TouchAction::kAuto);
1363 EXPECT_TRUE(TouchEventTimeoutEnabled());
1364 }
1365
1366 // Test that a touch sequenced preceded by TouchAction::kNone is not affected by
1367 // the touch timeout.
TEST_F(InputRouterImplTest,TouchAckTimeoutDisabledForTouchSequenceAfterTouchActionNone)1368 TEST_F(InputRouterImplTest,
1369 TouchAckTimeoutDisabledForTouchSequenceAfterTouchActionNone) {
1370 const int kDesktopTimeoutMs = 1;
1371 const int kMobileTimeoutMs = 2;
1372 SetUpForTouchAckTimeoutTest(kDesktopTimeoutMs, kMobileTimeoutMs);
1373 ASSERT_TRUE(TouchEventTimeoutEnabled());
1374 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
1375 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
1376 OnHasTouchEventConsumers(std::move(touch_event_consumers));
1377
1378 // Start a touch sequence.
1379 PressTouchPoint(1, 1);
1380 SendTouchEvent();
1381 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1382 ASSERT_EQ(1U, dispatched_messages.size());
1383 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1384
1385 // TouchAction::kNone should disable the timeout.
1386 CancelTouchTimeout();
1387 dispatched_messages[0]->ToEvent()->CallCallback(
1388 blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(),
1389 blink::mojom::InputEventResultState::kConsumed, nullptr,
1390 blink::mojom::TouchActionOptional::New(cc::TouchAction::kNone));
1391 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1392 EXPECT_FALSE(TouchEventTimeoutEnabled());
1393
1394 MoveTouchPoint(0, 1, 2);
1395 SendTouchEvent();
1396 dispatched_messages = GetAndResetDispatchedMessages();
1397 EXPECT_FALSE(TouchEventTimeoutEnabled());
1398 EXPECT_EQ(1U, dispatched_messages.size());
1399
1400 // Delay the move ack. The timeout should not fire.
1401 RunTasksAndWait(base::TimeDelta::FromMilliseconds(kDesktopTimeoutMs + 1));
1402 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1403 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1404 dispatched_messages[0]->ToEvent()->CallCallback(
1405 blink::mojom::InputEventResultState::kConsumed);
1406 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1407
1408 // End the touch sequence.
1409 ReleaseTouchPoint(0);
1410 SendTouchEvent();
1411 input_router_->SetTouchActionFromMain(cc::TouchAction::kAuto);
1412 dispatched_messages = GetAndResetDispatchedMessages();
1413 EXPECT_EQ(1U, dispatched_messages.size());
1414 dispatched_messages[0]->ToEvent()->CallCallback(
1415 blink::mojom::InputEventResultState::kConsumed);
1416 EXPECT_TRUE(TouchEventTimeoutEnabled());
1417 disposition_handler_->GetAndResetAckCount();
1418 GetAndResetDispatchedMessages();
1419
1420 // Start another touch sequence. This should restore the touch timeout.
1421 PressTouchPoint(1, 1);
1422 SendTouchEvent();
1423 EXPECT_TRUE(TouchEventTimeoutEnabled());
1424 dispatched_messages = GetAndResetDispatchedMessages();
1425 EXPECT_EQ(1U, dispatched_messages.size());
1426 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1427
1428 // Wait for the touch ack timeout to fire.
1429 RunTasksAndWait(base::TimeDelta::FromMilliseconds(kDesktopTimeoutMs + 1));
1430 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1431 }
1432
1433 // Test that TouchActionFilter::ResetTouchAction is called before the
1434 // first touch event for a touch sequence reaches the renderer.
TEST_F(InputRouterImplTest,TouchActionResetBeforeEventReachesRenderer)1435 TEST_F(InputRouterImplTest, TouchActionResetBeforeEventReachesRenderer) {
1436 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
1437 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
1438 OnHasTouchEventConsumers(std::move(touch_event_consumers));
1439
1440 // Sequence 1.
1441 PressTouchPoint(1, 1);
1442 SendTouchEvent();
1443 DispatchedMessages touch_press_event1 = GetAndResetDispatchedMessages();
1444 ASSERT_EQ(1U, touch_press_event1.size());
1445 ASSERT_TRUE(touch_press_event1[0]->ToEvent());
1446 CancelTouchTimeout();
1447 MoveTouchPoint(0, 50, 50);
1448 SendTouchEvent();
1449 DispatchedMessages touch_move_event1 = GetAndResetDispatchedMessages();
1450 ASSERT_EQ(1U, touch_move_event1.size());
1451 ASSERT_TRUE(touch_move_event1[0]->ToEvent());
1452 ReleaseTouchPoint(0);
1453 SendTouchEvent();
1454 DispatchedMessages touch_release_event1 = GetAndResetDispatchedMessages();
1455 ASSERT_EQ(1U, touch_release_event1.size());
1456 ASSERT_TRUE(touch_release_event1[0]->ToEvent());
1457
1458 // Sequence 2.
1459 PressTouchPoint(1, 1);
1460 SendTouchEvent();
1461 DispatchedMessages touch_press_event2 = GetAndResetDispatchedMessages();
1462 ASSERT_EQ(1U, touch_press_event2.size());
1463 ASSERT_TRUE(touch_press_event2[0]->ToEvent());
1464 MoveTouchPoint(0, 50, 50);
1465 SendTouchEvent();
1466 DispatchedMessages touch_move_event2 = GetAndResetDispatchedMessages();
1467 EXPECT_EQ(1U, touch_move_event2.size());
1468 ReleaseTouchPoint(0);
1469 SendTouchEvent();
1470 DispatchedMessages touch_release_event2 = GetAndResetDispatchedMessages();
1471 ASSERT_EQ(1U, touch_release_event2.size());
1472 ASSERT_TRUE(touch_release_event2[0]->ToEvent());
1473
1474 touch_press_event1[0]->ToEvent()->CallCallback(
1475 blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(),
1476 blink::mojom::InputEventResultState::kConsumed, nullptr,
1477 blink::mojom::TouchActionOptional::New(cc::TouchAction::kNone));
1478 touch_move_event1[0]->ToEvent()->CallCallback(
1479 blink::mojom::InputEventResultState::kConsumed);
1480
1481 // Ensure touch action is still none, as the next touch start hasn't been
1482 // acked yet. ScrollBegin and ScrollEnd don't require acks.
1483 SimulateGestureEvent(WebInputEvent::Type::kGestureTapDown,
1484 blink::WebGestureDevice::kTouchscreen);
1485 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1486 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin,
1487 blink::WebGestureDevice::kTouchscreen);
1488 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1489 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollEnd,
1490 blink::WebGestureDevice::kTouchscreen);
1491 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1492
1493 // This allows the next touch sequence to start.
1494 touch_release_event1[0]->ToEvent()->CallCallback(
1495 blink::mojom::InputEventResultState::kConsumed);
1496
1497 // Ensure touch action has been set to auto, as a new touch sequence has
1498 // started.
1499 touch_press_event2[0]->ToEvent()->CallCallback(
1500 blink::mojom::InputEventResultSource::kCompositorThread,
1501 ui::LatencyInfo(), blink::mojom::InputEventResultState::kConsumed,
1502 nullptr, blink::mojom::TouchActionOptional::New(cc::TouchAction::kAuto));
1503 touch_press_event2[0]->ToEvent()->CallCallback(
1504 blink::mojom::InputEventResultState::kConsumed);
1505 touch_move_event2[0]->ToEvent()->CallCallback(
1506 blink::mojom::InputEventResultState::kConsumed);
1507 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1508 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin,
1509 blink::WebGestureDevice::kTouchscreen);
1510 DispatchedMessages gesture_scroll_begin = GetAndResetDispatchedMessages();
1511 EXPECT_EQ(1U, gesture_scroll_begin.size());
1512 gesture_scroll_begin[0]->ToEvent()->CallCallback(
1513 blink::mojom::InputEventResultState::kConsumed);
1514 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollEnd,
1515 blink::WebGestureDevice::kTouchscreen);
1516 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1517 touch_release_event2[0]->ToEvent()->CallCallback(
1518 blink::mojom::InputEventResultState::kConsumed);
1519 }
1520
1521 // Test that TouchActionFilter::ResetTouchAction is called when a new touch
1522 // sequence has no consumer.
TEST_F(InputRouterImplTest,TouchActionResetWhenTouchHasNoConsumer)1523 TEST_F(InputRouterImplTest, TouchActionResetWhenTouchHasNoConsumer) {
1524 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
1525 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
1526 OnHasTouchEventConsumers(std::move(touch_event_consumers));
1527
1528 // Sequence 1.
1529 PressTouchPoint(1, 1);
1530 SendTouchEvent();
1531 DispatchedMessages touch_press_event1 = GetAndResetDispatchedMessages();
1532 ASSERT_EQ(1U, touch_press_event1.size());
1533 ASSERT_TRUE(touch_press_event1[0]->ToEvent());
1534 MoveTouchPoint(0, 50, 50);
1535 SendTouchEvent();
1536 DispatchedMessages touch_move_event1 = GetAndResetDispatchedMessages();
1537 ASSERT_EQ(1U, touch_move_event1.size());
1538 ASSERT_TRUE(touch_move_event1[0]->ToEvent());
1539 CancelTouchTimeout();
1540 touch_press_event1[0]->ToEvent()->CallCallback(
1541 blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(),
1542 blink::mojom::InputEventResultState::kConsumed, nullptr,
1543 blink::mojom::TouchActionOptional::New(cc::TouchAction::kNone));
1544 touch_move_event1[0]->ToEvent()->CallCallback(
1545 blink::mojom::InputEventResultState::kConsumed);
1546
1547 ReleaseTouchPoint(0);
1548 SendTouchEvent();
1549 DispatchedMessages touch_release_event1 = GetAndResetDispatchedMessages();
1550 ASSERT_EQ(1U, touch_release_event1.size());
1551 ASSERT_TRUE(touch_release_event1[0]->ToEvent());
1552
1553 // Sequence 2
1554 PressTouchPoint(1, 1);
1555 SendTouchEvent();
1556 DispatchedMessages touch_press_event2 = GetAndResetDispatchedMessages();
1557 ASSERT_EQ(1U, touch_press_event2.size());
1558 ASSERT_TRUE(touch_press_event2[0]->ToEvent());
1559 MoveTouchPoint(0, 50, 50);
1560 SendTouchEvent();
1561 ReleaseTouchPoint(0);
1562 SendTouchEvent();
1563 EXPECT_EQ(2U, GetAndResetDispatchedMessages().size());
1564
1565 // Ensure we have touch-action:none. ScrollBegin and ScrollEnd don't require
1566 // acks.
1567 SimulateGestureEvent(WebInputEvent::Type::kGestureTapDown,
1568 blink::WebGestureDevice::kTouchscreen);
1569 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1570 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin,
1571 blink::WebGestureDevice::kTouchscreen);
1572 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1573 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollEnd,
1574 blink::WebGestureDevice::kTouchscreen);
1575 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1576
1577 touch_release_event1[0]->ToEvent()->CallCallback(
1578 blink::mojom::InputEventResultState::kConsumed);
1579 touch_press_event2[0]->ToEvent()->CallCallback(
1580 blink::mojom::InputEventResultState::kNoConsumerExists);
1581
1582 PressAndSetTouchActionAuto();
1583 // Ensure touch action has been set to auto, as the touch had no consumer.
1584 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1585 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin,
1586 blink::WebGestureDevice::kTouchscreen);
1587 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1588 ASSERT_EQ(1U, dispatched_messages.size());
1589 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1590 dispatched_messages[0]->ToEvent()->CallCallback(
1591 blink::mojom::InputEventResultState::kConsumed);
1592 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollEnd,
1593 blink::WebGestureDevice::kTouchscreen);
1594 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1595 }
1596
1597 // Test that TouchActionFilter::ResetTouchAction is called when the touch
1598 // handler is removed.
TEST_F(InputRouterImplTest,TouchActionResetWhenTouchHandlerRemoved)1599 TEST_F(InputRouterImplTest, TouchActionResetWhenTouchHandlerRemoved) {
1600 // Touch sequence with touch handler.
1601 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
1602 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
1603 OnHasTouchEventConsumers(std::move(touch_event_consumers));
1604 PressTouchPoint(1, 1);
1605 SendTouchEvent();
1606 MoveTouchPoint(0, 50, 50);
1607 SendTouchEvent();
1608 CancelTouchTimeout();
1609 ReleaseTouchPoint(0);
1610 SendTouchEvent();
1611 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1612 ASSERT_EQ(3U, dispatched_messages.size());
1613 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1614 ASSERT_TRUE(dispatched_messages[1]->ToEvent());
1615 ASSERT_TRUE(dispatched_messages[2]->ToEvent());
1616
1617 // Ensure we have touch-action:none, suppressing scroll events.
1618 dispatched_messages[0]->ToEvent()->CallCallback(
1619 blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(),
1620 blink::mojom::InputEventResultState::kConsumed, nullptr,
1621 blink::mojom::TouchActionOptional::New(cc::TouchAction::kNone));
1622 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1623 dispatched_messages[1]->ToEvent()->CallCallback(
1624 blink::mojom::InputEventResultState::kNotConsumed);
1625 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1626 SimulateGestureEvent(WebInputEvent::Type::kGestureTapDown,
1627 blink::WebGestureDevice::kTouchscreen);
1628 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1629 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin,
1630 blink::WebGestureDevice::kTouchscreen);
1631 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1632
1633 dispatched_messages[2]->ToEvent()->CallCallback(
1634 blink::mojom::InputEventResultState::kNotConsumed);
1635 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollEnd,
1636 blink::WebGestureDevice::kTouchscreen);
1637 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1638
1639 // Sequence without a touch handler. Note that in this case, the view may not
1640 // necessarily forward touches to the router (as no touch handler exists).
1641 touch_event_consumers = blink::mojom::TouchEventConsumers::New(
1642 HasTouchEventHandlers(false), HasHitTestableScrollbar(false));
1643 OnHasTouchEventConsumers(std::move(touch_event_consumers));
1644
1645 // Ensure touch action has been set to auto, as the touch handler has been
1646 // removed.
1647 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin,
1648 blink::WebGestureDevice::kTouchscreen);
1649 dispatched_messages = GetAndResetDispatchedMessages();
1650 ASSERT_EQ(1U, dispatched_messages.size());
1651 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1652 dispatched_messages[0]->ToEvent()->CallCallback(
1653 blink::mojom::InputEventResultState::kConsumed);
1654 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollEnd,
1655 blink::WebGestureDevice::kTouchscreen);
1656 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1657 }
1658
1659 // Tests that async touch-moves are ack'd from the browser side.
TEST_F(InputRouterImplTest,AsyncTouchMoveAckedImmediately)1660 TEST_F(InputRouterImplTest, AsyncTouchMoveAckedImmediately) {
1661 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
1662 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
1663 OnHasTouchEventConsumers(std::move(touch_event_consumers));
1664
1665 PressTouchPoint(1, 1);
1666 SendTouchEvent();
1667 input_router_->SetTouchActionFromMain(cc::TouchAction::kAuto);
1668 EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
1669 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1670 ASSERT_EQ(1U, dispatched_messages.size());
1671 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1672 EXPECT_FALSE(TouchEventQueueEmpty());
1673
1674 // Receive an ACK for the first touch-event.
1675 dispatched_messages[0]->ToEvent()->CallCallback(
1676 blink::mojom::InputEventResultState::kConsumed);
1677 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1678 EXPECT_EQ(WebInputEvent::Type::kTouchStart,
1679 disposition_handler_->ack_event_type());
1680
1681 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollBegin,
1682 blink::WebGestureDevice::kTouchscreen);
1683 dispatched_messages = GetAndResetDispatchedMessages();
1684 ASSERT_EQ(1U, dispatched_messages.size());
1685 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1686 dispatched_messages[0]->ToEvent()->CallCallback(
1687 blink::mojom::InputEventResultState::kConsumed);
1688 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1689 EXPECT_EQ(WebInputEvent::Type::kGestureScrollBegin,
1690 disposition_handler_->ack_event_type());
1691
1692 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
1693 blink::WebGestureDevice::kTouchscreen);
1694 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1695 dispatched_messages = GetAndResetDispatchedMessages();
1696 EXPECT_EQ(2U, dispatched_messages.size());
1697 EXPECT_EQ(WebInputEvent::Type::kTouchScrollStarted,
1698 dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
1699 EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
1700 dispatched_messages[1]->ToEvent()->Event()->Event().GetType());
1701 // Ack the GestureScrollUpdate.
1702 dispatched_messages[1]->ToEvent()->CallCallback(
1703 blink::mojom::InputEventResultState::kConsumed);
1704 EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
1705 disposition_handler_->ack_event_type());
1706 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1707
1708 // Now since we're scrolling send an async move.
1709 MoveTouchPoint(0, 5, 5);
1710 SendTouchEvent();
1711 EXPECT_EQ(WebInputEvent::Type::kTouchMove,
1712 disposition_handler_->ack_event_type());
1713 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1714 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1715
1716 // To catch crbug/1072364 send another scroll which returns kNoConsumerExists
1717 // and ensure we're still async scrolling since we've already started the
1718 // scroll.
1719 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
1720 blink::WebGestureDevice::kTouchscreen);
1721 EXPECT_EQ(0U, disposition_handler_->GetAndResetAckCount());
1722 dispatched_messages = GetAndResetDispatchedMessages();
1723 EXPECT_EQ(1U, dispatched_messages.size());
1724 EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
1725 dispatched_messages[0]->ToEvent()->Event()->Event().GetType());
1726 // Ack the GestureScrollUpdate.
1727 dispatched_messages[0]->ToEvent()->CallCallback(
1728 blink::mojom::InputEventResultState::kNoConsumerExists);
1729 EXPECT_EQ(WebInputEvent::Type::kGestureScrollUpdate,
1730 disposition_handler_->ack_event_type());
1731 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1732
1733 // Now since we're scrolling (even with NoConsumerExists) send an async move.
1734 MoveTouchPoint(0, 10, 5);
1735 SendTouchEvent();
1736 EXPECT_EQ(WebInputEvent::Type::kTouchMove,
1737 disposition_handler_->ack_event_type());
1738 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1739 EXPECT_EQ(1U, GetAndResetDispatchedMessages().size());
1740 }
1741
1742 // Test that the double tap gesture depends on the touch action of the first
1743 // tap.
TEST_F(InputRouterImplTest,DoubleTapGestureDependsOnFirstTap)1744 TEST_F(InputRouterImplTest, DoubleTapGestureDependsOnFirstTap) {
1745 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
1746 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
1747 OnHasTouchEventConsumers(std::move(touch_event_consumers));
1748
1749 // Sequence 1.
1750 PressTouchPoint(1, 1);
1751 SendTouchEvent();
1752 CancelTouchTimeout();
1753 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1754 ASSERT_EQ(1U, dispatched_messages.size());
1755 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1756 dispatched_messages[0]->ToEvent()->CallCallback(
1757 blink::mojom::InputEventResultSource::kMainThread, ui::LatencyInfo(),
1758 blink::mojom::InputEventResultState::kConsumed, nullptr,
1759 blink::mojom::TouchActionOptional::New(cc::TouchAction::kNone));
1760 ReleaseTouchPoint(0);
1761 SendTouchEvent();
1762
1763 // Sequence 2
1764 PressTouchPoint(1, 1);
1765 SendTouchEvent();
1766
1767 // First tap.
1768 SimulateGestureEvent(WebInputEvent::Type::kGestureTapDown,
1769 blink::WebGestureDevice::kTouchscreen);
1770
1771 // The GestureTapUnconfirmed is converted into a tap, as the touch action is
1772 // none.
1773 SimulateGestureEvent(WebInputEvent::Type::kGestureTapUnconfirmed,
1774 blink::WebGestureDevice::kTouchscreen);
1775 dispatched_messages = GetAndResetDispatchedMessages();
1776 ASSERT_EQ(4U, dispatched_messages.size());
1777 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1778 ASSERT_TRUE(dispatched_messages[1]->ToEvent());
1779 ASSERT_TRUE(dispatched_messages[2]->ToEvent());
1780 ASSERT_TRUE(dispatched_messages[3]->ToEvent());
1781 // This test will become invalid if GestureTap stops requiring an ack.
1782 ASSERT_TRUE(ShouldBlockEventStream(
1783 GetEventWithType(WebInputEvent::Type::kGestureTap)));
1784 EXPECT_EQ(3, client_->in_flight_event_count());
1785
1786 dispatched_messages[3]->ToEvent()->CallCallback(
1787 blink::mojom::InputEventResultState::kConsumed);
1788 EXPECT_EQ(2, client_->in_flight_event_count());
1789
1790 // This tap gesture is dropped, since the GestureTapUnconfirmed was turned
1791 // into a tap.
1792 SimulateGestureEvent(WebInputEvent::Type::kGestureTap,
1793 blink::WebGestureDevice::kTouchscreen);
1794 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1795
1796 dispatched_messages[0]->ToEvent()->CallCallback(
1797 blink::mojom::InputEventResultState::kConsumed);
1798 dispatched_messages[1]->ToEvent()->CallCallback(
1799 blink::mojom::InputEventResultState::kNoConsumerExists);
1800
1801 // Second Tap.
1802 EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
1803 SimulateGestureEvent(WebInputEvent::Type::kGestureTapDown,
1804 blink::WebGestureDevice::kTouchscreen);
1805 dispatched_messages = GetAndResetDispatchedMessages();
1806 EXPECT_EQ(1U, dispatched_messages.size());
1807
1808 // Although the touch-action is now auto, the double tap still won't be
1809 // dispatched, because the first tap occurred when the touch-action was none.
1810 SimulateGestureEvent(WebInputEvent::Type::kGestureDoubleTap,
1811 blink::WebGestureDevice::kTouchscreen);
1812 dispatched_messages = GetAndResetDispatchedMessages();
1813 EXPECT_EQ(1U, dispatched_messages.size());
1814 // This test will become invalid if GestureDoubleTap stops requiring an ack.
1815 ASSERT_TRUE(ShouldBlockEventStream(
1816 GetEventWithType(WebInputEvent::Type::kGestureDoubleTap)));
1817 ASSERT_EQ(1, client_->in_flight_event_count());
1818 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1819 dispatched_messages[0]->ToEvent()->CallCallback(
1820 blink::mojom::InputEventResultState::kConsumed);
1821 EXPECT_EQ(0, client_->in_flight_event_count());
1822 }
1823
1824 class TouchpadPinchInputRouterImplTest
1825 : public InputRouterImplTestBase,
1826 public testing::WithParamInterface<bool> {
1827 public:
TouchpadPinchInputRouterImplTest()1828 TouchpadPinchInputRouterImplTest() : async_events_enabled_(GetParam()) {
1829 if (async_events_enabled_) {
1830 scoped_feature_list_.InitAndEnableFeature(
1831 features::kTouchpadAsyncPinchEvents);
1832 } else {
1833 scoped_feature_list_.InitAndDisableFeature(
1834 features::kTouchpadAsyncPinchEvents);
1835 }
1836 }
1837 ~TouchpadPinchInputRouterImplTest() = default;
1838
1839 const bool async_events_enabled_;
1840
1841 private:
1842 base::test::ScopedFeatureList scoped_feature_list_;
1843 DISALLOW_COPY_AND_ASSIGN(TouchpadPinchInputRouterImplTest);
1844 };
1845
1846 INSTANTIATE_TEST_SUITE_P(All,
1847 TouchpadPinchInputRouterImplTest,
1848 ::testing::Bool());
1849
1850 // Test that GesturePinchUpdate is handled specially for trackpad
TEST_P(TouchpadPinchInputRouterImplTest,TouchpadPinchUpdate)1851 TEST_P(TouchpadPinchInputRouterImplTest, TouchpadPinchUpdate) {
1852 // GesturePinchUpdate for trackpad sends synthetic wheel events.
1853 // Note that the Touchscreen case is verified as NOT doing this as
1854 // part of the ShowPressIsInOrder test.
1855
1856 SimulateGestureEvent(WebInputEvent::Type::kGesturePinchBegin,
1857 blink::WebGestureDevice::kTouchpad);
1858 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1859 ASSERT_EQ(WebInputEvent::Type::kGesturePinchBegin,
1860 disposition_handler_->ack_event_type());
1861
1862 SimulateGesturePinchUpdateEvent(1.5f, 20, 25, 0,
1863 blink::WebGestureDevice::kTouchpad);
1864
1865 // Verify we actually sent a special wheel event to the renderer.
1866 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
1867 ASSERT_EQ(1U, dispatched_messages.size());
1868 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1869 const WebInputEvent* input_event =
1870 &dispatched_messages[0]->ToEvent()->Event()->Event();
1871 ASSERT_EQ(WebInputEvent::Type::kMouseWheel, input_event->GetType());
1872 const WebMouseWheelEvent* synthetic_wheel =
1873 static_cast<const WebMouseWheelEvent*>(input_event);
1874 EXPECT_EQ(20, synthetic_wheel->PositionInWidget().x());
1875 EXPECT_EQ(25, synthetic_wheel->PositionInWidget().y());
1876 EXPECT_EQ(20, synthetic_wheel->PositionInScreen().x());
1877 EXPECT_EQ(25, synthetic_wheel->PositionInScreen().y());
1878 EXPECT_TRUE(synthetic_wheel->GetModifiers() &
1879 blink::WebInputEvent::kControlKey);
1880 EXPECT_EQ(blink::WebMouseWheelEvent::kPhaseBegan, synthetic_wheel->phase);
1881 EXPECT_EQ(blink::WebInputEvent::DispatchType::kBlocking,
1882 synthetic_wheel->dispatch_type);
1883
1884 dispatched_messages[0]->ToEvent()->CallCallback(
1885 blink::mojom::InputEventResultState::kNotConsumed);
1886
1887 // Check that the correct unhandled pinch event was received.
1888 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1889 ASSERT_EQ(WebInputEvent::Type::kGesturePinchUpdate,
1890 disposition_handler_->ack_event_type());
1891 EXPECT_EQ(blink::mojom::InputEventResultState::kNotConsumed,
1892 disposition_handler_->ack_state());
1893 EXPECT_EQ(
1894 1.5f,
1895 disposition_handler_->acked_gesture_event().data.pinch_update.scale);
1896 EXPECT_EQ(0, client_->in_flight_event_count());
1897
1898 // Second a second pinch event.
1899 SimulateGesturePinchUpdateEvent(0.3f, 20, 25, 0,
1900 blink::WebGestureDevice::kTouchpad);
1901 dispatched_messages = GetAndResetDispatchedMessages();
1902 ASSERT_EQ(1U, dispatched_messages.size());
1903 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1904 input_event = &dispatched_messages[0]->ToEvent()->Event()->Event();
1905 ASSERT_EQ(WebInputEvent::Type::kMouseWheel, input_event->GetType());
1906 synthetic_wheel = static_cast<const WebMouseWheelEvent*>(input_event);
1907 EXPECT_EQ(blink::WebMouseWheelEvent::kPhaseChanged, synthetic_wheel->phase);
1908 if (async_events_enabled_) {
1909 EXPECT_EQ(blink::WebInputEvent::DispatchType::kEventNonBlocking,
1910 synthetic_wheel->dispatch_type);
1911 } else {
1912 EXPECT_EQ(blink::WebInputEvent::DispatchType::kBlocking,
1913 synthetic_wheel->dispatch_type);
1914 }
1915
1916 if (async_events_enabled_) {
1917 dispatched_messages[0]->ToEvent()->CallCallback(
1918 blink::mojom::InputEventResultState::kIgnored);
1919 } else {
1920 dispatched_messages[0]->ToEvent()->CallCallback(
1921 blink::mojom::InputEventResultState::kNotConsumed);
1922 }
1923
1924 // Check that the correct HANDLED pinch event was received.
1925 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1926 EXPECT_EQ(WebInputEvent::Type::kGesturePinchUpdate,
1927 disposition_handler_->ack_event_type());
1928 if (async_events_enabled_) {
1929 EXPECT_EQ(blink::mojom::InputEventResultState::kIgnored,
1930 disposition_handler_->ack_state());
1931 } else {
1932 EXPECT_EQ(blink::mojom::InputEventResultState::kNotConsumed,
1933 disposition_handler_->ack_state());
1934 }
1935 EXPECT_FLOAT_EQ(
1936 0.3f,
1937 disposition_handler_->acked_gesture_event().data.pinch_update.scale);
1938
1939 SimulateGestureEvent(WebInputEvent::Type::kGesturePinchEnd,
1940 blink::WebGestureDevice::kTouchpad);
1941 dispatched_messages = GetAndResetDispatchedMessages();
1942 ASSERT_EQ(1U, dispatched_messages.size());
1943 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1944 input_event = &dispatched_messages[0]->ToEvent()->Event()->Event();
1945 ASSERT_EQ(WebInputEvent::Type::kMouseWheel, input_event->GetType());
1946 synthetic_wheel = static_cast<const WebMouseWheelEvent*>(input_event);
1947 EXPECT_EQ(blink::WebMouseWheelEvent::kPhaseEnded, synthetic_wheel->phase);
1948 EXPECT_EQ(blink::WebInputEvent::DispatchType::kEventNonBlocking,
1949 synthetic_wheel->dispatch_type);
1950 dispatched_messages[0]->ToEvent()->CallCallback(
1951 blink::mojom::InputEventResultState::kIgnored);
1952
1953 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1954 EXPECT_EQ(WebInputEvent::Type::kGesturePinchEnd,
1955 disposition_handler_->ack_event_type());
1956 EXPECT_EQ(blink::mojom::InputEventResultState::kIgnored,
1957 disposition_handler_->ack_state());
1958
1959 // The first event is blocked. We should send following wheel events as
1960 // blocking events.
1961 SimulateGestureEvent(WebInputEvent::Type::kGesturePinchBegin,
1962 blink::WebGestureDevice::kTouchpad);
1963 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1964 ASSERT_EQ(WebInputEvent::Type::kGesturePinchBegin,
1965 disposition_handler_->ack_event_type());
1966
1967 SimulateGesturePinchUpdateEvent(1.5f, 20, 25, 0,
1968 blink::WebGestureDevice::kTouchpad);
1969
1970 // Verify we actually sent a special wheel event to the renderer.
1971 dispatched_messages = GetAndResetDispatchedMessages();
1972 ASSERT_EQ(1U, dispatched_messages.size());
1973 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
1974 input_event = &dispatched_messages[0]->ToEvent()->Event()->Event();
1975 ASSERT_EQ(WebInputEvent::Type::kMouseWheel, input_event->GetType());
1976 synthetic_wheel = static_cast<const WebMouseWheelEvent*>(input_event);
1977 EXPECT_TRUE(synthetic_wheel->GetModifiers() &
1978 blink::WebInputEvent::kControlKey);
1979 EXPECT_EQ(blink::WebMouseWheelEvent::kPhaseBegan, synthetic_wheel->phase);
1980 EXPECT_EQ(blink::WebInputEvent::DispatchType::kBlocking,
1981 synthetic_wheel->dispatch_type);
1982
1983 dispatched_messages[0]->ToEvent()->CallCallback(
1984 blink::mojom::InputEventResultState::kConsumed);
1985
1986 // Check that the correct handled pinch event was received.
1987 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
1988 ASSERT_EQ(WebInputEvent::Type::kGesturePinchUpdate,
1989 disposition_handler_->ack_event_type());
1990 EXPECT_EQ(blink::mojom::InputEventResultState::kConsumed,
1991 disposition_handler_->ack_state());
1992 EXPECT_EQ(
1993 1.5f,
1994 disposition_handler_->acked_gesture_event().data.pinch_update.scale);
1995 EXPECT_EQ(0, client_->in_flight_event_count());
1996
1997 // Second a second pinch event.
1998 SimulateGesturePinchUpdateEvent(0.3f, 20, 25, 0,
1999 blink::WebGestureDevice::kTouchpad);
2000 dispatched_messages = GetAndResetDispatchedMessages();
2001 ASSERT_EQ(1U, dispatched_messages.size());
2002 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
2003 input_event = &dispatched_messages[0]->ToEvent()->Event()->Event();
2004 ASSERT_EQ(WebInputEvent::Type::kMouseWheel, input_event->GetType());
2005 synthetic_wheel = static_cast<const WebMouseWheelEvent*>(input_event);
2006 EXPECT_EQ(blink::WebMouseWheelEvent::kPhaseChanged, synthetic_wheel->phase);
2007 EXPECT_EQ(blink::WebInputEvent::DispatchType::kBlocking,
2008 synthetic_wheel->dispatch_type);
2009
2010 dispatched_messages[0]->ToEvent()->CallCallback(
2011 blink::mojom::InputEventResultState::kConsumed);
2012
2013 // Check that the correct HANDLED pinch event was received.
2014 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
2015 EXPECT_EQ(WebInputEvent::Type::kGesturePinchUpdate,
2016 disposition_handler_->ack_event_type());
2017 EXPECT_EQ(blink::mojom::InputEventResultState::kConsumed,
2018 disposition_handler_->ack_state());
2019 EXPECT_FLOAT_EQ(
2020 0.3f,
2021 disposition_handler_->acked_gesture_event().data.pinch_update.scale);
2022 }
2023
2024 // Test proper handling of touchpad Gesture{Pinch,Scroll}Update sequences.
TEST_F(InputRouterImplTest,TouchpadPinchAndScrollUpdate)2025 TEST_F(InputRouterImplTest, TouchpadPinchAndScrollUpdate) {
2026 // All gesture events should be sent immediately.
2027 SimulateGestureScrollUpdateEvent(1.5f, 0.f, 0,
2028 blink::WebGestureDevice::kTouchpad);
2029 SimulateGestureEvent(WebInputEvent::Type::kGestureScrollUpdate,
2030 blink::WebGestureDevice::kTouchpad);
2031 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
2032 ASSERT_EQ(2U, dispatched_messages.size());
2033 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
2034 ASSERT_TRUE(dispatched_messages[1]->ToEvent());
2035 EXPECT_EQ(2, client_->in_flight_event_count());
2036
2037 // Subsequent scroll and pinch events will also be sent immediately.
2038 SimulateTouchpadGesturePinchEventWithoutWheel(
2039 WebInputEvent::Type::kGesturePinchUpdate, 1.5f, 20, 25, 0);
2040 DispatchedMessages temp_dispatched_messages = GetAndResetDispatchedMessages();
2041 ASSERT_EQ(1U, temp_dispatched_messages.size());
2042 ASSERT_TRUE(temp_dispatched_messages[0]->ToEvent());
2043 dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
2044 EXPECT_EQ(2, client_->in_flight_event_count());
2045
2046 SimulateGestureScrollUpdateEvent(1.5f, 1.5f, 0,
2047 blink::WebGestureDevice::kTouchpad);
2048 temp_dispatched_messages = GetAndResetDispatchedMessages();
2049 ASSERT_EQ(1U, temp_dispatched_messages.size());
2050 ASSERT_TRUE(temp_dispatched_messages[0]->ToEvent());
2051 dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
2052 EXPECT_EQ(3, client_->in_flight_event_count());
2053
2054 SimulateTouchpadGesturePinchEventWithoutWheel(
2055 WebInputEvent::Type::kGesturePinchUpdate, 1.5f, 20, 25, 0);
2056 temp_dispatched_messages = GetAndResetDispatchedMessages();
2057 ASSERT_EQ(1U, temp_dispatched_messages.size());
2058 ASSERT_TRUE(temp_dispatched_messages[0]->ToEvent());
2059 dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
2060 EXPECT_EQ(3, client_->in_flight_event_count());
2061
2062 SimulateGestureScrollUpdateEvent(0.f, 1.5f, 0,
2063 blink::WebGestureDevice::kTouchpad);
2064 temp_dispatched_messages = GetAndResetDispatchedMessages();
2065 ASSERT_EQ(1U, temp_dispatched_messages.size());
2066 ASSERT_TRUE(temp_dispatched_messages[0]->ToEvent());
2067 dispatched_messages.emplace_back(std::move(temp_dispatched_messages.at(0)));
2068 EXPECT_EQ(4, client_->in_flight_event_count());
2069
2070 // Ack'ing events should decrease in-flight event count.
2071 dispatched_messages[0]->ToEvent()->CallCallback(
2072 blink::mojom::InputEventResultState::kConsumed);
2073 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
2074 EXPECT_EQ(3, client_->in_flight_event_count());
2075
2076 // Ack the second scroll.
2077 dispatched_messages[1]->ToEvent()->CallCallback(
2078 blink::mojom::InputEventResultState::kConsumed);
2079 EXPECT_FALSE(dispatched_messages[2]->ToEvent()->HasCallback());
2080 EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
2081 EXPECT_EQ(2, client_->in_flight_event_count());
2082
2083 // Ack the scroll event.
2084 dispatched_messages[3]->ToEvent()->CallCallback(
2085 blink::mojom::InputEventResultState::kConsumed);
2086 EXPECT_FALSE(dispatched_messages[4]->ToEvent()->HasCallback());
2087 EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
2088 EXPECT_EQ(1, client_->in_flight_event_count());
2089
2090 // Ack the scroll event.
2091 dispatched_messages[5]->ToEvent()->CallCallback(
2092 blink::mojom::InputEventResultState::kConsumed);
2093 EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
2094 EXPECT_EQ(0, client_->in_flight_event_count());
2095 }
2096
2097 // Test proper routing of overscroll notifications received either from
2098 // event acks or from |DidOverscroll| IPC messages.
TEST_F(InputRouterImplTest,OverscrollDispatch)2099 TEST_F(InputRouterImplTest, OverscrollDispatch) {
2100 blink::mojom::DidOverscrollParams overscroll;
2101 overscroll.accumulated_overscroll = gfx::Vector2dF(-14, 14);
2102 overscroll.latest_overscroll_delta = gfx::Vector2dF(-7, 0);
2103 overscroll.current_fling_velocity = gfx::Vector2dF(-1, 0);
2104
2105 input_router_->DidOverscroll(overscroll.Clone());
2106 DidOverscrollParams client_overscroll = client_->GetAndResetOverscroll();
2107 EXPECT_EQ(overscroll.accumulated_overscroll,
2108 client_overscroll.accumulated_overscroll);
2109 EXPECT_EQ(overscroll.latest_overscroll_delta,
2110 client_overscroll.latest_overscroll_delta);
2111 // With browser side fling, the fling velocity doesn't come from overscroll
2112 // params of the renderer, instead the input router sets the
2113 // params.current_fling_velocity based on the velocity received from the fling
2114 // controller.
2115 EXPECT_EQ(gfx::Vector2dF(), client_overscroll.current_fling_velocity);
2116
2117 blink::mojom::DidOverscrollParams wheel_overscroll;
2118 wheel_overscroll.accumulated_overscroll = gfx::Vector2dF(7, -7);
2119 wheel_overscroll.latest_overscroll_delta = gfx::Vector2dF(3, 0);
2120 wheel_overscroll.current_fling_velocity = gfx::Vector2dF(1, 0);
2121
2122 SimulateWheelEvent(0, 0, 3, 0, 0, false, WebMouseWheelEvent::kPhaseBegan);
2123 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
2124 ASSERT_EQ(1U, dispatched_messages.size());
2125 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
2126
2127 dispatched_messages[0]->ToEvent()->CallCallback(
2128 blink::mojom::InputEventResultSource::kCompositorThread,
2129 ui::LatencyInfo(), blink::mojom::InputEventResultState::kNotConsumed,
2130 wheel_overscroll.Clone(), nullptr);
2131
2132 client_overscroll = client_->GetAndResetOverscroll();
2133 EXPECT_EQ(wheel_overscroll.accumulated_overscroll,
2134 client_overscroll.accumulated_overscroll);
2135 EXPECT_EQ(wheel_overscroll.latest_overscroll_delta,
2136 client_overscroll.latest_overscroll_delta);
2137 // With browser side fling, the fling velocity doesn't come from overscroll
2138 // params of the renderer, instead the input router sets the
2139 // params.current_fling_velocity based on the velocity received from the fling
2140 // controller.
2141 EXPECT_EQ(gfx::Vector2dF(), client_overscroll.current_fling_velocity);
2142 }
2143
2144 // Tests that touch event stream validation passes when events are filtered
2145 // out. See https://crbug.com/581231 for details.
TEST_F(InputRouterImplTest,TouchValidationPassesWithFilteredInputEvents)2146 TEST_F(InputRouterImplTest, TouchValidationPassesWithFilteredInputEvents) {
2147 // Touch sequence with touch handler.
2148 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
2149 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
2150 OnHasTouchEventConsumers(std::move(touch_event_consumers));
2151 PressTouchPoint(1, 1);
2152 SendTouchEvent();
2153 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
2154 ASSERT_EQ(1U, dispatched_messages.size());
2155 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
2156 dispatched_messages[0]->ToEvent()->CallCallback(
2157 blink::mojom::InputEventResultState::kNoConsumerExists);
2158
2159 PressTouchPoint(1, 1);
2160 SendTouchEvent();
2161 dispatched_messages = GetAndResetDispatchedMessages();
2162 ASSERT_EQ(1U, dispatched_messages.size());
2163 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
2164 dispatched_messages[0]->ToEvent()->CallCallback(
2165 blink::mojom::InputEventResultState::kNoConsumerExists);
2166
2167 // This event will not be filtered out even though no consumer exists.
2168 ReleaseTouchPoint(1);
2169 SendTouchEvent();
2170 dispatched_messages = GetAndResetDispatchedMessages();
2171 EXPECT_EQ(1U, dispatched_messages.size());
2172
2173 // If the validator didn't see the filtered out release event, it will crash
2174 // now, upon seeing a press for a touch which it believes to be still pressed.
2175 PressTouchPoint(1, 1);
2176 SendTouchEvent();
2177 dispatched_messages = GetAndResetDispatchedMessages();
2178 ASSERT_EQ(1U, dispatched_messages.size());
2179 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
2180 dispatched_messages[0]->ToEvent()->CallCallback(
2181 blink::mojom::InputEventResultState::kNoConsumerExists);
2182 }
2183
TEST_F(InputRouterImplTest,TouchActionInCallback)2184 TEST_F(InputRouterImplTest, TouchActionInCallback) {
2185 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
2186 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
2187 OnHasTouchEventConsumers(std::move(touch_event_consumers));
2188
2189 // Send a touchstart
2190 PressTouchPoint(1, 1);
2191 SendTouchEvent();
2192 DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
2193 ASSERT_EQ(1U, dispatched_messages.size());
2194 ASSERT_TRUE(dispatched_messages[0]->ToEvent());
2195 base::Optional<cc::TouchAction> expected_touch_action = cc::TouchAction::kPan;
2196 dispatched_messages[0]->ToEvent()->CallCallback(
2197 blink::mojom::InputEventResultSource::kCompositorThread,
2198 ui::LatencyInfo(), blink::mojom::InputEventResultState::kConsumed,
2199 nullptr, blink::mojom::TouchActionOptional::New(cc::TouchAction::kPan));
2200 ASSERT_EQ(1U, disposition_handler_->GetAndResetAckCount());
2201 base::Optional<cc::TouchAction> allowed_touch_action = AllowedTouchAction();
2202 cc::TouchAction compositor_allowed_touch_action =
2203 CompositorAllowedTouchAction();
2204 EXPECT_FALSE(allowed_touch_action.has_value());
2205 EXPECT_EQ(expected_touch_action.value(), compositor_allowed_touch_action);
2206 }
2207
2208 // TODO(crbug.com/953547): enable this when the bug is fixed.
TEST_F(InputRouterImplTest,DISABLED_TimeoutMonitorStopWithMainThreadTouchAction)2209 TEST_F(InputRouterImplTest,
2210 DISABLED_TimeoutMonitorStopWithMainThreadTouchAction) {
2211 SetUpForTouchAckTimeoutTest(1, 1);
2212 auto touch_event_consumers = blink::mojom::TouchEventConsumers::New(
2213 HasTouchEventHandlers(true), HasHitTestableScrollbar(false));
2214 OnHasTouchEventConsumers(std::move(touch_event_consumers));
2215 StopTimeoutMonitorTest();
2216 }
2217
2218 namespace {
2219
2220 class InputRouterImplScaleEventTest : public InputRouterImplTestBase {
2221 public:
InputRouterImplScaleEventTest()2222 InputRouterImplScaleEventTest() {}
2223
SetUp()2224 void SetUp() override {
2225 InputRouterImplTestBase::SetUp();
2226 input_router_->SetDeviceScaleFactor(2.f);
2227 }
2228
2229 template <typename T>
GetSentWebInputEvent()2230 const T* GetSentWebInputEvent() {
2231 EXPECT_EQ(1u, dispatched_messages_.size());
2232
2233 return static_cast<const T*>(
2234 &dispatched_messages_[0]->ToEvent()->Event()->Event());
2235 }
2236
2237 template <typename T>
GetFilterWebInputEvent() const2238 const T* GetFilterWebInputEvent() const {
2239 return static_cast<const T*>(client_->last_filter_event());
2240 }
2241
UpdateDispatchedMessages()2242 void UpdateDispatchedMessages() {
2243 dispatched_messages_ = GetAndResetDispatchedMessages();
2244 }
2245
2246 protected:
2247 DispatchedMessages dispatched_messages_;
2248
2249 private:
2250 DISALLOW_COPY_AND_ASSIGN(InputRouterImplScaleEventTest);
2251 };
2252
2253 class InputRouterImplScaleMouseEventTest
2254 : public InputRouterImplScaleEventTest {
2255 public:
InputRouterImplScaleMouseEventTest()2256 InputRouterImplScaleMouseEventTest() {}
2257
RunMouseEventTest(const std::string & name,WebInputEvent::Type type)2258 void RunMouseEventTest(const std::string& name, WebInputEvent::Type type) {
2259 SCOPED_TRACE(name);
2260 SimulateMouseEvent(type, 10, 10);
2261 UpdateDispatchedMessages();
2262 const WebMouseEvent* sent_event = GetSentWebInputEvent<WebMouseEvent>();
2263 EXPECT_EQ(20, sent_event->PositionInWidget().x());
2264 EXPECT_EQ(20, sent_event->PositionInWidget().y());
2265
2266 const WebMouseEvent* filter_event = GetFilterWebInputEvent<WebMouseEvent>();
2267 EXPECT_EQ(10, filter_event->PositionInWidget().x());
2268 EXPECT_EQ(10, filter_event->PositionInWidget().y());
2269 }
2270
2271 private:
2272 DISALLOW_COPY_AND_ASSIGN(InputRouterImplScaleMouseEventTest);
2273 };
2274
2275 } // namespace
2276
TEST_F(InputRouterImplScaleMouseEventTest,ScaleMouseEventTest)2277 TEST_F(InputRouterImplScaleMouseEventTest, ScaleMouseEventTest) {
2278 RunMouseEventTest("Enter", WebInputEvent::Type::kMouseEnter);
2279 RunMouseEventTest("Down", WebInputEvent::Type::kMouseDown);
2280 RunMouseEventTest("Move", WebInputEvent::Type::kMouseMove);
2281 RunMouseEventTest("Up", WebInputEvent::Type::kMouseUp);
2282 }
2283
TEST_F(InputRouterImplScaleEventTest,ScaleMouseWheelEventTest)2284 TEST_F(InputRouterImplScaleEventTest, ScaleMouseWheelEventTest) {
2285 SimulateWheelEvent(5, 5, 10, 10, 0, false, WebMouseWheelEvent::kPhaseBegan);
2286 UpdateDispatchedMessages();
2287
2288 const WebMouseWheelEvent* sent_event =
2289 GetSentWebInputEvent<WebMouseWheelEvent>();
2290 EXPECT_EQ(10, sent_event->PositionInWidget().x());
2291 EXPECT_EQ(10, sent_event->PositionInWidget().y());
2292 EXPECT_EQ(20, sent_event->delta_x);
2293 EXPECT_EQ(20, sent_event->delta_y);
2294 EXPECT_EQ(2, sent_event->wheel_ticks_x);
2295 EXPECT_EQ(2, sent_event->wheel_ticks_y);
2296
2297 const WebMouseWheelEvent* filter_event =
2298 GetFilterWebInputEvent<WebMouseWheelEvent>();
2299 EXPECT_EQ(5, filter_event->PositionInWidget().x());
2300 EXPECT_EQ(5, filter_event->PositionInWidget().y());
2301 EXPECT_EQ(10, filter_event->delta_x);
2302 EXPECT_EQ(10, filter_event->delta_y);
2303 EXPECT_EQ(1, filter_event->wheel_ticks_x);
2304 EXPECT_EQ(1, filter_event->wheel_ticks_y);
2305
2306 EXPECT_EQ(sent_event->acceleration_ratio_x,
2307 filter_event->acceleration_ratio_x);
2308 EXPECT_EQ(sent_event->acceleration_ratio_y,
2309 filter_event->acceleration_ratio_y);
2310 }
2311
2312 namespace {
2313
2314 class InputRouterImplScaleTouchEventTest
2315 : public InputRouterImplScaleEventTest {
2316 public:
InputRouterImplScaleTouchEventTest()2317 InputRouterImplScaleTouchEventTest() {}
2318
2319 // Test tests if two finger touch event at (10, 20) and (100, 200) are
2320 // properly scaled. The touch event must be generated ans flushed into
2321 // the message sink prior to this method.
RunTouchEventTest(const std::string & name,WebTouchPoint::State state)2322 void RunTouchEventTest(const std::string& name, WebTouchPoint::State state) {
2323 SCOPED_TRACE(name);
2324 const WebTouchEvent* sent_event = GetSentWebInputEvent<WebTouchEvent>();
2325 ASSERT_EQ(2u, sent_event->touches_length);
2326 EXPECT_EQ(state, sent_event->touches[0].state);
2327 EXPECT_EQ(20, sent_event->touches[0].PositionInWidget().x());
2328 EXPECT_EQ(40, sent_event->touches[0].PositionInWidget().y());
2329 EXPECT_EQ(10, sent_event->touches[0].PositionInScreen().x());
2330 EXPECT_EQ(20, sent_event->touches[0].PositionInScreen().y());
2331 EXPECT_EQ(2 * radius_x_, sent_event->touches[0].radius_x);
2332 EXPECT_EQ(2 * radius_x_, sent_event->touches[0].radius_y);
2333
2334 EXPECT_EQ(200, sent_event->touches[1].PositionInWidget().x());
2335 EXPECT_EQ(400, sent_event->touches[1].PositionInWidget().y());
2336 EXPECT_EQ(100, sent_event->touches[1].PositionInScreen().x());
2337 EXPECT_EQ(200, sent_event->touches[1].PositionInScreen().y());
2338 EXPECT_EQ(2 * radius_x_, sent_event->touches[1].radius_x);
2339 EXPECT_EQ(2 * radius_x_, sent_event->touches[1].radius_y);
2340
2341 const WebTouchEvent* filter_event = GetFilterWebInputEvent<WebTouchEvent>();
2342 ASSERT_EQ(2u, filter_event->touches_length);
2343 EXPECT_EQ(10, filter_event->touches[0].PositionInWidget().x());
2344 EXPECT_EQ(20, filter_event->touches[0].PositionInWidget().y());
2345 EXPECT_EQ(10, filter_event->touches[0].PositionInScreen().x());
2346 EXPECT_EQ(20, filter_event->touches[0].PositionInScreen().y());
2347 EXPECT_EQ(radius_x_, filter_event->touches[0].radius_x);
2348 EXPECT_EQ(radius_x_, filter_event->touches[0].radius_y);
2349
2350 EXPECT_EQ(100, filter_event->touches[1].PositionInWidget().x());
2351 EXPECT_EQ(200, filter_event->touches[1].PositionInWidget().y());
2352 EXPECT_EQ(100, filter_event->touches[1].PositionInScreen().x());
2353 EXPECT_EQ(200, filter_event->touches[1].PositionInScreen().y());
2354 EXPECT_EQ(radius_x_, filter_event->touches[1].radius_x);
2355 EXPECT_EQ(radius_x_, filter_event->touches[1].radius_y);
2356 }
2357
FlushTouchEvent(WebInputEvent::Type type)2358 void FlushTouchEvent(WebInputEvent::Type type) {
2359 SendTouchEvent();
2360 UpdateDispatchedMessages();
2361 ASSERT_EQ(1u, dispatched_messages_.size());
2362 ASSERT_TRUE(dispatched_messages_[0]->ToEvent());
2363 dispatched_messages_[0]->ToEvent()->CallCallback(
2364 blink::mojom::InputEventResultState::kConsumed);
2365 ASSERT_TRUE(TouchEventQueueEmpty());
2366 }
2367
ReleaseTouchPointAndAck(int index)2368 void ReleaseTouchPointAndAck(int index) {
2369 ReleaseTouchPoint(index);
2370 SendTouchEvent();
2371 UpdateDispatchedMessages();
2372 ASSERT_EQ(1u, dispatched_messages_.size());
2373 ASSERT_TRUE(dispatched_messages_[0]->ToEvent());
2374 dispatched_messages_[0]->ToEvent()->CallCallback(
2375 blink::mojom::InputEventResultState::kConsumed);
2376 }
2377
2378 private:
2379 DISALLOW_COPY_AND_ASSIGN(InputRouterImplScaleTouchEventTest);
2380 };
2381
2382 } // namespace
2383
TEST_F(InputRouterImplScaleTouchEventTest,ScaleTouchEventTest)2384 TEST_F(InputRouterImplScaleTouchEventTest, ScaleTouchEventTest) {
2385 ResetTouchAction();
2386 // Press
2387 PressTouchPoint(10, 20);
2388 PressTouchPoint(100, 200);
2389 FlushTouchEvent(WebInputEvent::Type::kTouchStart);
2390
2391 RunTouchEventTest("Press", WebTouchPoint::State::kStatePressed);
2392 ReleaseTouchPointAndAck(1);
2393 ReleaseTouchPointAndAck(0);
2394
2395 // Move
2396 PressTouchPoint(0, 0);
2397 PressTouchPoint(0, 0);
2398 FlushTouchEvent(WebInputEvent::Type::kTouchStart);
2399
2400 MoveTouchPoint(0, 10, 20);
2401 MoveTouchPoint(1, 100, 200);
2402 FlushTouchEvent(WebInputEvent::Type::kTouchMove);
2403 RunTouchEventTest("Move", WebTouchPoint::State::kStateMoved);
2404 ReleaseTouchPointAndAck(1);
2405 ReleaseTouchPointAndAck(0);
2406
2407 // Release
2408 PressTouchPoint(10, 20);
2409 PressTouchPoint(100, 200);
2410 FlushTouchEvent(WebInputEvent::Type::kTouchMove);
2411
2412 ReleaseTouchPoint(0);
2413 ReleaseTouchPoint(1);
2414 FlushTouchEvent(WebInputEvent::Type::kTouchEnd);
2415 RunTouchEventTest("Release", WebTouchPoint::State::kStateReleased);
2416
2417 // Cancel
2418 PressTouchPoint(10, 20);
2419 PressTouchPoint(100, 200);
2420 FlushTouchEvent(WebInputEvent::Type::kTouchStart);
2421
2422 CancelTouchPoint(0);
2423 CancelTouchPoint(1);
2424 FlushTouchEvent(WebInputEvent::Type::kTouchCancel);
2425 RunTouchEventTest("Cancel", WebTouchPoint::State::kStateCancelled);
2426 }
2427
2428 namespace {
2429
2430 class InputRouterImplScaleGestureEventTest
2431 : public InputRouterImplScaleEventTest {
2432 public:
InputRouterImplScaleGestureEventTest()2433 InputRouterImplScaleGestureEventTest() {}
2434
GetContactSize(const WebGestureEvent & event)2435 base::Optional<gfx::SizeF> GetContactSize(const WebGestureEvent& event) {
2436 switch (event.GetType()) {
2437 case WebInputEvent::Type::kGestureTapDown:
2438 return gfx::SizeF(event.data.tap_down.width,
2439 event.data.tap_down.height);
2440 case WebInputEvent::Type::kGestureShowPress:
2441 return gfx::SizeF(event.data.show_press.width,
2442 event.data.show_press.height);
2443 case WebInputEvent::Type::kGestureTap:
2444 case WebInputEvent::Type::kGestureTapUnconfirmed:
2445 case WebInputEvent::Type::kGestureDoubleTap:
2446 return gfx::SizeF(event.data.tap.width, event.data.tap.height);
2447 case WebInputEvent::Type::kGestureLongPress:
2448 case WebInputEvent::Type::kGestureLongTap:
2449 return gfx::SizeF(event.data.long_press.width,
2450 event.data.long_press.height);
2451 case WebInputEvent::Type::kGestureTwoFingerTap:
2452 return gfx::SizeF(event.data.two_finger_tap.first_finger_width,
2453 event.data.two_finger_tap.first_finger_height);
2454 default:
2455 return base::nullopt;
2456 }
2457 }
2458
SetContactSize(WebGestureEvent & event,const gfx::SizeF & size)2459 void SetContactSize(WebGestureEvent& event, const gfx::SizeF& size) {
2460 switch (event.GetType()) {
2461 case WebInputEvent::Type::kGestureTapDown:
2462 event.data.tap_down.width = size.width();
2463 event.data.tap_down.height = size.height();
2464 break;
2465 case WebInputEvent::Type::kGestureShowPress:
2466 event.data.show_press.width = size.width();
2467 event.data.show_press.height = size.height();
2468 break;
2469 case WebInputEvent::Type::kGestureTap:
2470 case WebInputEvent::Type::kGestureTapUnconfirmed:
2471 case WebInputEvent::Type::kGestureDoubleTap:
2472 event.data.tap.width = size.width();
2473 event.data.tap.height = size.height();
2474 break;
2475 case WebInputEvent::Type::kGestureLongPress:
2476 case WebInputEvent::Type::kGestureLongTap:
2477 event.data.long_press.width = size.width();
2478 event.data.long_press.height = size.height();
2479 break;
2480 case WebInputEvent::Type::kGestureTwoFingerTap:
2481 event.data.two_finger_tap.first_finger_width = size.width();
2482 event.data.two_finger_tap.first_finger_height = size.height();
2483 break;
2484 default:
2485 break;
2486 }
2487 }
2488
BuildGestureEvent(WebInputEvent::Type type,const gfx::PointF & point,const gfx::SizeF & contact_size)2489 WebGestureEvent BuildGestureEvent(WebInputEvent::Type type,
2490 const gfx::PointF& point,
2491 const gfx::SizeF& contact_size) {
2492 WebGestureEvent event = SyntheticWebGestureEventBuilder::Build(
2493 type, blink::WebGestureDevice::kTouchscreen);
2494 event.SetPositionInWidget(point);
2495 event.SetPositionInScreen(point);
2496 SetContactSize(event, contact_size);
2497 return event;
2498 }
2499
SendGestureSequence(const std::vector<WebInputEvent::Type> & gesture_types)2500 void SendGestureSequence(
2501 const std::vector<WebInputEvent::Type>& gesture_types) {
2502 const gfx::PointF orig(10, 20), scaled(20, 40);
2503 const gfx::SizeF contact_size(30, 40), contact_size_scaled(60, 80);
2504
2505 for (WebInputEvent::Type type : gesture_types) {
2506 SCOPED_TRACE(WebInputEvent::GetName(type));
2507
2508 WebGestureEvent event = BuildGestureEvent(type, orig, contact_size);
2509 SimulateGestureEvent(event);
2510 FlushGestureEvents({type});
2511
2512 const WebGestureEvent* sent_event =
2513 GetSentWebInputEvent<WebGestureEvent>();
2514 TestLocationInSentEvent(sent_event, orig, scaled, contact_size_scaled);
2515
2516 const WebGestureEvent* filter_event =
2517 GetFilterWebInputEvent<WebGestureEvent>();
2518 TestLocationInFilterEvent(filter_event, orig, contact_size);
2519 }
2520 }
2521
FlushGestureEvents(const std::vector<WebInputEvent::Type> & expected_types)2522 void FlushGestureEvents(
2523 const std::vector<WebInputEvent::Type>& expected_types) {
2524 UpdateDispatchedMessages();
2525 ASSERT_EQ(expected_types.size(), dispatched_messages_.size());
2526 for (size_t i = 0; i < dispatched_messages_.size(); i++) {
2527 ASSERT_TRUE(dispatched_messages_[i]->ToEvent());
2528 ASSERT_EQ(expected_types[i],
2529 dispatched_messages_[i]->ToEvent()->Event()->Event().GetType());
2530 dispatched_messages_[i]->ToEvent()->CallCallback(
2531 blink::mojom::InputEventResultState::kConsumed);
2532 }
2533 }
2534
TestLocationInSentEvent(const WebGestureEvent * sent_event,const gfx::PointF & orig,const gfx::PointF & scaled,const base::Optional<gfx::SizeF> & contact_size_scaled)2535 void TestLocationInSentEvent(
2536 const WebGestureEvent* sent_event,
2537 const gfx::PointF& orig,
2538 const gfx::PointF& scaled,
2539 const base::Optional<gfx::SizeF>& contact_size_scaled) {
2540 EXPECT_FLOAT_EQ(scaled.x(), sent_event->PositionInWidget().x());
2541 EXPECT_FLOAT_EQ(scaled.y(), sent_event->PositionInWidget().y());
2542 EXPECT_FLOAT_EQ(orig.x(), sent_event->PositionInScreen().x());
2543 EXPECT_FLOAT_EQ(orig.y(), sent_event->PositionInScreen().y());
2544
2545 base::Optional<gfx::SizeF> event_contact_size = GetContactSize(*sent_event);
2546 if (event_contact_size && contact_size_scaled) {
2547 EXPECT_FLOAT_EQ(contact_size_scaled->width(),
2548 event_contact_size->width());
2549 EXPECT_FLOAT_EQ(contact_size_scaled->height(),
2550 event_contact_size->height());
2551 }
2552 }
2553
TestLocationInFilterEvent(const WebGestureEvent * filter_event,const gfx::PointF & orig,const base::Optional<gfx::SizeF> & contact_size)2554 void TestLocationInFilterEvent(
2555 const WebGestureEvent* filter_event,
2556 const gfx::PointF& orig,
2557 const base::Optional<gfx::SizeF>& contact_size) {
2558 EXPECT_FLOAT_EQ(orig.x(), filter_event->PositionInWidget().x());
2559 EXPECT_FLOAT_EQ(orig.y(), filter_event->PositionInWidget().y());
2560 EXPECT_FLOAT_EQ(orig.x(), filter_event->PositionInScreen().x());
2561 EXPECT_FLOAT_EQ(orig.y(), filter_event->PositionInScreen().y());
2562
2563 base::Optional<gfx::SizeF> event_contact_size =
2564 GetContactSize(*filter_event);
2565 if (event_contact_size && contact_size) {
2566 EXPECT_FLOAT_EQ(contact_size->width(), event_contact_size->width());
2567 EXPECT_FLOAT_EQ(contact_size->height(), event_contact_size->height());
2568 }
2569 }
2570
2571 private:
2572 DISALLOW_COPY_AND_ASSIGN(InputRouterImplScaleGestureEventTest);
2573 };
2574
2575 } // namespace
2576
TEST_F(InputRouterImplScaleGestureEventTest,GestureScroll)2577 TEST_F(InputRouterImplScaleGestureEventTest, GestureScroll) {
2578 const gfx::Vector2dF delta(10.f, 20.f), delta_scaled(20.f, 40.f);
2579
2580 PressAndSetTouchActionAuto();
2581
2582 SendGestureSequence({WebInputEvent::Type::kGestureTapDown,
2583 WebInputEvent::Type::kGestureTapCancel});
2584
2585 {
2586 SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildScrollBegin(
2587 delta.x(), delta.y(), blink::WebGestureDevice::kTouchscreen));
2588 FlushGestureEvents({WebInputEvent::Type::kGestureScrollBegin});
2589
2590 const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
2591 EXPECT_FLOAT_EQ(delta_scaled.x(),
2592 sent_event->data.scroll_begin.delta_x_hint);
2593 EXPECT_FLOAT_EQ(delta_scaled.y(),
2594 sent_event->data.scroll_begin.delta_y_hint);
2595
2596 const WebGestureEvent* filter_event =
2597 GetFilterWebInputEvent<WebGestureEvent>();
2598 EXPECT_FLOAT_EQ(delta.x(), filter_event->data.scroll_begin.delta_x_hint);
2599 EXPECT_FLOAT_EQ(delta.y(), filter_event->data.scroll_begin.delta_y_hint);
2600 }
2601
2602 {
2603 SimulateGestureScrollUpdateEvent(delta.x(), delta.y(), 0,
2604 blink::WebGestureDevice::kTouchscreen);
2605 FlushGestureEvents({WebInputEvent::Type::kTouchScrollStarted,
2606 WebInputEvent::Type::kGestureScrollUpdate});
2607 // Erase TouchScrollStarted so we can inspect the GestureScrollUpdate.
2608 dispatched_messages_.erase(dispatched_messages_.begin());
2609
2610 const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
2611 EXPECT_FLOAT_EQ(delta_scaled.x(), sent_event->data.scroll_update.delta_x);
2612 EXPECT_FLOAT_EQ(delta_scaled.y(), sent_event->data.scroll_update.delta_y);
2613
2614 const WebGestureEvent* filter_event =
2615 GetFilterWebInputEvent<WebGestureEvent>();
2616 EXPECT_FLOAT_EQ(delta.x(), filter_event->data.scroll_update.delta_x);
2617 EXPECT_FLOAT_EQ(delta.y(), filter_event->data.scroll_update.delta_y);
2618 }
2619
2620 SendGestureSequence({WebInputEvent::Type::kGestureScrollEnd});
2621 }
2622
TEST_F(InputRouterImplScaleGestureEventTest,GesturePinch)2623 TEST_F(InputRouterImplScaleGestureEventTest, GesturePinch) {
2624 const gfx::PointF anchor(10.f, 20.f), anchor_scaled(20.f, 40.f);
2625 const float scale_change(1.5f);
2626
2627 PressAndSetTouchActionAuto();
2628
2629 SendGestureSequence({WebInputEvent::Type::kGestureTapDown,
2630 WebInputEvent::Type::kGestureTapCancel});
2631
2632 SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildScrollBegin(
2633 0.f, 0.f, blink::WebGestureDevice::kTouchscreen));
2634 FlushGestureEvents({WebInputEvent::Type::kGestureScrollBegin});
2635
2636 SendGestureSequence({WebInputEvent::Type::kGesturePinchBegin});
2637
2638 SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildPinchUpdate(
2639 scale_change, anchor.x(), anchor.y(), 0,
2640 blink::WebGestureDevice::kTouchscreen));
2641
2642 FlushGestureEvents({WebInputEvent::Type::kGesturePinchUpdate});
2643 const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
2644 TestLocationInSentEvent(sent_event, anchor, anchor_scaled, base::nullopt);
2645 EXPECT_FLOAT_EQ(scale_change, sent_event->data.pinch_update.scale);
2646
2647 const WebGestureEvent* filter_event =
2648 GetFilterWebInputEvent<WebGestureEvent>();
2649 TestLocationInFilterEvent(filter_event, anchor, base::nullopt);
2650 EXPECT_FLOAT_EQ(scale_change, filter_event->data.pinch_update.scale);
2651
2652 SendGestureSequence({WebInputEvent::Type::kGesturePinchEnd,
2653 WebInputEvent::Type::kGestureScrollEnd});
2654 }
2655
TEST_F(InputRouterImplScaleGestureEventTest,GestureTap)2656 TEST_F(InputRouterImplScaleGestureEventTest, GestureTap) {
2657 SendGestureSequence({WebInputEvent::Type::kGestureTapDown,
2658 WebInputEvent::Type::kGestureShowPress,
2659 WebInputEvent::Type::kGestureTap});
2660 }
2661
TEST_F(InputRouterImplScaleGestureEventTest,GestureDoubleTap)2662 TEST_F(InputRouterImplScaleGestureEventTest, GestureDoubleTap) {
2663 SendGestureSequence({WebInputEvent::Type::kGestureTapDown,
2664 WebInputEvent::Type::kGestureTapUnconfirmed,
2665 WebInputEvent::Type::kGestureTapCancel,
2666 WebInputEvent::Type::kGestureTapDown,
2667 WebInputEvent::Type::kGestureTapCancel,
2668 WebInputEvent::Type::kGestureDoubleTap});
2669 }
2670
TEST_F(InputRouterImplScaleGestureEventTest,GestureLongPress)2671 TEST_F(InputRouterImplScaleGestureEventTest, GestureLongPress) {
2672 SendGestureSequence({WebInputEvent::Type::kGestureTapDown,
2673 WebInputEvent::Type::kGestureShowPress,
2674 WebInputEvent::Type::kGestureLongPress,
2675 WebInputEvent::Type::kGestureTapCancel,
2676 WebInputEvent::Type::kGestureLongTap});
2677 }
2678
TEST_F(InputRouterImplScaleGestureEventTest,GestureTwoFingerTap)2679 TEST_F(InputRouterImplScaleGestureEventTest, GestureTwoFingerTap) {
2680 SendGestureSequence({WebInputEvent::Type::kGestureTapDown,
2681 WebInputEvent::Type::kGestureTapCancel,
2682 WebInputEvent::Type::kGestureTwoFingerTap});
2683 }
2684
2685 } // namespace content
2686