Ignore non-active fullscreen windows for shelf state.
[chromium-blink-merge.git] / content / browser / renderer_host / input / input_router_impl_unittest.cc
blobba94e8057bdae3fbe4ba6471c95c1e8683accb5e
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "base/command_line.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "content/browser/renderer_host/input/gesture_event_filter.h"
10 #include "content/browser/renderer_host/input/input_router_client.h"
11 #include "content/browser/renderer_host/input/input_router_impl.h"
12 #include "content/browser/renderer_host/input/mock_input_ack_handler.h"
13 #include "content/browser/renderer_host/input/mock_input_router_client.h"
14 #include "content/common/content_constants_internal.h"
15 #include "content/common/edit_command.h"
16 #include "content/common/input/synthetic_web_input_event_builders.h"
17 #include "content/common/input/web_input_event_traits.h"
18 #include "content/common/input_messages.h"
19 #include "content/common/view_messages.h"
20 #include "content/public/common/content_switches.h"
21 #include "content/public/test/mock_render_process_host.h"
22 #include "content/public/test/test_browser_context.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/events/keycodes/keyboard_codes.h"
26 #if defined(OS_WIN) || defined(USE_AURA)
27 #include "content/browser/renderer_host/ui_events_helper.h"
28 #include "ui/events/event.h"
29 #endif
31 using base::TimeDelta;
32 using blink::WebGestureEvent;
33 using blink::WebKeyboardEvent;
34 using blink::WebInputEvent;
35 using blink::WebMouseEvent;
36 using blink::WebMouseWheelEvent;
37 using blink::WebTouchEvent;
38 using blink::WebTouchPoint;
40 namespace content {
42 namespace {
44 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
45 PickleIterator iter(message);
46 const char* data;
47 int data_length;
48 if (!message.ReadData(&iter, &data, &data_length))
49 return NULL;
50 return reinterpret_cast<const WebInputEvent*>(data);
53 bool GetIsShortcutFromHandleInputEventMessage(const IPC::Message* msg) {
54 InputMsg_HandleInputEvent::Schema::Param param;
55 InputMsg_HandleInputEvent::Read(msg, &param);
56 return param.c;
59 template<typename MSG_T, typename ARG_T1>
60 void ExpectIPCMessageWithArg1(const IPC::Message* msg, const ARG_T1& arg1) {
61 ASSERT_EQ(MSG_T::ID, msg->type());
62 typename MSG_T::Schema::Param param;
63 ASSERT_TRUE(MSG_T::Read(msg, &param));
64 EXPECT_EQ(arg1, param.a);
67 template<typename MSG_T, typename ARG_T1, typename ARG_T2>
68 void ExpectIPCMessageWithArg2(const IPC::Message* msg,
69 const ARG_T1& arg1,
70 const ARG_T2& arg2) {
71 ASSERT_EQ(MSG_T::ID, msg->type());
72 typename MSG_T::Schema::Param param;
73 ASSERT_TRUE(MSG_T::Read(msg, &param));
74 EXPECT_EQ(arg1, param.a);
75 EXPECT_EQ(arg2, param.b);
78 #if defined(OS_WIN) || defined(USE_AURA)
79 bool TouchEventsAreEquivalent(const ui::TouchEvent& first,
80 const ui::TouchEvent& second) {
81 if (first.type() != second.type())
82 return false;
83 if (first.location() != second.location())
84 return false;
85 if (first.touch_id() != second.touch_id())
86 return false;
87 if (second.time_stamp().InSeconds() != first.time_stamp().InSeconds())
88 return false;
89 return true;
92 bool EventListIsSubset(const ScopedVector<ui::TouchEvent>& subset,
93 const ScopedVector<ui::TouchEvent>& set) {
94 if (subset.size() > set.size())
95 return false;
96 for (size_t i = 0; i < subset.size(); ++i) {
97 const ui::TouchEvent* first = subset[i];
98 const ui::TouchEvent* second = set[i];
99 bool equivalent = TouchEventsAreEquivalent(*first, *second);
100 if (!equivalent)
101 return false;
104 return true;
106 #endif // defined(OS_WIN) || defined(USE_AURA)
108 } // namespace
110 class InputRouterImplTest : public testing::Test {
111 public:
112 InputRouterImplTest() {}
113 virtual ~InputRouterImplTest() {}
115 protected:
116 // testing::Test
117 virtual void SetUp() OVERRIDE {
118 browser_context_.reset(new TestBrowserContext());
119 process_.reset(new MockRenderProcessHost(browser_context_.get()));
120 client_.reset(new MockInputRouterClient());
121 ack_handler_.reset(new MockInputAckHandler());
122 input_router_.reset(new InputRouterImpl(
123 process_.get(), client_.get(), ack_handler_.get(), MSG_ROUTING_NONE));
124 input_router_->gesture_event_filter_->set_debounce_enabled_for_testing(
125 false);
126 client_->set_input_router(input_router());
127 ack_handler_->set_input_router(input_router());
130 virtual void TearDown() OVERRIDE {
131 // Process all pending tasks to avoid leaks.
132 base::MessageLoop::current()->RunUntilIdle();
134 input_router_.reset();
135 client_.reset();
136 process_.reset();
137 browser_context_.reset();
140 void SimulateKeyboardEvent(WebInputEvent::Type type, bool is_shortcut) {
141 WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
142 NativeWebKeyboardEvent native_event;
143 memcpy(&native_event, &event, sizeof(event));
144 input_router_->SendKeyboardEvent(
145 native_event,
146 ui::LatencyInfo(),
147 is_shortcut);
150 void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
151 input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
152 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
153 ui::LatencyInfo()));
156 void SimulateMouseMove(int x, int y, int modifiers) {
157 input_router_->SendMouseEvent(MouseEventWithLatencyInfo(
158 SyntheticWebMouseEventBuilder::Build(
159 WebInputEvent::MouseMove, x, y, modifiers),
160 ui::LatencyInfo()));
163 void SimulateWheelEventWithPhase(WebMouseWheelEvent::Phase phase) {
164 input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
165 SyntheticWebMouseWheelEventBuilder::Build(phase), ui::LatencyInfo()));
168 void SimulateGestureEvent(const WebGestureEvent& gesture) {
169 input_router_->SendGestureEvent(
170 GestureEventWithLatencyInfo(gesture, ui::LatencyInfo()));
173 void SimulateGestureEvent(WebInputEvent::Type type,
174 WebGestureEvent::SourceDevice sourceDevice) {
175 SimulateGestureEvent(
176 SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
179 void SimulateGestureScrollUpdateEvent(float dX, float dY, int modifiers) {
180 SimulateGestureEvent(
181 SyntheticWebGestureEventBuilder::BuildScrollUpdate(dX, dY, modifiers));
184 void SimulateGesturePinchUpdateEvent(float scale,
185 float anchorX,
186 float anchorY,
187 int modifiers) {
188 SimulateGestureEvent(
189 SyntheticWebGestureEventBuilder::BuildPinchUpdate(scale,
190 anchorX,
191 anchorY,
192 modifiers));
195 void SimulateGestureFlingStartEvent(
196 float velocityX,
197 float velocityY,
198 WebGestureEvent::SourceDevice sourceDevice) {
199 SimulateGestureEvent(
200 SyntheticWebGestureEventBuilder::BuildFling(velocityX,
201 velocityY,
202 sourceDevice));
205 void SimulateTouchEvent(WebInputEvent::Type type) {
206 touch_event_.ResetPoints();
207 int index = PressTouchPoint(0, 0);
208 switch (type) {
209 case WebInputEvent::TouchStart:
210 // Already handled by |PressTouchPoint()|.
211 break;
212 case WebInputEvent::TouchMove:
213 MoveTouchPoint(index, 5, 5);
214 break;
215 case WebInputEvent::TouchEnd:
216 ReleaseTouchPoint(index);
217 break;
218 case WebInputEvent::TouchCancel:
219 CancelTouchPoint(index);
220 break;
221 default:
222 FAIL() << "Invalid touch event type.";
223 break;
225 SendTouchEvent();
228 void SetTouchTimestamp(base::TimeDelta timestamp) {
229 touch_event_.SetTimestamp(timestamp);
232 void SendTouchEvent() {
233 input_router_->SendTouchEvent(
234 TouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo()));
235 touch_event_.ResetPoints();
238 int PressTouchPoint(int x, int y) {
239 return touch_event_.PressPoint(x, y);
242 void MoveTouchPoint(int index, int x, int y) {
243 touch_event_.MovePoint(index, x, y);
246 void ReleaseTouchPoint(int index) {
247 touch_event_.ReleasePoint(index);
250 void CancelTouchPoint(int index) {
251 touch_event_.CancelPoint(index);
253 void SendInputEventACK(blink::WebInputEvent::Type type,
254 InputEventAckState ack_result) {
255 scoped_ptr<IPC::Message> response(
256 new InputHostMsg_HandleInputEvent_ACK(0, type, ack_result,
257 ui::LatencyInfo()));
258 input_router_->OnMessageReceived(*response);
261 InputRouterImpl* input_router() const {
262 return input_router_.get();
265 bool TouchEventQueueEmpty() const {
266 return input_router()->touch_event_queue_->empty();
269 bool TouchEventTimeoutEnabled() const {
270 return input_router()->touch_event_queue_->ack_timeout_enabled();
273 size_t GetSentMessageCountAndResetSink() {
274 size_t count = process_->sink().message_count();
275 process_->sink().ClearMessages();
276 return count;
279 scoped_ptr<MockRenderProcessHost> process_;
280 scoped_ptr<MockInputRouterClient> client_;
281 scoped_ptr<MockInputAckHandler> ack_handler_;
282 scoped_ptr<InputRouterImpl> input_router_;
284 private:
285 base::MessageLoopForUI message_loop_;
286 SyntheticWebTouchEvent touch_event_;
288 scoped_ptr<TestBrowserContext> browser_context_;
291 TEST_F(InputRouterImplTest, CoalescesRangeSelection) {
292 input_router_->SendInput(scoped_ptr<IPC::Message>(
293 new InputMsg_SelectRange(0, gfx::Point(1, 2), gfx::Point(3, 4))));
294 ExpectIPCMessageWithArg2<InputMsg_SelectRange>(
295 process_->sink().GetMessageAt(0),
296 gfx::Point(1, 2),
297 gfx::Point(3, 4));
298 EXPECT_EQ(1u, GetSentMessageCountAndResetSink());
300 // Send two more messages without acking.
301 input_router_->SendInput(scoped_ptr<IPC::Message>(
302 new InputMsg_SelectRange(0, gfx::Point(5, 6), gfx::Point(7, 8))));
303 EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
305 input_router_->SendInput(scoped_ptr<IPC::Message>(
306 new InputMsg_SelectRange(0, gfx::Point(9, 10), gfx::Point(11, 12))));
307 EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
309 // Now ack the first message.
311 scoped_ptr<IPC::Message> response(new ViewHostMsg_SelectRange_ACK(0));
312 input_router_->OnMessageReceived(*response);
315 // Verify that the two messages are coalesced into one message.
316 ExpectIPCMessageWithArg2<InputMsg_SelectRange>(
317 process_->sink().GetMessageAt(0),
318 gfx::Point(9, 10),
319 gfx::Point(11, 12));
320 EXPECT_EQ(1u, GetSentMessageCountAndResetSink());
322 // Acking the coalesced msg should not send any more msg.
324 scoped_ptr<IPC::Message> response(new ViewHostMsg_SelectRange_ACK(0));
325 input_router_->OnMessageReceived(*response);
327 EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
330 TEST_F(InputRouterImplTest, CoalescesCaretMove) {
331 input_router_->SendInput(
332 scoped_ptr<IPC::Message>(new InputMsg_MoveCaret(0, gfx::Point(1, 2))));
333 ExpectIPCMessageWithArg1<InputMsg_MoveCaret>(
334 process_->sink().GetMessageAt(0), gfx::Point(1, 2));
335 EXPECT_EQ(1u, GetSentMessageCountAndResetSink());
337 // Send two more messages without acking.
338 input_router_->SendInput(
339 scoped_ptr<IPC::Message>(new InputMsg_MoveCaret(0, gfx::Point(5, 6))));
340 EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
342 input_router_->SendInput(
343 scoped_ptr<IPC::Message>(new InputMsg_MoveCaret(0, gfx::Point(9, 10))));
344 EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
346 // Now ack the first message.
348 scoped_ptr<IPC::Message> response(new ViewHostMsg_MoveCaret_ACK(0));
349 input_router_->OnMessageReceived(*response);
352 // Verify that the two messages are coalesced into one message.
353 ExpectIPCMessageWithArg1<InputMsg_MoveCaret>(
354 process_->sink().GetMessageAt(0), gfx::Point(9, 10));
355 EXPECT_EQ(1u, GetSentMessageCountAndResetSink());
357 // Acking the coalesced msg should not send any more msg.
359 scoped_ptr<IPC::Message> response(new ViewHostMsg_MoveCaret_ACK(0));
360 input_router_->OnMessageReceived(*response);
362 EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
365 TEST_F(InputRouterImplTest, HandledInputEvent) {
366 client_->set_filter_state(INPUT_EVENT_ACK_STATE_CONSUMED);
368 // Simulate a keyboard event.
369 SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
371 // Make sure no input event is sent to the renderer.
372 EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
374 // OnKeyboardEventAck should be triggered without actual ack.
375 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
377 // As the event was acked already, keyboard event queue should be
378 // empty.
379 ASSERT_EQ(NULL, input_router_->GetLastKeyboardEvent());
382 TEST_F(InputRouterImplTest, ClientCanceledKeyboardEvent) {
383 client_->set_filter_state(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
385 // Simulate a keyboard event that has no consumer.
386 SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
388 // Make sure no input event is sent to the renderer.
389 EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
390 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
393 // Simulate a keyboard event that should be dropped.
394 client_->set_filter_state(INPUT_EVENT_ACK_STATE_UNKNOWN);
395 SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
397 // Make sure no input event is sent to the renderer, and no ack is sent.
398 EXPECT_EQ(0u, GetSentMessageCountAndResetSink());
399 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
402 TEST_F(InputRouterImplTest, ShortcutKeyboardEvent) {
403 SimulateKeyboardEvent(WebInputEvent::RawKeyDown, true);
404 EXPECT_TRUE(GetIsShortcutFromHandleInputEventMessage(
405 process_->sink().GetMessageAt(0)));
407 process_->sink().ClearMessages();
409 SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
410 EXPECT_FALSE(GetIsShortcutFromHandleInputEventMessage(
411 process_->sink().GetMessageAt(0)));
414 TEST_F(InputRouterImplTest, NoncorrespondingKeyEvents) {
415 SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
417 SendInputEventACK(WebInputEvent::KeyUp,
418 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
419 EXPECT_TRUE(ack_handler_->unexpected_event_ack_called());
422 // Tests ported from RenderWidgetHostTest --------------------------------------
424 TEST_F(InputRouterImplTest, HandleKeyEventsWeSent) {
425 // Simulate a keyboard event.
426 SimulateKeyboardEvent(WebInputEvent::RawKeyDown, false);
427 ASSERT_TRUE(input_router_->GetLastKeyboardEvent());
428 EXPECT_EQ(WebInputEvent::RawKeyDown,
429 input_router_->GetLastKeyboardEvent()->type);
431 // Make sure we sent the input event to the renderer.
432 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
433 InputMsg_HandleInputEvent::ID));
434 process_->sink().ClearMessages();
436 // Send the simulated response from the renderer back.
437 SendInputEventACK(WebInputEvent::RawKeyDown,
438 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
439 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
440 EXPECT_EQ(WebInputEvent::RawKeyDown,
441 ack_handler_->acked_keyboard_event().type);
444 TEST_F(InputRouterImplTest, IgnoreKeyEventsWeDidntSend) {
445 // Send a simulated, unrequested key response. We should ignore this.
446 SendInputEventACK(WebInputEvent::RawKeyDown,
447 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
449 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
452 TEST_F(InputRouterImplTest, CoalescesWheelEvents) {
453 // Simulate wheel events.
454 SimulateWheelEvent(0, -5, 0, false); // sent directly
455 SimulateWheelEvent(0, -10, 0, false); // enqueued
456 SimulateWheelEvent(8, -6, 0, false); // coalesced into previous event
457 SimulateWheelEvent(9, -7, 1, false); // enqueued, different modifiers
459 // Check that only the first event was sent.
460 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
461 InputMsg_HandleInputEvent::ID));
462 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
464 // Check that the ACK sends the second message immediately.
465 SendInputEventACK(WebInputEvent::MouseWheel,
466 INPUT_EVENT_ACK_STATE_CONSUMED);
467 // The coalesced events can queue up a delayed ack
468 // so that additional input events can be processed before
469 // we turn off coalescing.
470 base::MessageLoop::current()->RunUntilIdle();
471 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
472 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
473 InputMsg_HandleInputEvent::ID));
474 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
476 // One more time.
477 SendInputEventACK(WebInputEvent::MouseWheel,
478 INPUT_EVENT_ACK_STATE_CONSUMED);
479 base::MessageLoop::current()->RunUntilIdle();
480 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
481 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
482 InputMsg_HandleInputEvent::ID));
483 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
485 // After the final ack, the queue should be empty.
486 SendInputEventACK(WebInputEvent::MouseWheel,
487 INPUT_EVENT_ACK_STATE_CONSUMED);
488 base::MessageLoop::current()->RunUntilIdle();
489 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
490 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
493 TEST_F(InputRouterImplTest,
494 CoalescesWheelEventsQueuedPhaseEndIsNotDropped) {
495 // Send an initial gesture begin and ACK it.
496 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
497 WebGestureEvent::Touchpad);
498 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
499 SendInputEventACK(WebInputEvent::GestureScrollBegin,
500 INPUT_EVENT_ACK_STATE_CONSUMED);
501 base::MessageLoop::current()->RunUntilIdle();
503 // Send a wheel event, should get sent directly.
504 SimulateWheelEvent(0, -5, 0, false);
505 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
507 // Send a wheel phase end event before an ACK is received for the previous
508 // wheel event, which should get queued.
509 SimulateWheelEventWithPhase(WebMouseWheelEvent::PhaseEnded);
510 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
512 // A gesture event should now result in the queued phase ended event being
513 // transmitted before it.
514 SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
515 WebGestureEvent::Touchpad);
517 // Verify the events that were sent.
518 const WebInputEvent* input_event =
519 GetInputEventFromMessage(*process_->sink().GetMessageAt(0));
520 ASSERT_EQ(WebInputEvent::MouseWheel, input_event->type);
521 const WebMouseWheelEvent* wheel_event =
522 static_cast<const WebMouseWheelEvent*>(input_event);
523 ASSERT_EQ(WebMouseWheelEvent::PhaseEnded, wheel_event->phase);
525 input_event = GetInputEventFromMessage(*process_->sink().GetMessageAt(1));
526 EXPECT_EQ(WebInputEvent::GestureScrollEnd, input_event->type);
528 ASSERT_EQ(2U, GetSentMessageCountAndResetSink());
531 // Tests that touch-events are queued properly.
532 TEST_F(InputRouterImplTest, TouchEventQueue) {
533 PressTouchPoint(1, 1);
534 SendTouchEvent();
535 EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
536 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
537 EXPECT_FALSE(TouchEventQueueEmpty());
539 // The second touch should not be sent since one is already in queue.
540 MoveTouchPoint(0, 5, 5);
541 SendTouchEvent();
542 EXPECT_FALSE(client_->GetAndResetFilterEventCalled());
543 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
544 EXPECT_FALSE(TouchEventQueueEmpty());
546 // Receive an ACK for the first touch-event.
547 SendInputEventACK(WebInputEvent::TouchStart,
548 INPUT_EVENT_ACK_STATE_CONSUMED);
549 EXPECT_FALSE(TouchEventQueueEmpty());
550 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
551 EXPECT_EQ(WebInputEvent::TouchStart,
552 ack_handler_->acked_touch_event().event.type);
553 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
555 SendInputEventACK(WebInputEvent::TouchMove,
556 INPUT_EVENT_ACK_STATE_CONSUMED);
557 EXPECT_TRUE(TouchEventQueueEmpty());
558 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
559 EXPECT_EQ(WebInputEvent::TouchMove,
560 ack_handler_->acked_touch_event().event.type);
561 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
564 // Tests that the touch-queue is emptied if a page stops listening for touch
565 // events.
566 TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
567 input_router_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
568 EXPECT_TRUE(client_->has_touch_handler());
569 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
570 EXPECT_TRUE(TouchEventQueueEmpty());
572 EXPECT_TRUE(input_router_->ShouldForwardTouchEvent());
574 // Send a touch-press event.
575 PressTouchPoint(1, 1);
576 SendTouchEvent();
577 EXPECT_FALSE(TouchEventQueueEmpty());
578 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
580 // The page stops listening for touch-events. The touch-event queue should now
581 // be emptied, but none of the queued touch-events should be sent to the
582 // renderer.
583 input_router_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
584 EXPECT_FALSE(client_->has_touch_handler());
585 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
586 EXPECT_TRUE(TouchEventQueueEmpty());
587 EXPECT_FALSE(input_router_->ShouldForwardTouchEvent());
590 #if defined(OS_WIN) || defined(USE_AURA)
591 // Tests that the acked events have correct state. (ui::Events are used only on
592 // windows and aura)
593 TEST_F(InputRouterImplTest, AckedTouchEventState) {
594 input_router_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
595 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
596 EXPECT_TRUE(TouchEventQueueEmpty());
597 EXPECT_TRUE(input_router_->ShouldForwardTouchEvent());
599 // Send a bunch of events, and make sure the ACKed events are correct.
600 ScopedVector<ui::TouchEvent> expected_events;
602 // Use a custom timestamp for all the events to test that the acked events
603 // have the same timestamp;
604 base::TimeDelta timestamp = base::Time::NowFromSystemTime() - base::Time();
605 timestamp -= base::TimeDelta::FromSeconds(600);
607 // Press the first finger.
608 PressTouchPoint(1, 1);
609 SetTouchTimestamp(timestamp);
610 SendTouchEvent();
611 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
612 expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
613 gfx::Point(1, 1), 0, timestamp));
615 // Move the finger.
616 timestamp += base::TimeDelta::FromSeconds(10);
617 MoveTouchPoint(0, 5, 5);
618 SetTouchTimestamp(timestamp);
619 SendTouchEvent();
620 EXPECT_FALSE(TouchEventQueueEmpty());
621 expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_MOVED,
622 gfx::Point(5, 5), 0, timestamp));
624 // Now press a second finger.
625 timestamp += base::TimeDelta::FromSeconds(10);
626 PressTouchPoint(2, 2);
627 SetTouchTimestamp(timestamp);
628 SendTouchEvent();
629 EXPECT_FALSE(TouchEventQueueEmpty());
630 expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
631 gfx::Point(2, 2), 1, timestamp));
633 // Move both fingers.
634 timestamp += base::TimeDelta::FromSeconds(10);
635 MoveTouchPoint(0, 10, 10);
636 MoveTouchPoint(1, 20, 20);
637 SetTouchTimestamp(timestamp);
638 SendTouchEvent();
639 EXPECT_FALSE(TouchEventQueueEmpty());
640 expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_MOVED,
641 gfx::Point(10, 10), 0, timestamp));
642 expected_events.push_back(new ui::TouchEvent(ui::ET_TOUCH_MOVED,
643 gfx::Point(20, 20), 1, timestamp));
645 // Receive the ACKs and make sure the generated events from the acked events
646 // are correct.
647 WebInputEvent::Type acks[] = { WebInputEvent::TouchStart,
648 WebInputEvent::TouchMove,
649 WebInputEvent::TouchStart,
650 WebInputEvent::TouchMove };
652 TouchEventCoordinateSystem coordinate_system = LOCAL_COORDINATES;
653 #if !defined(OS_WIN)
654 coordinate_system = SCREEN_COORDINATES;
655 #endif
656 for (size_t i = 0; i < arraysize(acks); ++i) {
657 SendInputEventACK(acks[i],
658 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
659 EXPECT_EQ(acks[i], ack_handler_->acked_touch_event().event.type);
660 ScopedVector<ui::TouchEvent> acked;
662 MakeUITouchEventsFromWebTouchEvents(
663 ack_handler_->acked_touch_event(), &acked, coordinate_system);
664 bool success = EventListIsSubset(acked, expected_events);
665 EXPECT_TRUE(success) << "Failed on step: " << i;
666 if (!success)
667 break;
668 expected_events.erase(expected_events.begin(),
669 expected_events.begin() + acked.size());
672 EXPECT_TRUE(TouchEventQueueEmpty());
673 EXPECT_EQ(0U, expected_events.size());
675 #endif // defined(OS_WIN) || defined(USE_AURA)
677 TEST_F(InputRouterImplTest, UnhandledWheelEvent) {
678 // Simulate wheel events.
679 SimulateWheelEvent(0, -5, 0, false); // sent directly
680 SimulateWheelEvent(0, -10, 0, false); // enqueued
682 // Check that only the first event was sent.
683 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
684 InputMsg_HandleInputEvent::ID));
685 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
687 // Indicate that the wheel event was unhandled.
688 SendInputEventACK(WebInputEvent::MouseWheel,
689 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
691 // Check that the correct unhandled wheel event was received.
692 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
693 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_handler_->ack_state());
694 EXPECT_EQ(ack_handler_->acked_wheel_event().deltaY, -5);
696 // Check that the second event was sent.
697 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
698 InputMsg_HandleInputEvent::ID));
699 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
701 // Check that the correct unhandled wheel event was received.
702 EXPECT_EQ(ack_handler_->acked_wheel_event().deltaY, -5);
705 TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
706 int start_type = static_cast<int>(WebInputEvent::TouchStart);
707 int end_type = static_cast<int>(WebInputEvent::TouchCancel);
708 for (int i = start_type; i <= end_type; ++i) {
709 WebInputEvent::Type type = static_cast<WebInputEvent::Type>(i);
710 if (!WebInputEventTraits::IgnoresAckDisposition(type))
711 continue;
713 // The TouchEventQueue requires an initial TouchStart for it to begin
714 // forwarding other touch event types.
715 if (type != WebInputEvent::TouchStart) {
716 SimulateTouchEvent(WebInputEvent::TouchStart);
717 SendInputEventACK(WebInputEvent::TouchStart,
718 INPUT_EVENT_ACK_STATE_CONSUMED);
719 ASSERT_EQ(1U, GetSentMessageCountAndResetSink());
720 ASSERT_EQ(1U, ack_handler_->GetAndResetAckCount());
723 SimulateTouchEvent(type);
724 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
725 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
726 SendInputEventACK(type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
727 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
728 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
732 TEST_F(InputRouterImplTest, GestureTypesIgnoringAck) {
733 int start_type = static_cast<int>(WebInputEvent::GestureScrollBegin);
734 int end_type = static_cast<int>(WebInputEvent::GesturePinchUpdate);
735 for (int i = start_type; i <= end_type; ++i) {
736 WebInputEvent::Type type = static_cast<WebInputEvent::Type>(i);
737 if (!WebInputEventTraits::IgnoresAckDisposition(type))
738 continue;
740 SimulateGestureEvent(type, WebGestureEvent::Touchscreen);
741 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
742 EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
743 SendInputEventACK(type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
744 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
745 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
749 // Test that GestureShowPress, GestureTapDown and GestureTapCancel events don't
750 // wait for ACKs.
751 TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
752 // Interleave a few events that do and do not ignore acks, ensuring that
753 // ack-ignoring events aren't dispatched until all prior events which observe
754 // their ack disposition have been dispatched.
755 SimulateGestureEvent(WebInputEvent::GesturePinchUpdate,
756 WebGestureEvent::Touchscreen);
757 ASSERT_EQ(1U, GetSentMessageCountAndResetSink());
758 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
760 SimulateGestureEvent(WebInputEvent::GestureTapDown,
761 WebGestureEvent::Touchscreen);
762 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
763 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
765 SimulateGestureEvent(WebInputEvent::GesturePinchUpdate,
766 WebGestureEvent::Touchscreen);
767 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
768 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
770 SimulateGestureEvent(WebInputEvent::GestureShowPress,
771 WebGestureEvent::Touchscreen);
772 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
773 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
775 SimulateGestureEvent(WebInputEvent::GesturePinchUpdate,
776 WebGestureEvent::Touchscreen);
777 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
778 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
780 SimulateGestureEvent(WebInputEvent::GestureTapCancel,
781 WebGestureEvent::Touchscreen);
782 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
783 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
785 // Now ack each event. Ack-ignoring events should not be dispatched until all
786 // prior events which observe ack disposition have been fired, at which
787 // point they should be sent immediately.
788 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
789 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
790 EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
791 EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
793 // For events which ignore ack disposition, non-synthetic acks are ignored.
794 SendInputEventACK(WebInputEvent::GestureTapDown,
795 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
796 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
797 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
799 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
800 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
801 EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
802 EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
804 // For events which ignore ack disposition, non-synthetic acks are ignored.
805 SendInputEventACK(WebInputEvent::GestureShowPress,
806 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
807 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
808 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
810 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
811 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
812 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
813 EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount());
815 // For events which ignore ack disposition, non-synthetic acks are ignored.
816 SendInputEventACK(WebInputEvent::GestureTapCancel,
817 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
818 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
819 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
822 // Test that GestureShowPress events don't get out of order due to
823 // ignoring their acks.
824 TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
825 SimulateGestureEvent(WebInputEvent::GestureTap,
826 WebGestureEvent::Touchscreen);
828 EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
829 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
831 SimulateGestureEvent(WebInputEvent::GestureShowPress,
832 WebGestureEvent::Touchscreen);
834 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
835 // The ShowPress, though it ignores ack, is still stuck in the queue
836 // behind the Tap which requires an ack.
837 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
839 SimulateGestureEvent(WebInputEvent::GestureShowPress,
840 WebGestureEvent::Touchscreen);
842 EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
843 // ShowPress has entered the queue.
844 EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
846 SendInputEventACK(WebInputEvent::GestureTap,
847 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
849 // Now that the Tap has been ACKed, the ShowPress events should receive
850 // synthetics acks, and fire immediately.
851 EXPECT_EQ(2U, GetSentMessageCountAndResetSink());
852 EXPECT_EQ(3U, ack_handler_->GetAndResetAckCount());
855 // Test that touch ack timeout behavior is properly configured via the command
856 // line, and toggled by the view update flags.
857 TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
858 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
859 switches::kTouchAckTimeoutDelayMs, "5");
860 TearDown();
861 SetUp();
862 ASSERT_TRUE(TouchEventTimeoutEnabled());
864 // A fixed page scale or mobile viewport should disable the touch timeout.
865 input_router()->OnViewUpdated(InputRouter::FIXED_PAGE_SCALE);
866 EXPECT_FALSE(TouchEventTimeoutEnabled());
868 input_router()->OnViewUpdated(InputRouter::VIEW_FLAGS_NONE);
869 EXPECT_TRUE(TouchEventTimeoutEnabled());
871 input_router()->OnViewUpdated(InputRouter::MOBILE_VIEWPORT);
872 EXPECT_FALSE(TouchEventTimeoutEnabled());
874 input_router()->OnViewUpdated(InputRouter::MOBILE_VIEWPORT |
875 InputRouter::FIXED_PAGE_SCALE);
876 EXPECT_FALSE(TouchEventTimeoutEnabled());
878 input_router()->OnViewUpdated(InputRouter::VIEW_FLAGS_NONE);
879 EXPECT_TRUE(TouchEventTimeoutEnabled());
882 } // namespace content