1 // Copyright (c) 2012 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"
7 #include "base/command_line.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/shared_memory.h"
10 #include "base/timer/timer.h"
11 #include "content/browser/browser_thread_impl.h"
12 #include "content/browser/renderer_host/input/input_router_impl.h"
13 #include "content/browser/renderer_host/render_widget_host_delegate.h"
14 #include "content/browser/renderer_host/render_widget_host_view_base.h"
15 #include "content/common/input/synthetic_web_input_event_builders.h"
16 #include "content/common/input_messages.h"
17 #include "content/common/view_messages.h"
18 #include "content/public/common/content_switches.h"
19 #include "content/public/test/mock_render_process_host.h"
20 #include "content/public/test/test_browser_context.h"
21 #include "content/test/test_render_view_host.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/events/keycodes/keyboard_codes.h"
24 #include "ui/gfx/canvas.h"
25 #include "ui/gfx/screen.h"
27 #if defined(OS_ANDROID)
28 #include "content/browser/renderer_host/render_widget_host_view_android.h"
32 #include "content/browser/compositor/image_transport_factory.h"
33 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
34 #include "content/browser/renderer_host/ui_events_helper.h"
35 #include "ui/aura/env.h"
36 #include "ui/aura/test/test_screen.h"
37 #include "ui/compositor/test/in_process_context_factory.h"
38 #include "ui/events/event.h"
41 using base::TimeDelta;
42 using blink::WebGestureDevice;
43 using blink::WebGestureEvent;
44 using blink::WebInputEvent;
45 using blink::WebKeyboardEvent;
46 using blink::WebMouseEvent;
47 using blink::WebMouseWheelEvent;
48 using blink::WebTouchEvent;
49 using blink::WebTouchPoint;
53 // MockInputRouter -------------------------------------------------------------
55 class MockInputRouter : public InputRouter {
57 explicit MockInputRouter(InputRouterClient* client)
58 : send_event_called_(false),
59 sent_mouse_event_(false),
60 sent_wheel_event_(false),
61 sent_keyboard_event_(false),
62 sent_gesture_event_(false),
63 send_touch_event_not_cancelled_(false),
64 message_received_(false),
67 virtual ~MockInputRouter() {}
70 virtual void Flush() OVERRIDE {
73 virtual bool SendInput(scoped_ptr<IPC::Message> message) OVERRIDE {
74 send_event_called_ = true;
77 virtual void SendMouseEvent(
78 const MouseEventWithLatencyInfo& mouse_event) OVERRIDE {
79 sent_mouse_event_ = true;
81 virtual void SendWheelEvent(
82 const MouseWheelEventWithLatencyInfo& wheel_event) OVERRIDE {
83 sent_wheel_event_ = true;
85 virtual void SendKeyboardEvent(
86 const NativeWebKeyboardEvent& key_event,
87 const ui::LatencyInfo& latency_info,
88 bool is_shortcut) OVERRIDE {
89 sent_keyboard_event_ = true;
91 virtual void SendGestureEvent(
92 const GestureEventWithLatencyInfo& gesture_event) OVERRIDE {
93 sent_gesture_event_ = true;
95 virtual void SendTouchEvent(
96 const TouchEventWithLatencyInfo& touch_event) OVERRIDE {
97 send_touch_event_not_cancelled_ =
98 client_->FilterInputEvent(touch_event.event, touch_event.latency) ==
99 INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
101 virtual const NativeWebKeyboardEvent* GetLastKeyboardEvent() const OVERRIDE {
105 virtual bool ShouldForwardTouchEvent() const OVERRIDE { return true; }
106 virtual void OnViewUpdated(int view_flags) OVERRIDE {}
109 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
110 message_received_ = true;
115 bool send_event_called_;
116 bool sent_mouse_event_;
117 bool sent_wheel_event_;
118 bool sent_keyboard_event_;
119 bool sent_gesture_event_;
120 bool send_touch_event_not_cancelled_;
121 bool message_received_;
124 InputRouterClient* client_;
126 DISALLOW_COPY_AND_ASSIGN(MockInputRouter);
129 // MockRenderWidgetHost ----------------------------------------------------
131 class MockRenderWidgetHost : public RenderWidgetHostImpl {
133 MockRenderWidgetHost(
134 RenderWidgetHostDelegate* delegate,
135 RenderProcessHost* process,
137 : RenderWidgetHostImpl(delegate, process, routing_id, false),
138 unresponsive_timer_fired_(false) {
139 acked_touch_event_type_ = blink::WebInputEvent::Undefined;
142 // Allow poking at a few private members.
143 using RenderWidgetHostImpl::OnUpdateRect;
144 using RenderWidgetHostImpl::RendererExited;
145 using RenderWidgetHostImpl::last_requested_size_;
146 using RenderWidgetHostImpl::is_hidden_;
147 using RenderWidgetHostImpl::resize_ack_pending_;
148 using RenderWidgetHostImpl::input_router_;
150 virtual void OnTouchEventAck(
151 const TouchEventWithLatencyInfo& event,
152 InputEventAckState ack_result) OVERRIDE {
154 acked_touch_event_type_ = event.event.type;
155 RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
158 bool unresponsive_timer_fired() const {
159 return unresponsive_timer_fired_;
162 void set_hung_renderer_delay_ms(int delay_ms) {
163 hung_renderer_delay_ms_ = delay_ms;
166 void DisableGestureDebounce() {
167 input_router_.reset(new InputRouterImpl(
168 process_, this, this, routing_id_, InputRouterImpl::Config()));
171 WebInputEvent::Type acked_touch_event_type() const {
172 return acked_touch_event_type_;
175 void SetupForInputRouterTest() {
176 input_router_.reset(new MockInputRouter(this));
179 MockInputRouter* mock_input_router() {
180 return static_cast<MockInputRouter*>(input_router_.get());
184 virtual void NotifyRendererUnresponsive() OVERRIDE {
185 unresponsive_timer_fired_ = true;
188 bool unresponsive_timer_fired_;
189 WebInputEvent::Type acked_touch_event_type_;
191 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
196 // RenderWidgetHostProcess -----------------------------------------------------
198 class RenderWidgetHostProcess : public MockRenderProcessHost {
200 explicit RenderWidgetHostProcess(BrowserContext* browser_context)
201 : MockRenderProcessHost(browser_context),
202 update_msg_should_reply_(false),
203 update_msg_reply_flags_(0) {
205 virtual ~RenderWidgetHostProcess() {
208 void set_update_msg_should_reply(bool reply) {
209 update_msg_should_reply_ = reply;
211 void set_update_msg_reply_flags(int flags) {
212 update_msg_reply_flags_ = flags;
215 // Fills the given update parameters with resonable default values.
216 void InitUpdateRectParams(ViewHostMsg_UpdateRect_Params* params);
218 virtual bool HasConnection() const OVERRIDE { return true; }
221 virtual bool WaitForBackingStoreMsg(int render_widget_id,
222 const base::TimeDelta& max_delay,
223 IPC::Message* msg) OVERRIDE;
225 // Set to true when WaitForBackingStoreMsg should return a successful update
226 // message reply. False implies timeout.
227 bool update_msg_should_reply_;
229 // Indicates the flags that should be sent with a repaint request. This
230 // only has an effect when update_msg_should_reply_ is true.
231 int update_msg_reply_flags_;
233 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess);
236 void RenderWidgetHostProcess::InitUpdateRectParams(
237 ViewHostMsg_UpdateRect_Params* params) {
238 const int w = 100, h = 100;
240 params->view_size = gfx::Size(w, h);
241 params->flags = update_msg_reply_flags_;
244 bool RenderWidgetHostProcess::WaitForBackingStoreMsg(
245 int render_widget_id,
246 const base::TimeDelta& max_delay,
248 if (!update_msg_should_reply_)
251 // Construct a fake update reply.
252 ViewHostMsg_UpdateRect_Params params;
253 InitUpdateRectParams(¶ms);
255 ViewHostMsg_UpdateRect message(render_widget_id, params);
260 // TestView --------------------------------------------------------------------
262 // This test view allows us to specify the size, and keep track of acked
264 class TestView : public TestRenderWidgetHostView {
266 explicit TestView(RenderWidgetHostImpl* rwh)
267 : TestRenderWidgetHostView(rwh),
268 unhandled_wheel_event_count_(0),
269 acked_event_count_(0),
270 gesture_event_type_(-1),
271 use_fake_physical_backing_size_(false),
272 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
275 // Sets the bounds returned by GetViewBounds.
276 void set_bounds(const gfx::Rect& bounds) {
280 const WebTouchEvent& acked_event() const { return acked_event_; }
281 int acked_event_count() const { return acked_event_count_; }
282 void ClearAckedEvent() {
283 acked_event_.type = blink::WebInputEvent::Undefined;
284 acked_event_count_ = 0;
287 const WebMouseWheelEvent& unhandled_wheel_event() const {
288 return unhandled_wheel_event_;
290 int unhandled_wheel_event_count() const {
291 return unhandled_wheel_event_count_;
293 int gesture_event_type() const { return gesture_event_type_; }
294 InputEventAckState ack_result() const { return ack_result_; }
296 void SetMockPhysicalBackingSize(const gfx::Size& mock_physical_backing_size) {
297 use_fake_physical_backing_size_ = true;
298 mock_physical_backing_size_ = mock_physical_backing_size;
300 void ClearMockPhysicalBackingSize() {
301 use_fake_physical_backing_size_ = false;
304 // RenderWidgetHostView override.
305 virtual gfx::Rect GetViewBounds() const OVERRIDE {
308 virtual void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
309 InputEventAckState ack_result) OVERRIDE {
310 acked_event_ = touch.event;
311 ++acked_event_count_;
313 virtual void WheelEventAck(const WebMouseWheelEvent& event,
314 InputEventAckState ack_result) OVERRIDE {
315 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
317 unhandled_wheel_event_count_++;
318 unhandled_wheel_event_ = event;
320 virtual void GestureEventAck(const WebGestureEvent& event,
321 InputEventAckState ack_result) OVERRIDE {
322 gesture_event_type_ = event.type;
323 ack_result_ = ack_result;
325 virtual gfx::Size GetPhysicalBackingSize() const OVERRIDE {
326 if (use_fake_physical_backing_size_)
327 return mock_physical_backing_size_;
328 return TestRenderWidgetHostView::GetPhysicalBackingSize();
332 WebMouseWheelEvent unhandled_wheel_event_;
333 int unhandled_wheel_event_count_;
334 WebTouchEvent acked_event_;
335 int acked_event_count_;
336 int gesture_event_type_;
338 bool use_fake_physical_backing_size_;
339 gfx::Size mock_physical_backing_size_;
340 InputEventAckState ack_result_;
342 DISALLOW_COPY_AND_ASSIGN(TestView);
345 // MockRenderWidgetHostDelegate --------------------------------------------
347 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
349 MockRenderWidgetHostDelegate()
350 : prehandle_keyboard_event_(false),
351 prehandle_keyboard_event_called_(false),
352 prehandle_keyboard_event_type_(WebInputEvent::Undefined),
353 unhandled_keyboard_event_called_(false),
354 unhandled_keyboard_event_type_(WebInputEvent::Undefined),
355 handle_wheel_event_(false),
356 handle_wheel_event_called_(false) {
358 virtual ~MockRenderWidgetHostDelegate() {}
360 // Tests that make sure we ignore keyboard event acknowledgments to events we
361 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
362 bool unhandled_keyboard_event_called() const {
363 return unhandled_keyboard_event_called_;
366 WebInputEvent::Type unhandled_keyboard_event_type() const {
367 return unhandled_keyboard_event_type_;
370 bool prehandle_keyboard_event_called() const {
371 return prehandle_keyboard_event_called_;
374 WebInputEvent::Type prehandle_keyboard_event_type() const {
375 return prehandle_keyboard_event_type_;
378 void set_prehandle_keyboard_event(bool handle) {
379 prehandle_keyboard_event_ = handle;
382 void set_handle_wheel_event(bool handle) {
383 handle_wheel_event_ = handle;
386 bool handle_wheel_event_called() {
387 return handle_wheel_event_called_;
391 virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
392 bool* is_keyboard_shortcut) OVERRIDE {
393 prehandle_keyboard_event_type_ = event.type;
394 prehandle_keyboard_event_called_ = true;
395 return prehandle_keyboard_event_;
398 virtual void HandleKeyboardEvent(
399 const NativeWebKeyboardEvent& event) OVERRIDE {
400 unhandled_keyboard_event_type_ = event.type;
401 unhandled_keyboard_event_called_ = true;
404 virtual bool HandleWheelEvent(
405 const blink::WebMouseWheelEvent& event) OVERRIDE {
406 handle_wheel_event_called_ = true;
407 return handle_wheel_event_;
411 bool prehandle_keyboard_event_;
412 bool prehandle_keyboard_event_called_;
413 WebInputEvent::Type prehandle_keyboard_event_type_;
415 bool unhandled_keyboard_event_called_;
416 WebInputEvent::Type unhandled_keyboard_event_type_;
418 bool handle_wheel_event_;
419 bool handle_wheel_event_called_;
422 // RenderWidgetHostTest --------------------------------------------------------
424 class RenderWidgetHostTest : public testing::Test {
426 RenderWidgetHostTest()
428 handle_key_press_event_(false),
429 handle_mouse_event_(false),
430 simulated_event_time_delta_seconds_(0) {
431 last_simulated_event_time_seconds_ =
432 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
434 virtual ~RenderWidgetHostTest() {
437 bool KeyPressEventCallback(const NativeWebKeyboardEvent& /* event */) {
438 return handle_key_press_event_;
440 bool MouseEventCallback(const blink::WebMouseEvent& /* event */) {
441 return handle_mouse_event_;
446 virtual void SetUp() {
447 CommandLine* command_line = CommandLine::ForCurrentProcess();
448 command_line->AppendSwitch(switches::kValidateInputEventStream);
450 browser_context_.reset(new TestBrowserContext());
451 delegate_.reset(new MockRenderWidgetHostDelegate());
452 process_ = new RenderWidgetHostProcess(browser_context_.get());
453 #if defined(USE_AURA)
454 ImageTransportFactory::InitializeForUnitTests(
455 scoped_ptr<ui::ContextFactory>(new ui::InProcessContextFactory));
456 aura::Env::CreateInstance(true);
457 screen_.reset(aura::TestScreen::Create(gfx::Size()));
458 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
461 new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
462 view_.reset(new TestView(host_.get()));
463 host_->SetView(view_.get());
465 host_->DisableGestureDebounce();
467 virtual void TearDown() {
472 browser_context_.reset();
474 #if defined(USE_AURA)
475 aura::Env::DeleteInstance();
477 ImageTransportFactory::Terminate();
480 // Process all pending tasks to avoid leaks.
481 base::MessageLoop::current()->RunUntilIdle();
484 int64 GetLatencyComponentId() {
485 return host_->GetLatencyComponentId();
488 void SendInputEventACK(WebInputEvent::Type type,
489 InputEventAckState ack_result) {
490 InputHostMsg_HandleInputEvent_ACK_Params ack;
492 ack.state = ack_result;
493 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
496 double GetNextSimulatedEventTimeSeconds() {
497 last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_;
498 return last_simulated_event_time_seconds_;
501 void SimulateKeyboardEvent(WebInputEvent::Type type) {
502 SimulateKeyboardEvent(type, 0);
505 void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) {
506 WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
507 event.modifiers = modifiers;
508 NativeWebKeyboardEvent native_event;
509 memcpy(&native_event, &event, sizeof(event));
510 host_->ForwardKeyboardEvent(native_event);
513 void SimulateMouseEvent(WebInputEvent::Type type) {
514 host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type));
517 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type,
518 const ui::LatencyInfo& ui_latency) {
519 host_->ForwardMouseEventWithLatencyInfo(
520 SyntheticWebMouseEventBuilder::Build(type),
524 void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
525 host_->ForwardWheelEvent(
526 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
529 void SimulateWheelEventWithLatencyInfo(float dX,
533 const ui::LatencyInfo& ui_latency) {
534 host_->ForwardWheelEventWithLatencyInfo(
535 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
539 void SimulateMouseMove(int x, int y, int modifiers) {
540 SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false);
543 void SimulateMouseEvent(
544 WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) {
545 WebMouseEvent event =
546 SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers);
548 event.button = WebMouseEvent::ButtonLeft;
549 event.timeStampSeconds = GetNextSimulatedEventTimeSeconds();
550 host_->ForwardMouseEvent(event);
553 // Inject simple synthetic WebGestureEvent instances.
554 void SimulateGestureEvent(WebInputEvent::Type type,
555 WebGestureDevice sourceDevice) {
556 host_->ForwardGestureEvent(
557 SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
560 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type,
561 WebGestureDevice sourceDevice,
562 const ui::LatencyInfo& ui_latency) {
563 host_->ForwardGestureEventWithLatencyInfo(
564 SyntheticWebGestureEventBuilder::Build(type, sourceDevice),
568 // Set the timestamp for the touch-event.
569 void SetTouchTimestamp(base::TimeDelta timestamp) {
570 touch_event_.SetTimestamp(timestamp);
573 // Sends a touch event (irrespective of whether the page has a touch-event
575 void SendTouchEvent() {
576 host_->ForwardTouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo());
578 touch_event_.ResetPoints();
581 int PressTouchPoint(int x, int y) {
582 return touch_event_.PressPoint(x, y);
585 void MoveTouchPoint(int index, int x, int y) {
586 touch_event_.MovePoint(index, x, y);
589 void ReleaseTouchPoint(int index) {
590 touch_event_.ReleasePoint(index);
593 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
594 PickleIterator iter(message);
597 if (!message.ReadData(&iter, &data, &data_length))
599 return reinterpret_cast<const WebInputEvent*>(data);
602 base::MessageLoopForUI message_loop_;
604 scoped_ptr<TestBrowserContext> browser_context_;
605 RenderWidgetHostProcess* process_; // Deleted automatically by the widget.
606 scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
607 scoped_ptr<MockRenderWidgetHost> host_;
608 scoped_ptr<TestView> view_;
609 scoped_ptr<gfx::Screen> screen_;
610 bool handle_key_press_event_;
611 bool handle_mouse_event_;
612 double last_simulated_event_time_seconds_;
613 double simulated_event_time_delta_seconds_;
616 SyntheticWebTouchEvent touch_event_;
618 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest);
621 #if GTEST_HAS_PARAM_TEST
622 // RenderWidgetHostWithSourceTest ----------------------------------------------
624 // This is for tests that are to be run for all source devices.
625 class RenderWidgetHostWithSourceTest
626 : public RenderWidgetHostTest,
627 public testing::WithParamInterface<WebGestureDevice> {};
628 #endif // GTEST_HAS_PARAM_TEST
632 // -----------------------------------------------------------------------------
634 TEST_F(RenderWidgetHostTest, Resize) {
635 // The initial bounds is the empty rect, and the screen info hasn't been sent
636 // yet, so setting it to the same thing shouldn't send the resize message.
637 view_->set_bounds(gfx::Rect());
639 EXPECT_FALSE(host_->resize_ack_pending_);
640 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
642 // Setting the bounds to a "real" rect should send out the notification.
643 // but should not expect ack for empty physical backing size.
644 gfx::Rect original_size(0, 0, 100, 100);
645 process_->sink().ClearMessages();
646 view_->set_bounds(original_size);
647 view_->SetMockPhysicalBackingSize(gfx::Size());
649 EXPECT_FALSE(host_->resize_ack_pending_);
650 EXPECT_EQ(original_size.size(), host_->last_requested_size_);
651 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
653 // Setting the bounds to a "real" rect should send out the notification.
654 // but should not expect ack for only physical backing size change.
655 process_->sink().ClearMessages();
656 view_->ClearMockPhysicalBackingSize();
658 EXPECT_FALSE(host_->resize_ack_pending_);
659 EXPECT_EQ(original_size.size(), host_->last_requested_size_);
660 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
662 // Send out a update that's not a resize ack after setting resize ack pending
663 // flag. This should not clean the resize ack pending flag.
664 process_->sink().ClearMessages();
665 gfx::Rect second_size(0, 0, 110, 110);
666 EXPECT_FALSE(host_->resize_ack_pending_);
667 view_->set_bounds(second_size);
669 EXPECT_TRUE(host_->resize_ack_pending_);
670 ViewHostMsg_UpdateRect_Params params;
671 process_->InitUpdateRectParams(¶ms);
672 host_->OnUpdateRect(params);
673 EXPECT_TRUE(host_->resize_ack_pending_);
674 EXPECT_EQ(second_size.size(), host_->last_requested_size_);
676 // Sending out a new notification should NOT send out a new IPC message since
677 // a resize ACK is pending.
678 gfx::Rect third_size(0, 0, 120, 120);
679 process_->sink().ClearMessages();
680 view_->set_bounds(third_size);
682 EXPECT_TRUE(host_->resize_ack_pending_);
683 EXPECT_EQ(second_size.size(), host_->last_requested_size_);
684 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
686 // Send a update that's a resize ack, but for the original_size we sent. Since
687 // this isn't the second_size, the message handler should immediately send
688 // a new resize message for the new size to the renderer.
689 process_->sink().ClearMessages();
690 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
691 params.view_size = original_size.size();
692 host_->OnUpdateRect(params);
693 EXPECT_TRUE(host_->resize_ack_pending_);
694 EXPECT_EQ(third_size.size(), host_->last_requested_size_);
695 ASSERT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
697 // Send the resize ack for the latest size.
698 process_->sink().ClearMessages();
699 params.view_size = third_size.size();
700 host_->OnUpdateRect(params);
701 EXPECT_FALSE(host_->resize_ack_pending_);
702 EXPECT_EQ(third_size.size(), host_->last_requested_size_);
703 ASSERT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
705 // Now clearing the bounds should send out a notification but we shouldn't
706 // expect a resize ack (since the renderer won't ack empty sizes). The message
707 // should contain the new size (0x0) and not the previous one that we skipped
708 process_->sink().ClearMessages();
709 view_->set_bounds(gfx::Rect());
711 EXPECT_FALSE(host_->resize_ack_pending_);
712 EXPECT_EQ(gfx::Size(), host_->last_requested_size_);
713 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
715 // Send a rect that has no area but has either width or height set.
716 process_->sink().ClearMessages();
717 view_->set_bounds(gfx::Rect(0, 0, 0, 30));
719 EXPECT_FALSE(host_->resize_ack_pending_);
720 EXPECT_EQ(gfx::Size(0, 30), host_->last_requested_size_);
721 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
723 // Set the same size again. It should not be sent again.
724 process_->sink().ClearMessages();
726 EXPECT_FALSE(host_->resize_ack_pending_);
727 EXPECT_EQ(gfx::Size(0, 30), host_->last_requested_size_);
728 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
730 // A different size should be sent again, however.
731 view_->set_bounds(gfx::Rect(0, 0, 0, 31));
733 EXPECT_FALSE(host_->resize_ack_pending_);
734 EXPECT_EQ(gfx::Size(0, 31), host_->last_requested_size_);
735 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
738 // Test for crbug.com/25097. If a renderer crashes between a resize and the
739 // corresponding update message, we must be sure to clear the resize ack logic.
740 TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
741 // Clear the first Resize message that carried screen info.
742 process_->sink().ClearMessages();
744 // Setting the bounds to a "real" rect should send out the notification.
745 gfx::Rect original_size(0, 0, 100, 100);
746 view_->set_bounds(original_size);
748 EXPECT_TRUE(host_->resize_ack_pending_);
749 EXPECT_EQ(original_size.size(), host_->last_requested_size_);
750 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
752 // Simulate a renderer crash before the update message. Ensure all the
753 // resize ack logic is cleared. Must clear the view first so it doesn't get
755 host_->SetView(NULL);
756 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
757 EXPECT_FALSE(host_->resize_ack_pending_);
758 EXPECT_EQ(gfx::Size(), host_->last_requested_size_);
760 // Reset the view so we can exit the test cleanly.
761 host_->SetView(view_.get());
764 // Unable to include render_widget_host_view_mac.h and compile.
765 #if !defined(OS_MACOSX)
766 // Tests setting background transparency.
767 TEST_F(RenderWidgetHostTest, Background) {
768 scoped_ptr<RenderWidgetHostViewBase> view;
769 #if defined(USE_AURA)
770 view.reset(new RenderWidgetHostViewAura(host_.get()));
771 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
772 view->InitAsChild(NULL);
773 #elif defined(OS_ANDROID)
774 view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
776 host_->SetView(view.get());
778 EXPECT_TRUE(view->GetBackgroundOpaque());
779 view->SetBackgroundOpaque(false);
780 EXPECT_FALSE(view->GetBackgroundOpaque());
782 const IPC::Message* set_background =
783 process_->sink().GetUniqueMessageMatching(
784 ViewMsg_SetBackgroundOpaque::ID);
785 ASSERT_TRUE(set_background);
786 Tuple1<bool> sent_background;
787 ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
788 EXPECT_FALSE(sent_background.a);
790 #if defined(USE_AURA)
791 // See the comment above |InitAsChild(NULL)|.
792 host_->SetView(NULL);
793 static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
798 // Test that we don't paint when we're hidden, but we still send the ACK. Most
799 // of the rest of the painting is tested in the GetBackingStore* ones.
800 TEST_F(RenderWidgetHostTest, HiddenPaint) {
801 BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
802 // Hide the widget, it should have sent out a message to the renderer.
803 EXPECT_FALSE(host_->is_hidden_);
805 EXPECT_TRUE(host_->is_hidden_);
806 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID));
808 // Send it an update as from the renderer.
809 process_->sink().ClearMessages();
810 ViewHostMsg_UpdateRect_Params params;
811 process_->InitUpdateRectParams(¶ms);
812 host_->OnUpdateRect(params);
815 process_->sink().ClearMessages();
817 EXPECT_FALSE(host_->is_hidden_);
819 // It should have sent out a restored message with a request to paint.
820 const IPC::Message* restored = process_->sink().GetUniqueMessageMatching(
821 ViewMsg_WasShown::ID);
822 ASSERT_TRUE(restored);
823 Tuple1<bool> needs_repaint;
824 ViewMsg_WasShown::Read(restored, &needs_repaint);
825 EXPECT_TRUE(needs_repaint.a);
828 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
829 // Simulate a keyboard event.
830 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
832 // Make sure we sent the input event to the renderer.
833 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
834 InputMsg_HandleInputEvent::ID));
835 process_->sink().ClearMessages();
837 // Send the simulated response from the renderer back.
838 SendInputEventACK(WebInputEvent::RawKeyDown,
839 INPUT_EVENT_ACK_STATE_CONSUMED);
840 EXPECT_FALSE(delegate_->unhandled_keyboard_event_called());
843 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
844 // Simluate the situation that the browser handled the key down event during
845 // pre-handle phrase.
846 delegate_->set_prehandle_keyboard_event(true);
847 process_->sink().ClearMessages();
849 // Simulate a keyboard event.
850 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
852 EXPECT_TRUE(delegate_->prehandle_keyboard_event_called());
853 EXPECT_EQ(WebInputEvent::RawKeyDown,
854 delegate_->prehandle_keyboard_event_type());
856 // Make sure the RawKeyDown event is not sent to the renderer.
857 EXPECT_EQ(0U, process_->sink().message_count());
859 // The browser won't pre-handle a Char event.
860 delegate_->set_prehandle_keyboard_event(false);
862 // Forward the Char event.
863 SimulateKeyboardEvent(WebInputEvent::Char);
865 // Make sure the Char event is suppressed.
866 EXPECT_EQ(0U, process_->sink().message_count());
868 // Forward the KeyUp event.
869 SimulateKeyboardEvent(WebInputEvent::KeyUp);
871 // Make sure only KeyUp was sent to the renderer.
872 EXPECT_EQ(1U, process_->sink().message_count());
873 EXPECT_EQ(InputMsg_HandleInputEvent::ID,
874 process_->sink().GetMessageAt(0)->type());
875 process_->sink().ClearMessages();
877 // Send the simulated response from the renderer back.
878 SendInputEventACK(WebInputEvent::KeyUp,
879 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
881 EXPECT_TRUE(delegate_->unhandled_keyboard_event_called());
882 EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type());
885 TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
886 SimulateWheelEvent(-5, 0, 0, true);
888 // Make sure we sent the input event to the renderer.
889 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
890 InputMsg_HandleInputEvent::ID));
891 process_->sink().ClearMessages();
893 // Send the simulated response from the renderer back.
894 SendInputEventACK(WebInputEvent::MouseWheel,
895 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
896 EXPECT_TRUE(delegate_->handle_wheel_event_called());
897 EXPECT_EQ(1, view_->unhandled_wheel_event_count());
898 EXPECT_EQ(-5, view_->unhandled_wheel_event().deltaX);
901 TEST_F(RenderWidgetHostTest, HandleWheelEvent) {
902 // Indicate that we're going to handle this wheel event
903 delegate_->set_handle_wheel_event(true);
905 SimulateWheelEvent(-5, 0, 0, true);
907 // Make sure we sent the input event to the renderer.
908 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
909 InputMsg_HandleInputEvent::ID));
910 process_->sink().ClearMessages();
912 // Send the simulated response from the renderer back.
913 SendInputEventACK(WebInputEvent::MouseWheel,
914 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
916 // ensure the wheel event handler was invoked
917 EXPECT_TRUE(delegate_->handle_wheel_event_called());
919 // and that it suppressed the unhandled wheel event handler.
920 EXPECT_EQ(0, view_->unhandled_wheel_event_count());
923 TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
924 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap,
925 blink::WebGestureDeviceTouchscreen);
927 // Make sure we sent the input event to the renderer.
928 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
929 InputMsg_HandleInputEvent::ID));
930 process_->sink().ClearMessages();
932 // Send the simulated response from the renderer back.
933 SendInputEventACK(WebInputEvent::GestureTwoFingerTap,
934 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
935 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap, view_->gesture_event_type());
936 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, view_->ack_result());
939 // Test that the hang monitor timer expires properly if a new timer is started
940 // while one is in progress (see crbug.com/11007).
941 TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) {
942 // Start with a short timeout.
943 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
945 // Immediately try to add a long 30 second timeout.
946 EXPECT_FALSE(host_->unresponsive_timer_fired());
947 host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
949 // Wait long enough for first timeout and see if it fired.
950 base::MessageLoop::current()->PostDelayedTask(
952 base::MessageLoop::QuitClosure(),
953 TimeDelta::FromMilliseconds(10));
954 base::MessageLoop::current()->Run();
955 EXPECT_TRUE(host_->unresponsive_timer_fired());
958 // Test that the hang monitor timer expires properly if it is started, stopped,
959 // and then started again.
960 TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
961 // Start with a short timeout, then stop it.
962 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
963 host_->StopHangMonitorTimeout();
965 // Start it again to ensure it still works.
966 EXPECT_FALSE(host_->unresponsive_timer_fired());
967 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
969 // Wait long enough for first timeout and see if it fired.
970 base::MessageLoop::current()->PostDelayedTask(
972 base::MessageLoop::QuitClosure(),
973 TimeDelta::FromMilliseconds(40));
974 base::MessageLoop::current()->Run();
975 EXPECT_TRUE(host_->unresponsive_timer_fired());
978 // Test that the hang monitor timer expires properly if it is started, then
979 // updated to a shorter duration.
980 TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) {
981 // Start with a timeout.
982 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
984 // Start it again with shorter delay.
985 EXPECT_FALSE(host_->unresponsive_timer_fired());
986 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
988 // Wait long enough for the second timeout and see if it fired.
989 base::MessageLoop::current()->PostDelayedTask(
991 base::MessageLoop::QuitClosure(),
992 TimeDelta::FromMilliseconds(25));
993 base::MessageLoop::current()->Run();
994 EXPECT_TRUE(host_->unresponsive_timer_fired());
997 // Test that the hang monitor catches two input events but only one ack.
998 // This can happen if the second input event causes the renderer to hang.
999 // This test will catch a regression of crbug.com/111185.
1000 TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
1001 // Configure the host to wait 10ms before considering
1002 // the renderer hung.
1003 host_->set_hung_renderer_delay_ms(10);
1005 // Send two events but only one ack.
1006 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1007 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1008 SendInputEventACK(WebInputEvent::RawKeyDown,
1009 INPUT_EVENT_ACK_STATE_CONSUMED);
1011 // Wait long enough for first timeout and see if it fired.
1012 base::MessageLoop::current()->PostDelayedTask(
1014 base::MessageLoop::QuitClosure(),
1015 TimeDelta::FromMilliseconds(40));
1016 base::MessageLoop::current()->Run();
1017 EXPECT_TRUE(host_->unresponsive_timer_fired());
1020 std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
1022 for (size_t i = 0; i < process->sink().message_count(); ++i) {
1023 const IPC::Message *message = process->sink().GetMessageAt(i);
1024 EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
1025 InputMsg_HandleInputEvent::Param params;
1026 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, ¶ms));
1027 const WebInputEvent* event = params.a;
1030 result += WebInputEventTraits::GetName(event->type);
1032 process->sink().ClearMessages();
1036 TEST_F(RenderWidgetHostTest, TouchEmulator) {
1037 simulated_event_time_delta_seconds_ = 0.1;
1038 // Immediately ack all touches instead of sending them to the renderer.
1039 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1040 host_->OnMessageReceived(
1041 ViewHostMsg_SetTouchEventEmulationEnabled(0, true, true));
1042 process_->sink().ClearMessages();
1043 view_->set_bounds(gfx::Rect(0, 0, 400, 200));
1046 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1047 EXPECT_EQ(0U, process_->sink().message_count());
1049 // Mouse press becomes touch start which in turn becomes tap.
1050 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1051 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1052 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1054 // Mouse drag generates touch move, cancels tap and starts scroll.
1055 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1056 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1058 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1059 GetInputMessageTypes(process_));
1060 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1061 INPUT_EVENT_ACK_STATE_CONSUMED);
1062 EXPECT_EQ(0U, process_->sink().message_count());
1064 // Mouse drag with shift becomes pinch.
1066 WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true);
1067 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1068 EXPECT_EQ("GesturePinchBegin",
1069 GetInputMessageTypes(process_));
1070 EXPECT_EQ(0U, process_->sink().message_count());
1073 WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true);
1074 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1075 EXPECT_EQ("GesturePinchUpdate",
1076 GetInputMessageTypes(process_));
1077 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1078 INPUT_EVENT_ACK_STATE_CONSUMED);
1079 EXPECT_EQ(0U, process_->sink().message_count());
1081 // Mouse drag without shift becomes scroll again.
1082 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true);
1083 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1084 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1085 GetInputMessageTypes(process_));
1086 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1087 INPUT_EVENT_ACK_STATE_CONSUMED);
1088 EXPECT_EQ(0U, process_->sink().message_count());
1090 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true);
1091 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1092 EXPECT_EQ("GestureScrollUpdate",
1093 GetInputMessageTypes(process_));
1094 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1095 INPUT_EVENT_ACK_STATE_CONSUMED);
1096 EXPECT_EQ(0U, process_->sink().message_count());
1098 SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true);
1099 EXPECT_EQ(WebInputEvent::TouchEnd, host_->acked_touch_event_type());
1100 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1101 EXPECT_EQ(0U, process_->sink().message_count());
1103 // Mouse move does nothing.
1104 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false);
1105 EXPECT_EQ(0U, process_->sink().message_count());
1107 // Another mouse down continues scroll.
1108 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true);
1109 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1110 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1111 EXPECT_EQ(0U, process_->sink().message_count());
1113 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true);
1114 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1116 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1117 GetInputMessageTypes(process_));
1118 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1119 INPUT_EVENT_ACK_STATE_CONSUMED);
1120 EXPECT_EQ(0U, process_->sink().message_count());
1124 WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true);
1125 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1126 EXPECT_EQ("GesturePinchBegin",
1127 GetInputMessageTypes(process_));
1128 EXPECT_EQ(0U, process_->sink().message_count());
1131 WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true);
1132 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1133 EXPECT_EQ("GesturePinchUpdate",
1134 GetInputMessageTypes(process_));
1135 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1136 INPUT_EVENT_ACK_STATE_CONSUMED);
1137 EXPECT_EQ(0U, process_->sink().message_count());
1139 // Turn off emulation during a pinch.
1140 host_->OnMessageReceived(
1141 ViewHostMsg_SetTouchEventEmulationEnabled(0, false, false));
1142 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1143 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1144 GetInputMessageTypes(process_));
1145 EXPECT_EQ(0U, process_->sink().message_count());
1147 // Mouse event should pass untouched.
1149 WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true);
1150 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_));
1151 SendInputEventACK(WebInputEvent::MouseMove,
1152 INPUT_EVENT_ACK_STATE_CONSUMED);
1153 EXPECT_EQ(0U, process_->sink().message_count());
1155 // Turn on emulation.
1156 host_->OnMessageReceived(
1157 ViewHostMsg_SetTouchEventEmulationEnabled(0, true, true));
1158 EXPECT_EQ(0U, process_->sink().message_count());
1161 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1162 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1163 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1164 EXPECT_EQ(0U, process_->sink().message_count());
1167 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1168 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1170 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1171 GetInputMessageTypes(process_));
1172 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1173 INPUT_EVENT_ACK_STATE_CONSUMED);
1175 // Turn off emulation during a scroll.
1176 host_->OnMessageReceived(
1177 ViewHostMsg_SetTouchEventEmulationEnabled(0, false, false));
1178 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1180 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1181 EXPECT_EQ(0U, process_->sink().message_count());
1184 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1185 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1186 host_->SetupForInputRouterTest(); \
1187 host_->INPUTMSG(); \
1188 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1191 TEST_InputRouterRoutes_NOARGS(Focus);
1192 TEST_InputRouterRoutes_NOARGS(Blur);
1193 TEST_InputRouterRoutes_NOARGS(LostCapture);
1195 #undef TEST_InputRouterRoutes_NOARGS
1197 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1198 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1199 host_->SetupForInputRouterTest(); \
1200 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1201 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1204 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo);
1205 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo);
1206 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut);
1207 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy);
1208 #if defined(OS_MACOSX)
1209 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard);
1211 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste);
1212 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle);
1213 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete);
1214 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll);
1215 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect);
1217 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1219 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplace) {
1220 host_->SetupForInputRouterTest();
1221 host_->Send(new InputMsg_Replace(host_->GetRoutingID(), base::string16()));
1222 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1225 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplaceMisspelling) {
1226 host_->SetupForInputRouterTest();
1227 host_->Send(new InputMsg_ReplaceMisspelling(host_->GetRoutingID(),
1229 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1232 TEST_F(RenderWidgetHostTest, IgnoreInputEvent) {
1233 host_->SetupForInputRouterTest();
1235 host_->SetIgnoreInputEvents(true);
1237 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1238 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1240 SimulateMouseEvent(WebInputEvent::MouseMove);
1241 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1243 SimulateWheelEvent(0, 100, 0, true);
1244 EXPECT_FALSE(host_->mock_input_router()->sent_wheel_event_);
1246 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1247 blink::WebGestureDeviceTouchpad);
1248 EXPECT_FALSE(host_->mock_input_router()->sent_gesture_event_);
1250 PressTouchPoint(100, 100);
1252 EXPECT_FALSE(host_->mock_input_router()->send_touch_event_not_cancelled_);
1255 TEST_F(RenderWidgetHostTest, KeyboardListenerIgnoresEvent) {
1256 host_->SetupForInputRouterTest();
1257 host_->AddKeyPressEventCallback(
1258 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1259 base::Unretained(this)));
1260 handle_key_press_event_ = false;
1261 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1263 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1266 TEST_F(RenderWidgetHostTest, KeyboardListenerSuppressFollowingEvents) {
1267 host_->SetupForInputRouterTest();
1269 host_->AddKeyPressEventCallback(
1270 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1271 base::Unretained(this)));
1273 // The callback handles the first event
1274 handle_key_press_event_ = true;
1275 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1277 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1279 // Following Char events should be suppressed
1280 handle_key_press_event_ = false;
1281 SimulateKeyboardEvent(WebInputEvent::Char);
1282 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1283 SimulateKeyboardEvent(WebInputEvent::Char);
1284 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1286 // Sending RawKeyDown event should stop suppression
1287 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1288 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1290 host_->mock_input_router()->sent_keyboard_event_ = false;
1291 SimulateKeyboardEvent(WebInputEvent::Char);
1292 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1295 TEST_F(RenderWidgetHostTest, MouseEventCallbackCanHandleEvent) {
1296 host_->SetupForInputRouterTest();
1298 host_->AddMouseEventCallback(
1299 base::Bind(&RenderWidgetHostTest::MouseEventCallback,
1300 base::Unretained(this)));
1302 handle_mouse_event_ = true;
1303 SimulateMouseEvent(WebInputEvent::MouseDown);
1305 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1307 handle_mouse_event_ = false;
1308 SimulateMouseEvent(WebInputEvent::MouseDown);
1310 EXPECT_TRUE(host_->mock_input_router()->sent_mouse_event_);
1313 TEST_F(RenderWidgetHostTest, InputRouterReceivesHandleInputEvent_ACK) {
1314 host_->SetupForInputRouterTest();
1316 SendInputEventACK(WebInputEvent::RawKeyDown,
1317 INPUT_EVENT_ACK_STATE_CONSUMED);
1319 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1322 TEST_F(RenderWidgetHostTest, InputRouterReceivesMoveCaret_ACK) {
1323 host_->SetupForInputRouterTest();
1325 host_->OnMessageReceived(ViewHostMsg_MoveCaret_ACK(0));
1327 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1330 TEST_F(RenderWidgetHostTest, InputRouterReceivesSelectRange_ACK) {
1331 host_->SetupForInputRouterTest();
1333 host_->OnMessageReceived(ViewHostMsg_SelectRange_ACK(0));
1335 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1338 TEST_F(RenderWidgetHostTest, InputRouterReceivesHasTouchEventHandlers) {
1339 host_->SetupForInputRouterTest();
1341 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1343 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1347 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process,
1349 WebInputEvent::Type input_type) {
1350 const IPC::Message* message = process->sink().GetUniqueMessageMatching(
1351 InputMsg_HandleInputEvent::ID);
1352 ASSERT_TRUE(message);
1353 InputMsg_HandleInputEvent::Param params;
1354 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, ¶ms));
1355 ui::LatencyInfo latency_info = params.b;
1356 EXPECT_TRUE(latency_info.FindLatency(
1357 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
1360 process->sink().ClearMessages();
1363 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1364 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1365 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1366 // event's LatencyInfo.
1367 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
1368 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1369 process_->sink().ClearMessages();
1371 // Tests RWHI::ForwardWheelEvent().
1372 SimulateWheelEvent(-5, 0, 0, true);
1373 CheckLatencyInfoComponentInMessage(
1374 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1375 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1377 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1378 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1379 CheckLatencyInfoComponentInMessage(
1380 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1381 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1383 // Tests RWHI::ForwardMouseEvent().
1384 SimulateMouseEvent(WebInputEvent::MouseMove);
1385 CheckLatencyInfoComponentInMessage(
1386 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1387 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1389 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1390 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove,
1392 CheckLatencyInfoComponentInMessage(
1393 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1394 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1396 // Tests RWHI::ForwardGestureEvent().
1397 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1398 blink::WebGestureDeviceTouchscreen);
1399 CheckLatencyInfoComponentInMessage(
1400 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin);
1402 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1403 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate,
1404 blink::WebGestureDeviceTouchscreen,
1406 CheckLatencyInfoComponentInMessage(
1407 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate);
1408 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1409 INPUT_EVENT_ACK_STATE_CONSUMED);
1411 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1412 PressTouchPoint(0, 1);
1414 CheckLatencyInfoComponentInMessage(
1415 process_, GetLatencyComponentId(), WebInputEvent::TouchStart);
1416 SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
1419 } // namespace content