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/gpu/compositor_util.h"
13 #include "content/browser/renderer_host/input/input_router_impl.h"
14 #include "content/browser/renderer_host/render_widget_host_delegate.h"
15 #include "content/browser/renderer_host/render_widget_host_view_base.h"
16 #include "content/common/input/synthetic_web_input_event_builders.h"
17 #include "content/common/input_messages.h"
18 #include "content/common/view_messages.h"
19 #include "content/public/common/content_switches.h"
20 #include "content/public/test/mock_render_process_host.h"
21 #include "content/public/test/test_browser_context.h"
22 #include "content/test/test_render_view_host.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/events/keycodes/keyboard_codes.h"
25 #include "ui/gfx/canvas.h"
26 #include "ui/gfx/screen.h"
28 #if defined(OS_ANDROID)
29 #include "content/browser/renderer_host/render_widget_host_view_android.h"
32 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
33 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
37 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
38 #include "content/browser/renderer_host/ui_events_helper.h"
39 #include "ui/aura/env.h"
40 #include "ui/aura/test/test_screen.h"
41 #include "ui/events/event.h"
44 using base::TimeDelta;
45 using blink::WebGestureDevice;
46 using blink::WebGestureEvent;
47 using blink::WebInputEvent;
48 using blink::WebKeyboardEvent;
49 using blink::WebMouseEvent;
50 using blink::WebMouseWheelEvent;
51 using blink::WebTouchEvent;
52 using blink::WebTouchPoint;
56 // MockInputRouter -------------------------------------------------------------
58 class MockInputRouter : public InputRouter {
60 explicit MockInputRouter(InputRouterClient* client)
61 : send_event_called_(false),
62 sent_mouse_event_(false),
63 sent_wheel_event_(false),
64 sent_keyboard_event_(false),
65 sent_gesture_event_(false),
66 send_touch_event_not_cancelled_(false),
67 message_received_(false),
70 ~MockInputRouter() override {}
73 void Flush() override { flush_called_ = true; }
74 bool SendInput(scoped_ptr<IPC::Message> message) override {
75 send_event_called_ = true;
78 void SendMouseEvent(const MouseEventWithLatencyInfo& mouse_event) override {
79 sent_mouse_event_ = true;
82 const MouseWheelEventWithLatencyInfo& wheel_event) override {
83 sent_wheel_event_ = true;
85 void SendKeyboardEvent(const NativeWebKeyboardEvent& key_event,
86 const ui::LatencyInfo& latency_info,
87 bool is_shortcut) override {
88 sent_keyboard_event_ = true;
90 void SendGestureEvent(
91 const GestureEventWithLatencyInfo& gesture_event) override {
92 sent_gesture_event_ = true;
94 void SendTouchEvent(const TouchEventWithLatencyInfo& touch_event) override {
95 send_touch_event_not_cancelled_ =
96 client_->FilterInputEvent(touch_event.event, touch_event.latency) ==
97 INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
99 const NativeWebKeyboardEvent* GetLastKeyboardEvent() const override {
103 bool ShouldForwardTouchEvent() const override { return true; }
104 void OnViewUpdated(int view_flags) override {}
105 bool HasPendingEvents() const override { return false; }
108 bool OnMessageReceived(const IPC::Message& message) override {
109 message_received_ = true;
114 bool send_event_called_;
115 bool sent_mouse_event_;
116 bool sent_wheel_event_;
117 bool sent_keyboard_event_;
118 bool sent_gesture_event_;
119 bool send_touch_event_not_cancelled_;
120 bool message_received_;
123 InputRouterClient* client_;
125 DISALLOW_COPY_AND_ASSIGN(MockInputRouter);
128 // MockRenderWidgetHost ----------------------------------------------------
130 class MockRenderWidgetHost : public RenderWidgetHostImpl {
132 MockRenderWidgetHost(
133 RenderWidgetHostDelegate* delegate,
134 RenderProcessHost* process,
136 : RenderWidgetHostImpl(delegate, process, routing_id, false),
137 unresponsive_timer_fired_(false) {
138 acked_touch_event_type_ = blink::WebInputEvent::Undefined;
141 // Allow poking at a few private members.
142 using RenderWidgetHostImpl::OnUpdateRect;
143 using RenderWidgetHostImpl::RendererExited;
144 using RenderWidgetHostImpl::last_requested_size_;
145 using RenderWidgetHostImpl::is_hidden_;
146 using RenderWidgetHostImpl::resize_ack_pending_;
147 using RenderWidgetHostImpl::input_router_;
149 void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
150 InputEventAckState ack_result) override {
152 acked_touch_event_type_ = event.event.type;
153 RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
156 bool unresponsive_timer_fired() const {
157 return unresponsive_timer_fired_;
160 void set_hung_renderer_delay_ms(int64 delay_ms) {
161 hung_renderer_delay_ms_ = delay_ms;
164 void DisableGestureDebounce() {
165 input_router_.reset(new InputRouterImpl(
166 process_, this, this, routing_id_, InputRouterImpl::Config()));
169 WebInputEvent::Type acked_touch_event_type() const {
170 return acked_touch_event_type_;
173 void SetupForInputRouterTest() {
174 input_router_.reset(new MockInputRouter(this));
177 MockInputRouter* mock_input_router() {
178 return static_cast<MockInputRouter*>(input_router_.get());
182 void NotifyRendererUnresponsive() override {
183 unresponsive_timer_fired_ = true;
186 bool unresponsive_timer_fired_;
187 WebInputEvent::Type acked_touch_event_type_;
189 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
194 // RenderWidgetHostProcess -----------------------------------------------------
196 class RenderWidgetHostProcess : public MockRenderProcessHost {
198 explicit RenderWidgetHostProcess(BrowserContext* browser_context)
199 : MockRenderProcessHost(browser_context),
200 update_msg_reply_flags_(0) {
202 ~RenderWidgetHostProcess() override {}
204 void set_update_msg_reply_flags(int flags) {
205 update_msg_reply_flags_ = flags;
208 // Fills the given update parameters with resonable default values.
209 void InitUpdateRectParams(ViewHostMsg_UpdateRect_Params* params);
211 bool HasConnection() const override { return true; }
214 // Indicates the flags that should be sent with a repaint request. This
215 // only has an effect when update_msg_should_reply_ is true.
216 int update_msg_reply_flags_;
218 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess);
221 void RenderWidgetHostProcess::InitUpdateRectParams(
222 ViewHostMsg_UpdateRect_Params* params) {
223 const int w = 100, h = 100;
225 params->view_size = gfx::Size(w, h);
226 params->flags = update_msg_reply_flags_;
229 // TestView --------------------------------------------------------------------
231 // This test view allows us to specify the size, and keep track of acked
233 class TestView : public TestRenderWidgetHostView {
235 explicit TestView(RenderWidgetHostImpl* rwh)
236 : TestRenderWidgetHostView(rwh),
237 unhandled_wheel_event_count_(0),
238 acked_event_count_(0),
239 gesture_event_type_(-1),
240 use_fake_physical_backing_size_(false),
241 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
244 // Sets the bounds returned by GetViewBounds.
245 void set_bounds(const gfx::Rect& bounds) {
249 const WebTouchEvent& acked_event() const { return acked_event_; }
250 int acked_event_count() const { return acked_event_count_; }
251 void ClearAckedEvent() {
252 acked_event_.type = blink::WebInputEvent::Undefined;
253 acked_event_count_ = 0;
256 const WebMouseWheelEvent& unhandled_wheel_event() const {
257 return unhandled_wheel_event_;
259 int unhandled_wheel_event_count() const {
260 return unhandled_wheel_event_count_;
262 int gesture_event_type() const { return gesture_event_type_; }
263 InputEventAckState ack_result() const { return ack_result_; }
265 void SetMockPhysicalBackingSize(const gfx::Size& mock_physical_backing_size) {
266 use_fake_physical_backing_size_ = true;
267 mock_physical_backing_size_ = mock_physical_backing_size;
269 void ClearMockPhysicalBackingSize() {
270 use_fake_physical_backing_size_ = false;
273 // RenderWidgetHostView override.
274 gfx::Rect GetViewBounds() const override { return bounds_; }
275 void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
276 InputEventAckState ack_result) override {
277 acked_event_ = touch.event;
278 ++acked_event_count_;
280 void WheelEventAck(const WebMouseWheelEvent& event,
281 InputEventAckState ack_result) override {
282 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
284 unhandled_wheel_event_count_++;
285 unhandled_wheel_event_ = event;
287 void GestureEventAck(const WebGestureEvent& event,
288 InputEventAckState ack_result) override {
289 gesture_event_type_ = event.type;
290 ack_result_ = ack_result;
292 gfx::Size GetPhysicalBackingSize() const override {
293 if (use_fake_physical_backing_size_)
294 return mock_physical_backing_size_;
295 return TestRenderWidgetHostView::GetPhysicalBackingSize();
297 #if defined(USE_AURA)
298 ~TestView() override {
299 // Simulate the mouse exit event dispatched when an aura window is
300 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
301 // into WebInputEvent::MouseMove.)
302 rwh_->input_router()->SendMouseEvent(
303 MouseEventWithLatencyInfo(
304 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove),
310 WebMouseWheelEvent unhandled_wheel_event_;
311 int unhandled_wheel_event_count_;
312 WebTouchEvent acked_event_;
313 int acked_event_count_;
314 int gesture_event_type_;
316 bool use_fake_physical_backing_size_;
317 gfx::Size mock_physical_backing_size_;
318 InputEventAckState ack_result_;
320 DISALLOW_COPY_AND_ASSIGN(TestView);
323 // MockRenderWidgetHostDelegate --------------------------------------------
325 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
327 MockRenderWidgetHostDelegate()
328 : prehandle_keyboard_event_(false),
329 prehandle_keyboard_event_called_(false),
330 prehandle_keyboard_event_type_(WebInputEvent::Undefined),
331 unhandled_keyboard_event_called_(false),
332 unhandled_keyboard_event_type_(WebInputEvent::Undefined),
333 handle_wheel_event_(false),
334 handle_wheel_event_called_(false) {
336 ~MockRenderWidgetHostDelegate() override {}
338 // Tests that make sure we ignore keyboard event acknowledgments to events we
339 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
340 bool unhandled_keyboard_event_called() const {
341 return unhandled_keyboard_event_called_;
344 WebInputEvent::Type unhandled_keyboard_event_type() const {
345 return unhandled_keyboard_event_type_;
348 bool prehandle_keyboard_event_called() const {
349 return prehandle_keyboard_event_called_;
352 WebInputEvent::Type prehandle_keyboard_event_type() const {
353 return prehandle_keyboard_event_type_;
356 void set_prehandle_keyboard_event(bool handle) {
357 prehandle_keyboard_event_ = handle;
360 void set_handle_wheel_event(bool handle) {
361 handle_wheel_event_ = handle;
364 bool handle_wheel_event_called() {
365 return handle_wheel_event_called_;
369 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
370 bool* is_keyboard_shortcut) override {
371 prehandle_keyboard_event_type_ = event.type;
372 prehandle_keyboard_event_called_ = true;
373 return prehandle_keyboard_event_;
376 void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override {
377 unhandled_keyboard_event_type_ = event.type;
378 unhandled_keyboard_event_called_ = true;
381 bool HandleWheelEvent(const blink::WebMouseWheelEvent& event) override {
382 handle_wheel_event_called_ = true;
383 return handle_wheel_event_;
387 bool prehandle_keyboard_event_;
388 bool prehandle_keyboard_event_called_;
389 WebInputEvent::Type prehandle_keyboard_event_type_;
391 bool unhandled_keyboard_event_called_;
392 WebInputEvent::Type unhandled_keyboard_event_type_;
394 bool handle_wheel_event_;
395 bool handle_wheel_event_called_;
398 // RenderWidgetHostTest --------------------------------------------------------
400 class RenderWidgetHostTest : public testing::Test {
402 RenderWidgetHostTest()
404 handle_key_press_event_(false),
405 handle_mouse_event_(false),
406 simulated_event_time_delta_seconds_(0) {
407 last_simulated_event_time_seconds_ =
408 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
410 ~RenderWidgetHostTest() override {}
412 bool KeyPressEventCallback(const NativeWebKeyboardEvent& /* event */) {
413 return handle_key_press_event_;
415 bool MouseEventCallback(const blink::WebMouseEvent& /* event */) {
416 return handle_mouse_event_;
421 void SetUp() override {
422 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
423 command_line->AppendSwitch(switches::kValidateInputEventStream);
425 browser_context_.reset(new TestBrowserContext());
426 delegate_.reset(new MockRenderWidgetHostDelegate());
427 process_ = new RenderWidgetHostProcess(browser_context_.get());
428 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
429 if (IsDelegatedRendererEnabled()) {
430 ImageTransportFactory::InitializeForUnitTests(
431 scoped_ptr<ImageTransportFactory>(
432 new NoTransportImageTransportFactory));
435 #if defined(USE_AURA)
436 aura::Env::CreateInstance(true);
437 screen_.reset(aura::TestScreen::Create(gfx::Size()));
438 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
441 new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
442 view_.reset(new TestView(host_.get()));
443 host_->SetView(view_.get());
445 host_->DisableGestureDebounce();
447 void TearDown() override {
452 browser_context_.reset();
454 #if defined(USE_AURA)
455 aura::Env::DeleteInstance();
458 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
459 if (IsDelegatedRendererEnabled())
460 ImageTransportFactory::Terminate();
463 // Process all pending tasks to avoid leaks.
464 base::MessageLoop::current()->RunUntilIdle();
467 int64 GetLatencyComponentId() {
468 return host_->GetLatencyComponentId();
471 void SendInputEventACK(WebInputEvent::Type type,
472 InputEventAckState ack_result) {
473 InputHostMsg_HandleInputEvent_ACK_Params ack;
475 ack.state = ack_result;
476 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
479 double GetNextSimulatedEventTimeSeconds() {
480 last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_;
481 return last_simulated_event_time_seconds_;
484 void SimulateKeyboardEvent(WebInputEvent::Type type) {
485 SimulateKeyboardEvent(type, 0);
488 void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) {
489 WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
490 event.modifiers = modifiers;
491 NativeWebKeyboardEvent native_event;
492 memcpy(&native_event, &event, sizeof(event));
493 host_->ForwardKeyboardEvent(native_event);
496 void SimulateMouseEvent(WebInputEvent::Type type) {
497 host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type));
500 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type,
501 const ui::LatencyInfo& ui_latency) {
502 host_->ForwardMouseEventWithLatencyInfo(
503 SyntheticWebMouseEventBuilder::Build(type),
507 void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
508 host_->ForwardWheelEvent(
509 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
512 void SimulateWheelEventWithLatencyInfo(float dX,
516 const ui::LatencyInfo& ui_latency) {
517 host_->ForwardWheelEventWithLatencyInfo(
518 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
522 void SimulateMouseMove(int x, int y, int modifiers) {
523 SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false);
526 void SimulateMouseEvent(
527 WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) {
528 WebMouseEvent event =
529 SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers);
531 event.button = WebMouseEvent::ButtonLeft;
532 event.timeStampSeconds = GetNextSimulatedEventTimeSeconds();
533 host_->ForwardMouseEvent(event);
536 // Inject simple synthetic WebGestureEvent instances.
537 void SimulateGestureEvent(WebInputEvent::Type type,
538 WebGestureDevice sourceDevice) {
539 host_->ForwardGestureEvent(
540 SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
543 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type,
544 WebGestureDevice sourceDevice,
545 const ui::LatencyInfo& ui_latency) {
546 host_->ForwardGestureEventWithLatencyInfo(
547 SyntheticWebGestureEventBuilder::Build(type, sourceDevice),
551 // Set the timestamp for the touch-event.
552 void SetTouchTimestamp(base::TimeDelta timestamp) {
553 touch_event_.SetTimestamp(timestamp);
556 // Sends a touch event (irrespective of whether the page has a touch-event
558 void SendTouchEvent() {
559 host_->ForwardTouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo());
561 touch_event_.ResetPoints();
564 int PressTouchPoint(int x, int y) {
565 return touch_event_.PressPoint(x, y);
568 void MoveTouchPoint(int index, int x, int y) {
569 touch_event_.MovePoint(index, x, y);
572 void ReleaseTouchPoint(int index) {
573 touch_event_.ReleasePoint(index);
576 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
577 PickleIterator iter(message);
580 if (!message.ReadData(&iter, &data, &data_length))
582 return reinterpret_cast<const WebInputEvent*>(data);
585 base::MessageLoopForUI message_loop_;
587 scoped_ptr<TestBrowserContext> browser_context_;
588 RenderWidgetHostProcess* process_; // Deleted automatically by the widget.
589 scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
590 scoped_ptr<MockRenderWidgetHost> host_;
591 scoped_ptr<TestView> view_;
592 scoped_ptr<gfx::Screen> screen_;
593 bool handle_key_press_event_;
594 bool handle_mouse_event_;
595 double last_simulated_event_time_seconds_;
596 double simulated_event_time_delta_seconds_;
599 SyntheticWebTouchEvent touch_event_;
601 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest);
604 #if GTEST_HAS_PARAM_TEST
605 // RenderWidgetHostWithSourceTest ----------------------------------------------
607 // This is for tests that are to be run for all source devices.
608 class RenderWidgetHostWithSourceTest
609 : public RenderWidgetHostTest,
610 public testing::WithParamInterface<WebGestureDevice> {};
611 #endif // GTEST_HAS_PARAM_TEST
615 // -----------------------------------------------------------------------------
617 TEST_F(RenderWidgetHostTest, Resize) {
618 // The initial bounds is the empty rect, and the screen info hasn't been sent
619 // yet, so setting it to the same thing shouldn't send the resize message.
620 view_->set_bounds(gfx::Rect());
622 EXPECT_FALSE(host_->resize_ack_pending_);
623 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
625 // Setting the bounds to a "real" rect should send out the notification.
626 // but should not expect ack for empty physical backing size.
627 gfx::Rect original_size(0, 0, 100, 100);
628 process_->sink().ClearMessages();
629 view_->set_bounds(original_size);
630 view_->SetMockPhysicalBackingSize(gfx::Size());
632 EXPECT_FALSE(host_->resize_ack_pending_);
633 EXPECT_EQ(original_size.size(), host_->last_requested_size_);
634 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
636 // Setting the bounds to a "real" rect should send out the notification.
637 // but should not expect ack for only physical backing size change.
638 process_->sink().ClearMessages();
639 view_->ClearMockPhysicalBackingSize();
641 EXPECT_FALSE(host_->resize_ack_pending_);
642 EXPECT_EQ(original_size.size(), host_->last_requested_size_);
643 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
645 // Send out a update that's not a resize ack after setting resize ack pending
646 // flag. This should not clean the resize ack pending flag.
647 process_->sink().ClearMessages();
648 gfx::Rect second_size(0, 0, 110, 110);
649 EXPECT_FALSE(host_->resize_ack_pending_);
650 view_->set_bounds(second_size);
652 EXPECT_TRUE(host_->resize_ack_pending_);
653 ViewHostMsg_UpdateRect_Params params;
654 process_->InitUpdateRectParams(¶ms);
655 host_->OnUpdateRect(params);
656 EXPECT_TRUE(host_->resize_ack_pending_);
657 EXPECT_EQ(second_size.size(), host_->last_requested_size_);
659 // Sending out a new notification should NOT send out a new IPC message since
660 // a resize ACK is pending.
661 gfx::Rect third_size(0, 0, 120, 120);
662 process_->sink().ClearMessages();
663 view_->set_bounds(third_size);
665 EXPECT_TRUE(host_->resize_ack_pending_);
666 EXPECT_EQ(second_size.size(), host_->last_requested_size_);
667 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
669 // Send a update that's a resize ack, but for the original_size we sent. Since
670 // this isn't the second_size, the message handler should immediately send
671 // a new resize message for the new size to the renderer.
672 process_->sink().ClearMessages();
673 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
674 params.view_size = original_size.size();
675 host_->OnUpdateRect(params);
676 EXPECT_TRUE(host_->resize_ack_pending_);
677 EXPECT_EQ(third_size.size(), host_->last_requested_size_);
678 ASSERT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
680 // Send the resize ack for the latest size.
681 process_->sink().ClearMessages();
682 params.view_size = third_size.size();
683 host_->OnUpdateRect(params);
684 EXPECT_FALSE(host_->resize_ack_pending_);
685 EXPECT_EQ(third_size.size(), host_->last_requested_size_);
686 ASSERT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
688 // Now clearing the bounds should send out a notification but we shouldn't
689 // expect a resize ack (since the renderer won't ack empty sizes). The message
690 // should contain the new size (0x0) and not the previous one that we skipped
691 process_->sink().ClearMessages();
692 view_->set_bounds(gfx::Rect());
694 EXPECT_FALSE(host_->resize_ack_pending_);
695 EXPECT_EQ(gfx::Size(), host_->last_requested_size_);
696 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
698 // Send a rect that has no area but has either width or height set.
699 process_->sink().ClearMessages();
700 view_->set_bounds(gfx::Rect(0, 0, 0, 30));
702 EXPECT_FALSE(host_->resize_ack_pending_);
703 EXPECT_EQ(gfx::Size(0, 30), host_->last_requested_size_);
704 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
706 // Set the same size again. It should not be sent again.
707 process_->sink().ClearMessages();
709 EXPECT_FALSE(host_->resize_ack_pending_);
710 EXPECT_EQ(gfx::Size(0, 30), host_->last_requested_size_);
711 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
713 // A different size should be sent again, however.
714 view_->set_bounds(gfx::Rect(0, 0, 0, 31));
716 EXPECT_FALSE(host_->resize_ack_pending_);
717 EXPECT_EQ(gfx::Size(0, 31), host_->last_requested_size_);
718 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
721 // Test for crbug.com/25097. If a renderer crashes between a resize and the
722 // corresponding update message, we must be sure to clear the resize ack logic.
723 TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
724 // Clear the first Resize message that carried screen info.
725 process_->sink().ClearMessages();
727 // Setting the bounds to a "real" rect should send out the notification.
728 gfx::Rect original_size(0, 0, 100, 100);
729 view_->set_bounds(original_size);
731 EXPECT_TRUE(host_->resize_ack_pending_);
732 EXPECT_EQ(original_size.size(), host_->last_requested_size_);
733 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
735 // Simulate a renderer crash before the update message. Ensure all the
736 // resize ack logic is cleared. Must clear the view first so it doesn't get
738 host_->SetView(NULL);
739 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
740 EXPECT_FALSE(host_->resize_ack_pending_);
741 EXPECT_EQ(gfx::Size(), host_->last_requested_size_);
743 // Reset the view so we can exit the test cleanly.
744 host_->SetView(view_.get());
747 // Unable to include render_widget_host_view_mac.h and compile.
748 #if !defined(OS_MACOSX)
749 // Tests setting background transparency.
750 TEST_F(RenderWidgetHostTest, Background) {
751 scoped_ptr<RenderWidgetHostViewBase> view;
752 #if defined(USE_AURA)
753 view.reset(new RenderWidgetHostViewAura(host_.get(), false));
754 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
755 view->InitAsChild(NULL);
756 #elif defined(OS_ANDROID)
757 view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
759 host_->SetView(view.get());
761 EXPECT_TRUE(view->GetBackgroundOpaque());
762 view->SetBackgroundColor(SK_ColorTRANSPARENT);
763 EXPECT_FALSE(view->GetBackgroundOpaque());
765 const IPC::Message* set_background =
766 process_->sink().GetUniqueMessageMatching(
767 ViewMsg_SetBackgroundOpaque::ID);
768 ASSERT_TRUE(set_background);
769 Tuple1<bool> sent_background;
770 ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
771 EXPECT_FALSE(sent_background.a);
773 #if defined(USE_AURA)
774 // See the comment above |InitAsChild(NULL)|.
775 host_->SetView(NULL);
776 static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
781 // Test that we don't paint when we're hidden, but we still send the ACK. Most
782 // of the rest of the painting is tested in the GetBackingStore* ones.
783 TEST_F(RenderWidgetHostTest, HiddenPaint) {
784 BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
785 // Hide the widget, it should have sent out a message to the renderer.
786 EXPECT_FALSE(host_->is_hidden_);
788 EXPECT_TRUE(host_->is_hidden_);
789 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID));
791 // Send it an update as from the renderer.
792 process_->sink().ClearMessages();
793 ViewHostMsg_UpdateRect_Params params;
794 process_->InitUpdateRectParams(¶ms);
795 host_->OnUpdateRect(params);
798 process_->sink().ClearMessages();
799 host_->WasShown(ui::LatencyInfo());
800 EXPECT_FALSE(host_->is_hidden_);
802 // It should have sent out a restored message with a request to paint.
803 const IPC::Message* restored = process_->sink().GetUniqueMessageMatching(
804 ViewMsg_WasShown::ID);
805 ASSERT_TRUE(restored);
806 Tuple2<bool, ui::LatencyInfo> needs_repaint;
807 ViewMsg_WasShown::Read(restored, &needs_repaint);
808 EXPECT_TRUE(needs_repaint.a);
811 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
812 // Simulate a keyboard event.
813 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
815 // Make sure we sent the input event to the renderer.
816 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
817 InputMsg_HandleInputEvent::ID));
818 process_->sink().ClearMessages();
820 // Send the simulated response from the renderer back.
821 SendInputEventACK(WebInputEvent::RawKeyDown,
822 INPUT_EVENT_ACK_STATE_CONSUMED);
823 EXPECT_FALSE(delegate_->unhandled_keyboard_event_called());
826 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
827 // Simluate the situation that the browser handled the key down event during
828 // pre-handle phrase.
829 delegate_->set_prehandle_keyboard_event(true);
830 process_->sink().ClearMessages();
832 // Simulate a keyboard event.
833 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
835 EXPECT_TRUE(delegate_->prehandle_keyboard_event_called());
836 EXPECT_EQ(WebInputEvent::RawKeyDown,
837 delegate_->prehandle_keyboard_event_type());
839 // Make sure the RawKeyDown event is not sent to the renderer.
840 EXPECT_EQ(0U, process_->sink().message_count());
842 // The browser won't pre-handle a Char event.
843 delegate_->set_prehandle_keyboard_event(false);
845 // Forward the Char event.
846 SimulateKeyboardEvent(WebInputEvent::Char);
848 // Make sure the Char event is suppressed.
849 EXPECT_EQ(0U, process_->sink().message_count());
851 // Forward the KeyUp event.
852 SimulateKeyboardEvent(WebInputEvent::KeyUp);
854 // Make sure only KeyUp was sent to the renderer.
855 EXPECT_EQ(1U, process_->sink().message_count());
856 EXPECT_EQ(InputMsg_HandleInputEvent::ID,
857 process_->sink().GetMessageAt(0)->type());
858 process_->sink().ClearMessages();
860 // Send the simulated response from the renderer back.
861 SendInputEventACK(WebInputEvent::KeyUp,
862 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
864 EXPECT_TRUE(delegate_->unhandled_keyboard_event_called());
865 EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type());
868 TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
869 SimulateWheelEvent(-5, 0, 0, true);
871 // Make sure we sent the input event to the renderer.
872 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
873 InputMsg_HandleInputEvent::ID));
874 process_->sink().ClearMessages();
876 // Send the simulated response from the renderer back.
877 SendInputEventACK(WebInputEvent::MouseWheel,
878 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
879 EXPECT_TRUE(delegate_->handle_wheel_event_called());
880 EXPECT_EQ(1, view_->unhandled_wheel_event_count());
881 EXPECT_EQ(-5, view_->unhandled_wheel_event().deltaX);
884 TEST_F(RenderWidgetHostTest, HandleWheelEvent) {
885 // Indicate that we're going to handle this wheel event
886 delegate_->set_handle_wheel_event(true);
888 SimulateWheelEvent(-5, 0, 0, true);
890 // Make sure we sent the input event to the renderer.
891 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
892 InputMsg_HandleInputEvent::ID));
893 process_->sink().ClearMessages();
895 // Send the simulated response from the renderer back.
896 SendInputEventACK(WebInputEvent::MouseWheel,
897 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
899 // ensure the wheel event handler was invoked
900 EXPECT_TRUE(delegate_->handle_wheel_event_called());
902 // and that it suppressed the unhandled wheel event handler.
903 EXPECT_EQ(0, view_->unhandled_wheel_event_count());
906 TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
907 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap,
908 blink::WebGestureDeviceTouchscreen);
910 // Make sure we sent the input event to the renderer.
911 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
912 InputMsg_HandleInputEvent::ID));
913 process_->sink().ClearMessages();
915 // Send the simulated response from the renderer back.
916 SendInputEventACK(WebInputEvent::GestureTwoFingerTap,
917 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
918 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap, view_->gesture_event_type());
919 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, view_->ack_result());
922 // Test that the hang monitor timer expires properly if a new timer is started
923 // while one is in progress (see crbug.com/11007).
924 TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) {
925 // Start with a short timeout.
926 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
928 // Immediately try to add a long 30 second timeout.
929 EXPECT_FALSE(host_->unresponsive_timer_fired());
930 host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
932 // Wait long enough for first timeout and see if it fired.
933 base::MessageLoop::current()->PostDelayedTask(
935 base::MessageLoop::QuitClosure(),
936 TimeDelta::FromMilliseconds(10));
937 base::MessageLoop::current()->Run();
938 EXPECT_TRUE(host_->unresponsive_timer_fired());
941 // Test that the hang monitor timer expires properly if it is started, stopped,
942 // and then started again.
943 TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
944 // Start with a short timeout, then stop it.
945 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
946 host_->StopHangMonitorTimeout();
948 // Start it again to ensure it still works.
949 EXPECT_FALSE(host_->unresponsive_timer_fired());
950 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
952 // Wait long enough for first timeout and see if it fired.
953 base::MessageLoop::current()->PostDelayedTask(
955 base::MessageLoop::QuitClosure(),
956 TimeDelta::FromMilliseconds(40));
957 base::MessageLoop::current()->Run();
958 EXPECT_TRUE(host_->unresponsive_timer_fired());
961 // Test that the hang monitor timer expires properly if it is started, then
962 // updated to a shorter duration.
963 TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) {
964 // Start with a timeout.
965 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
967 // Start it again with shorter delay.
968 EXPECT_FALSE(host_->unresponsive_timer_fired());
969 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
971 // Wait long enough for the second timeout and see if it fired.
972 base::MessageLoop::current()->PostDelayedTask(
974 base::MessageLoop::QuitClosure(),
975 TimeDelta::FromMilliseconds(25));
976 base::MessageLoop::current()->Run();
977 EXPECT_TRUE(host_->unresponsive_timer_fired());
980 // Test that the hang monitor catches two input events but only one ack.
981 // This can happen if the second input event causes the renderer to hang.
982 // This test will catch a regression of crbug.com/111185.
983 TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
984 // Configure the host to wait 10ms before considering
985 // the renderer hung.
986 host_->set_hung_renderer_delay_ms(10);
988 // Send two events but only one ack.
989 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
990 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
991 SendInputEventACK(WebInputEvent::RawKeyDown,
992 INPUT_EVENT_ACK_STATE_CONSUMED);
994 // Wait long enough for first timeout and see if it fired.
995 base::MessageLoop::current()->PostDelayedTask(
997 base::MessageLoop::QuitClosure(),
998 TimeDelta::FromMilliseconds(40));
999 base::MessageLoop::current()->Run();
1000 EXPECT_TRUE(host_->unresponsive_timer_fired());
1003 std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
1005 for (size_t i = 0; i < process->sink().message_count(); ++i) {
1006 const IPC::Message *message = process->sink().GetMessageAt(i);
1007 EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
1008 InputMsg_HandleInputEvent::Param params;
1009 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, ¶ms));
1010 const WebInputEvent* event = params.a;
1013 result += WebInputEventTraits::GetName(event->type);
1015 process->sink().ClearMessages();
1019 TEST_F(RenderWidgetHostTest, TouchEmulator) {
1020 simulated_event_time_delta_seconds_ = 0.1;
1021 // Immediately ack all touches instead of sending them to the renderer.
1022 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1023 host_->SetTouchEventEmulationEnabled(true);
1024 process_->sink().ClearMessages();
1025 view_->set_bounds(gfx::Rect(0, 0, 400, 200));
1028 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1029 EXPECT_EQ(0U, process_->sink().message_count());
1031 // Mouse press becomes touch start which in turn becomes tap.
1032 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1033 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1034 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1036 // Mouse drag generates touch move, cancels tap and starts scroll.
1037 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1038 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1040 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1041 GetInputMessageTypes(process_));
1042 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1043 INPUT_EVENT_ACK_STATE_CONSUMED);
1044 EXPECT_EQ(0U, process_->sink().message_count());
1046 // Mouse drag with shift becomes pinch.
1048 WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true);
1049 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1050 EXPECT_EQ("GesturePinchBegin",
1051 GetInputMessageTypes(process_));
1052 EXPECT_EQ(0U, process_->sink().message_count());
1055 WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true);
1056 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1057 EXPECT_EQ("GesturePinchUpdate",
1058 GetInputMessageTypes(process_));
1059 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1060 INPUT_EVENT_ACK_STATE_CONSUMED);
1061 EXPECT_EQ(0U, process_->sink().message_count());
1063 // Mouse drag without shift becomes scroll again.
1064 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true);
1065 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1066 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1067 GetInputMessageTypes(process_));
1068 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1069 INPUT_EVENT_ACK_STATE_CONSUMED);
1070 EXPECT_EQ(0U, process_->sink().message_count());
1072 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true);
1073 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1074 EXPECT_EQ("GestureScrollUpdate",
1075 GetInputMessageTypes(process_));
1076 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1077 INPUT_EVENT_ACK_STATE_CONSUMED);
1078 EXPECT_EQ(0U, process_->sink().message_count());
1080 SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true);
1081 EXPECT_EQ(WebInputEvent::TouchEnd, host_->acked_touch_event_type());
1082 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1083 EXPECT_EQ(0U, process_->sink().message_count());
1085 // Mouse move does nothing.
1086 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false);
1087 EXPECT_EQ(0U, process_->sink().message_count());
1089 // Another mouse down continues scroll.
1090 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true);
1091 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1092 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1093 EXPECT_EQ(0U, process_->sink().message_count());
1095 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true);
1096 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1098 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1099 GetInputMessageTypes(process_));
1100 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1101 INPUT_EVENT_ACK_STATE_CONSUMED);
1102 EXPECT_EQ(0U, process_->sink().message_count());
1106 WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true);
1107 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1108 EXPECT_EQ("GesturePinchBegin",
1109 GetInputMessageTypes(process_));
1110 EXPECT_EQ(0U, process_->sink().message_count());
1113 WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true);
1114 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1115 EXPECT_EQ("GesturePinchUpdate",
1116 GetInputMessageTypes(process_));
1117 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1118 INPUT_EVENT_ACK_STATE_CONSUMED);
1119 EXPECT_EQ(0U, process_->sink().message_count());
1121 // Turn off emulation during a pinch.
1122 host_->SetTouchEventEmulationEnabled(false);
1123 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1124 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1125 GetInputMessageTypes(process_));
1126 EXPECT_EQ(0U, process_->sink().message_count());
1128 // Mouse event should pass untouched.
1130 WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true);
1131 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_));
1132 SendInputEventACK(WebInputEvent::MouseMove,
1133 INPUT_EVENT_ACK_STATE_CONSUMED);
1134 EXPECT_EQ(0U, process_->sink().message_count());
1136 // Turn on emulation.
1137 host_->SetTouchEventEmulationEnabled(true);
1138 EXPECT_EQ(0U, process_->sink().message_count());
1141 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1142 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1143 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1144 EXPECT_EQ(0U, process_->sink().message_count());
1147 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1148 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1150 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1151 GetInputMessageTypes(process_));
1152 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1153 INPUT_EVENT_ACK_STATE_CONSUMED);
1155 // Turn off emulation during a scroll.
1156 host_->SetTouchEventEmulationEnabled(false);
1157 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1159 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1160 EXPECT_EQ(0U, process_->sink().message_count());
1163 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1164 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1165 host_->SetupForInputRouterTest(); \
1166 host_->INPUTMSG(); \
1167 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1170 TEST_InputRouterRoutes_NOARGS(Focus);
1171 TEST_InputRouterRoutes_NOARGS(Blur);
1172 TEST_InputRouterRoutes_NOARGS(LostCapture);
1174 #undef TEST_InputRouterRoutes_NOARGS
1176 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1177 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1178 host_->SetupForInputRouterTest(); \
1179 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1180 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1183 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo);
1184 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo);
1185 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut);
1186 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy);
1187 #if defined(OS_MACOSX)
1188 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard);
1190 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste);
1191 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle);
1192 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete);
1193 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll);
1194 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect);
1196 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1198 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplace) {
1199 host_->SetupForInputRouterTest();
1200 host_->Send(new InputMsg_Replace(host_->GetRoutingID(), base::string16()));
1201 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1204 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplaceMisspelling) {
1205 host_->SetupForInputRouterTest();
1206 host_->Send(new InputMsg_ReplaceMisspelling(host_->GetRoutingID(),
1208 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1211 TEST_F(RenderWidgetHostTest, IgnoreInputEvent) {
1212 host_->SetupForInputRouterTest();
1214 host_->SetIgnoreInputEvents(true);
1216 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1217 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1219 SimulateMouseEvent(WebInputEvent::MouseMove);
1220 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1222 SimulateWheelEvent(0, 100, 0, true);
1223 EXPECT_FALSE(host_->mock_input_router()->sent_wheel_event_);
1225 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1226 blink::WebGestureDeviceTouchpad);
1227 EXPECT_FALSE(host_->mock_input_router()->sent_gesture_event_);
1229 PressTouchPoint(100, 100);
1231 EXPECT_FALSE(host_->mock_input_router()->send_touch_event_not_cancelled_);
1234 TEST_F(RenderWidgetHostTest, KeyboardListenerIgnoresEvent) {
1235 host_->SetupForInputRouterTest();
1236 host_->AddKeyPressEventCallback(
1237 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1238 base::Unretained(this)));
1239 handle_key_press_event_ = false;
1240 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1242 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1245 TEST_F(RenderWidgetHostTest, KeyboardListenerSuppressFollowingEvents) {
1246 host_->SetupForInputRouterTest();
1248 host_->AddKeyPressEventCallback(
1249 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1250 base::Unretained(this)));
1252 // The callback handles the first event
1253 handle_key_press_event_ = true;
1254 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1256 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1258 // Following Char events should be suppressed
1259 handle_key_press_event_ = false;
1260 SimulateKeyboardEvent(WebInputEvent::Char);
1261 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1262 SimulateKeyboardEvent(WebInputEvent::Char);
1263 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1265 // Sending RawKeyDown event should stop suppression
1266 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1267 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1269 host_->mock_input_router()->sent_keyboard_event_ = false;
1270 SimulateKeyboardEvent(WebInputEvent::Char);
1271 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1274 TEST_F(RenderWidgetHostTest, MouseEventCallbackCanHandleEvent) {
1275 host_->SetupForInputRouterTest();
1277 host_->AddMouseEventCallback(
1278 base::Bind(&RenderWidgetHostTest::MouseEventCallback,
1279 base::Unretained(this)));
1281 handle_mouse_event_ = true;
1282 SimulateMouseEvent(WebInputEvent::MouseDown);
1284 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1286 handle_mouse_event_ = false;
1287 SimulateMouseEvent(WebInputEvent::MouseDown);
1289 EXPECT_TRUE(host_->mock_input_router()->sent_mouse_event_);
1292 TEST_F(RenderWidgetHostTest, InputRouterReceivesHandleInputEvent_ACK) {
1293 host_->SetupForInputRouterTest();
1295 SendInputEventACK(WebInputEvent::RawKeyDown,
1296 INPUT_EVENT_ACK_STATE_CONSUMED);
1298 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1301 TEST_F(RenderWidgetHostTest, InputRouterReceivesMoveCaret_ACK) {
1302 host_->SetupForInputRouterTest();
1304 host_->OnMessageReceived(InputHostMsg_MoveCaret_ACK(0));
1306 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1309 TEST_F(RenderWidgetHostTest, InputRouterReceivesSelectRange_ACK) {
1310 host_->SetupForInputRouterTest();
1312 host_->OnMessageReceived(InputHostMsg_SelectRange_ACK(0));
1314 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1317 TEST_F(RenderWidgetHostTest, InputRouterReceivesHasTouchEventHandlers) {
1318 host_->SetupForInputRouterTest();
1320 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1322 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1325 ui::LatencyInfo GetLatencyInfoFromInputEvent(RenderWidgetHostProcess* process) {
1326 const IPC::Message* message = process->sink().GetUniqueMessageMatching(
1327 InputMsg_HandleInputEvent::ID);
1328 EXPECT_TRUE(message);
1329 InputMsg_HandleInputEvent::Param params;
1330 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, ¶ms));
1331 process->sink().ClearMessages();
1335 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process,
1337 WebInputEvent::Type input_type) {
1338 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process);
1339 EXPECT_TRUE(latency_info.FindLatency(
1340 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
1345 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1346 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1347 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1348 // event's LatencyInfo.
1349 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
1350 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1351 process_->sink().ClearMessages();
1353 // Tests RWHI::ForwardWheelEvent().
1354 SimulateWheelEvent(-5, 0, 0, true);
1355 CheckLatencyInfoComponentInMessage(
1356 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1357 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1359 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1360 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1361 CheckLatencyInfoComponentInMessage(
1362 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1363 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1365 // Tests RWHI::ForwardMouseEvent().
1366 SimulateMouseEvent(WebInputEvent::MouseMove);
1367 CheckLatencyInfoComponentInMessage(
1368 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1369 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1371 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1372 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove,
1374 CheckLatencyInfoComponentInMessage(
1375 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1376 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1378 // Tests RWHI::ForwardGestureEvent().
1379 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1380 blink::WebGestureDeviceTouchscreen);
1381 CheckLatencyInfoComponentInMessage(
1382 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin);
1384 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1385 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate,
1386 blink::WebGestureDeviceTouchscreen,
1388 CheckLatencyInfoComponentInMessage(
1389 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate);
1390 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1391 INPUT_EVENT_ACK_STATE_CONSUMED);
1393 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1394 PressTouchPoint(0, 1);
1396 CheckLatencyInfoComponentInMessage(
1397 process_, GetLatencyComponentId(), WebInputEvent::TouchStart);
1398 SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
1401 // Tests that after input event passes through RWHI through
1402 // ForwardXXXEventWithLatencyInfo(), input event coordinates will be present in
1403 // the latency info.
1404 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyInfoCoordinates) {
1405 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1406 process_->sink().ClearMessages();
1409 WebMouseWheelEvent event =
1410 SyntheticWebMouseWheelEventBuilder::Build(-5, 0, 0, true);
1413 host_->ForwardWheelEvent(event);
1414 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_);
1415 EXPECT_EQ(1u, latency_info.input_coordinates_size);
1416 EXPECT_EQ(100, latency_info.input_coordinates[0].x);
1417 EXPECT_EQ(200, latency_info.input_coordinates[0].y);
1418 SendInputEventACK(WebInputEvent::MouseWheel,
1419 INPUT_EVENT_ACK_STATE_CONSUMED);
1423 WebMouseEvent event =
1424 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove);
1427 host_->ForwardMouseEvent(event);
1428 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_);
1429 EXPECT_EQ(1u, latency_info.input_coordinates_size);
1430 EXPECT_EQ(300, latency_info.input_coordinates[0].x);
1431 EXPECT_EQ(400, latency_info.input_coordinates[0].y);
1432 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1436 WebGestureEvent event = SyntheticWebGestureEventBuilder::Build(
1437 WebInputEvent::GestureScrollBegin, blink::WebGestureDeviceTouchscreen);
1440 host_->ForwardGestureEvent(event);
1441 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_);
1442 EXPECT_EQ(1u, latency_info.input_coordinates_size);
1443 EXPECT_EQ(500, latency_info.input_coordinates[0].x);
1444 EXPECT_EQ(600, latency_info.input_coordinates[0].y);
1445 SendInputEventACK(WebInputEvent::GestureScrollBegin,
1446 INPUT_EVENT_ACK_STATE_CONSUMED);
1450 PressTouchPoint(700, 800);
1451 PressTouchPoint(900, 1000);
1452 PressTouchPoint(1100, 1200); // LatencyInfo only holds two coordinates.
1454 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_);
1455 EXPECT_EQ(2u, latency_info.input_coordinates_size);
1456 EXPECT_EQ(700, latency_info.input_coordinates[0].x);
1457 EXPECT_EQ(800, latency_info.input_coordinates[0].y);
1458 EXPECT_EQ(900, latency_info.input_coordinates[1].x);
1459 EXPECT_EQ(1000, latency_info.input_coordinates[1].y);
1460 SendInputEventACK(WebInputEvent::TouchStart,
1461 INPUT_EVENT_ACK_STATE_CONSUMED);
1465 NativeWebKeyboardEvent event;
1466 event.type = WebKeyboardEvent::KeyDown;
1467 host_->ForwardKeyboardEvent(event);
1468 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_);
1469 EXPECT_EQ(0u, latency_info.input_coordinates_size);
1470 SendInputEventACK(WebInputEvent::KeyDown, INPUT_EVENT_ACK_STATE_CONSUMED);
1474 TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) {
1475 // RendererExited will delete the view.
1476 host_->SetView(new TestView(host_.get()));
1477 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1479 // Make sure the input router is in a fresh state.
1480 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1483 // Regression test for http://crbug.com/401859.
1484 TEST_F(RenderWidgetHostTest, RendererExitedResetsIsHidden) {
1485 // RendererExited will delete the view.
1486 host_->SetView(new TestView(host_.get()));
1489 ASSERT_TRUE(host_->is_hidden());
1490 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1491 ASSERT_FALSE(host_->is_hidden());
1493 // Make sure the input router is in a fresh state.
1494 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1497 } // namespace content