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 void OnViewUpdated(int view_flags
) override
{}
104 bool HasPendingEvents() const override
{ return false; }
107 bool OnMessageReceived(const IPC::Message
& message
) override
{
108 message_received_
= true;
113 bool send_event_called_
;
114 bool sent_mouse_event_
;
115 bool sent_wheel_event_
;
116 bool sent_keyboard_event_
;
117 bool sent_gesture_event_
;
118 bool send_touch_event_not_cancelled_
;
119 bool message_received_
;
122 InputRouterClient
* client_
;
124 DISALLOW_COPY_AND_ASSIGN(MockInputRouter
);
127 // MockRenderWidgetHost ----------------------------------------------------
129 class MockRenderWidgetHost
: public RenderWidgetHostImpl
{
131 MockRenderWidgetHost(
132 RenderWidgetHostDelegate
* delegate
,
133 RenderProcessHost
* process
,
135 : RenderWidgetHostImpl(delegate
, process
, routing_id
, false),
136 unresponsive_timer_fired_(false) {
137 acked_touch_event_type_
= blink::WebInputEvent::Undefined
;
140 // Allow poking at a few private members.
141 using RenderWidgetHostImpl::GetResizeParams
;
142 using RenderWidgetHostImpl::OnUpdateRect
;
143 using RenderWidgetHostImpl::RendererExited
;
144 using RenderWidgetHostImpl::SetInitialRenderSizeParams
;
145 using RenderWidgetHostImpl::old_resize_params_
;
146 using RenderWidgetHostImpl::is_hidden_
;
147 using RenderWidgetHostImpl::resize_ack_pending_
;
148 using RenderWidgetHostImpl::input_router_
;
150 void OnTouchEventAck(const TouchEventWithLatencyInfo
& event
,
151 InputEventAckState ack_result
) override
{
153 acked_touch_event_type_
= event
.event
.type
;
154 RenderWidgetHostImpl::OnTouchEventAck(event
, ack_result
);
157 bool unresponsive_timer_fired() const {
158 return unresponsive_timer_fired_
;
161 void set_hung_renderer_delay_ms(int64 delay_ms
) {
162 hung_renderer_delay_ms_
= delay_ms
;
165 void DisableGestureDebounce() {
166 input_router_
.reset(new InputRouterImpl(
167 process_
, this, this, routing_id_
, InputRouterImpl::Config()));
170 WebInputEvent::Type
acked_touch_event_type() const {
171 return acked_touch_event_type_
;
174 void SetupForInputRouterTest() {
175 input_router_
.reset(new MockInputRouter(this));
178 MockInputRouter
* mock_input_router() {
179 return static_cast<MockInputRouter
*>(input_router_
.get());
183 void NotifyRendererUnresponsive() override
{
184 unresponsive_timer_fired_
= true;
187 bool unresponsive_timer_fired_
;
188 WebInputEvent::Type acked_touch_event_type_
;
190 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost
);
195 // RenderWidgetHostProcess -----------------------------------------------------
197 class RenderWidgetHostProcess
: public MockRenderProcessHost
{
199 explicit RenderWidgetHostProcess(BrowserContext
* browser_context
)
200 : MockRenderProcessHost(browser_context
) {
202 ~RenderWidgetHostProcess() override
{}
204 bool HasConnection() const override
{ return true; }
207 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess
);
210 // TestView --------------------------------------------------------------------
212 // This test view allows us to specify the size, and keep track of acked
214 class TestView
: public TestRenderWidgetHostView
{
216 explicit TestView(RenderWidgetHostImpl
* rwh
)
217 : TestRenderWidgetHostView(rwh
),
218 unhandled_wheel_event_count_(0),
219 acked_event_count_(0),
220 gesture_event_type_(-1),
221 use_fake_physical_backing_size_(false),
222 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN
) {
225 // Sets the bounds returned by GetViewBounds.
226 void set_bounds(const gfx::Rect
& bounds
) {
230 const WebTouchEvent
& acked_event() const { return acked_event_
; }
231 int acked_event_count() const { return acked_event_count_
; }
232 void ClearAckedEvent() {
233 acked_event_
.type
= blink::WebInputEvent::Undefined
;
234 acked_event_count_
= 0;
237 const WebMouseWheelEvent
& unhandled_wheel_event() const {
238 return unhandled_wheel_event_
;
240 int unhandled_wheel_event_count() const {
241 return unhandled_wheel_event_count_
;
243 int gesture_event_type() const { return gesture_event_type_
; }
244 InputEventAckState
ack_result() const { return ack_result_
; }
246 void SetMockPhysicalBackingSize(const gfx::Size
& mock_physical_backing_size
) {
247 use_fake_physical_backing_size_
= true;
248 mock_physical_backing_size_
= mock_physical_backing_size
;
250 void ClearMockPhysicalBackingSize() {
251 use_fake_physical_backing_size_
= false;
254 // RenderWidgetHostView override.
255 gfx::Rect
GetViewBounds() const override
{ return bounds_
; }
256 void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo
& touch
,
257 InputEventAckState ack_result
) override
{
258 acked_event_
= touch
.event
;
259 ++acked_event_count_
;
261 void WheelEventAck(const WebMouseWheelEvent
& event
,
262 InputEventAckState ack_result
) override
{
263 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
)
265 unhandled_wheel_event_count_
++;
266 unhandled_wheel_event_
= event
;
268 void GestureEventAck(const WebGestureEvent
& event
,
269 InputEventAckState ack_result
) override
{
270 gesture_event_type_
= event
.type
;
271 ack_result_
= ack_result
;
273 gfx::Size
GetPhysicalBackingSize() const override
{
274 if (use_fake_physical_backing_size_
)
275 return mock_physical_backing_size_
;
276 return TestRenderWidgetHostView::GetPhysicalBackingSize();
278 #if defined(USE_AURA)
279 ~TestView() override
{
280 // Simulate the mouse exit event dispatched when an aura window is
281 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
282 // into WebInputEvent::MouseMove.)
283 rwh_
->input_router()->SendMouseEvent(
284 MouseEventWithLatencyInfo(
285 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove
),
291 WebMouseWheelEvent unhandled_wheel_event_
;
292 int unhandled_wheel_event_count_
;
293 WebTouchEvent acked_event_
;
294 int acked_event_count_
;
295 int gesture_event_type_
;
297 bool use_fake_physical_backing_size_
;
298 gfx::Size mock_physical_backing_size_
;
299 InputEventAckState ack_result_
;
301 DISALLOW_COPY_AND_ASSIGN(TestView
);
304 // MockRenderWidgetHostDelegate --------------------------------------------
306 class MockRenderWidgetHostDelegate
: public RenderWidgetHostDelegate
{
308 MockRenderWidgetHostDelegate()
309 : prehandle_keyboard_event_(false),
310 prehandle_keyboard_event_called_(false),
311 prehandle_keyboard_event_type_(WebInputEvent::Undefined
),
312 unhandled_keyboard_event_called_(false),
313 unhandled_keyboard_event_type_(WebInputEvent::Undefined
),
314 handle_wheel_event_(false),
315 handle_wheel_event_called_(false) {
317 ~MockRenderWidgetHostDelegate() override
{}
319 // Tests that make sure we ignore keyboard event acknowledgments to events we
320 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
321 bool unhandled_keyboard_event_called() const {
322 return unhandled_keyboard_event_called_
;
325 WebInputEvent::Type
unhandled_keyboard_event_type() const {
326 return unhandled_keyboard_event_type_
;
329 bool prehandle_keyboard_event_called() const {
330 return prehandle_keyboard_event_called_
;
333 WebInputEvent::Type
prehandle_keyboard_event_type() const {
334 return prehandle_keyboard_event_type_
;
337 void set_prehandle_keyboard_event(bool handle
) {
338 prehandle_keyboard_event_
= handle
;
341 void set_handle_wheel_event(bool handle
) {
342 handle_wheel_event_
= handle
;
345 bool handle_wheel_event_called() {
346 return handle_wheel_event_called_
;
350 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent
& event
,
351 bool* is_keyboard_shortcut
) override
{
352 prehandle_keyboard_event_type_
= event
.type
;
353 prehandle_keyboard_event_called_
= true;
354 return prehandle_keyboard_event_
;
357 void HandleKeyboardEvent(const NativeWebKeyboardEvent
& event
) override
{
358 unhandled_keyboard_event_type_
= event
.type
;
359 unhandled_keyboard_event_called_
= true;
362 bool HandleWheelEvent(const blink::WebMouseWheelEvent
& event
) override
{
363 handle_wheel_event_called_
= true;
364 return handle_wheel_event_
;
368 bool prehandle_keyboard_event_
;
369 bool prehandle_keyboard_event_called_
;
370 WebInputEvent::Type prehandle_keyboard_event_type_
;
372 bool unhandled_keyboard_event_called_
;
373 WebInputEvent::Type unhandled_keyboard_event_type_
;
375 bool handle_wheel_event_
;
376 bool handle_wheel_event_called_
;
379 // RenderWidgetHostTest --------------------------------------------------------
381 class RenderWidgetHostTest
: public testing::Test
{
383 RenderWidgetHostTest()
385 handle_key_press_event_(false),
386 handle_mouse_event_(false),
387 simulated_event_time_delta_seconds_(0) {
388 last_simulated_event_time_seconds_
=
389 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
391 ~RenderWidgetHostTest() override
{}
393 bool KeyPressEventCallback(const NativeWebKeyboardEvent
& /* event */) {
394 return handle_key_press_event_
;
396 bool MouseEventCallback(const blink::WebMouseEvent
& /* event */) {
397 return handle_mouse_event_
;
402 void SetUp() override
{
403 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
404 command_line
->AppendSwitch(switches::kValidateInputEventStream
);
406 browser_context_
.reset(new TestBrowserContext());
407 delegate_
.reset(new MockRenderWidgetHostDelegate());
408 process_
= new RenderWidgetHostProcess(browser_context_
.get());
409 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
410 if (IsDelegatedRendererEnabled()) {
411 ImageTransportFactory::InitializeForUnitTests(
412 scoped_ptr
<ImageTransportFactory
>(
413 new NoTransportImageTransportFactory
));
416 #if defined(USE_AURA)
417 aura::Env::CreateInstance(true);
418 screen_
.reset(aura::TestScreen::Create(gfx::Size()));
419 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
.get());
422 new MockRenderWidgetHost(delegate_
.get(), process_
, MSG_ROUTING_NONE
));
423 view_
.reset(new TestView(host_
.get()));
424 ConfigureView(view_
.get());
425 host_
->SetView(view_
.get());
426 SetInitialRenderSizeParams();
428 host_
->DisableGestureDebounce();
431 void TearDown() override
{
436 browser_context_
.reset();
438 #if defined(USE_AURA)
439 aura::Env::DeleteInstance();
440 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, nullptr);
443 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
444 if (IsDelegatedRendererEnabled())
445 ImageTransportFactory::Terminate();
448 // Process all pending tasks to avoid leaks.
449 base::MessageLoop::current()->RunUntilIdle();
452 void SetInitialRenderSizeParams() {
453 ViewMsg_Resize_Params render_size_params
;
454 host_
->GetResizeParams(&render_size_params
);
455 host_
->SetInitialRenderSizeParams(render_size_params
);
458 virtual void ConfigureView(TestView
* view
) {
461 int64
GetLatencyComponentId() {
462 return host_
->GetLatencyComponentId();
465 void SendInputEventACK(WebInputEvent::Type type
,
466 InputEventAckState ack_result
) {
467 InputHostMsg_HandleInputEvent_ACK_Params ack
;
469 ack
.state
= ack_result
;
470 host_
->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack
));
473 double GetNextSimulatedEventTimeSeconds() {
474 last_simulated_event_time_seconds_
+= simulated_event_time_delta_seconds_
;
475 return last_simulated_event_time_seconds_
;
478 void SimulateKeyboardEvent(WebInputEvent::Type type
) {
479 SimulateKeyboardEvent(type
, 0);
482 void SimulateKeyboardEvent(WebInputEvent::Type type
, int modifiers
) {
483 WebKeyboardEvent event
= SyntheticWebKeyboardEventBuilder::Build(type
);
484 event
.modifiers
= modifiers
;
485 NativeWebKeyboardEvent native_event
;
486 memcpy(&native_event
, &event
, sizeof(event
));
487 host_
->ForwardKeyboardEvent(native_event
);
490 void SimulateMouseEvent(WebInputEvent::Type type
) {
491 host_
->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type
));
494 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type
,
495 const ui::LatencyInfo
& ui_latency
) {
496 host_
->ForwardMouseEventWithLatencyInfo(
497 SyntheticWebMouseEventBuilder::Build(type
),
501 void SimulateWheelEvent(float dX
, float dY
, int modifiers
, bool precise
) {
502 host_
->ForwardWheelEvent(
503 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
));
506 void SimulateWheelEventWithLatencyInfo(float dX
,
510 const ui::LatencyInfo
& ui_latency
) {
511 host_
->ForwardWheelEventWithLatencyInfo(
512 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
),
516 void SimulateMouseMove(int x
, int y
, int modifiers
) {
517 SimulateMouseEvent(WebInputEvent::MouseMove
, x
, y
, modifiers
, false);
520 void SimulateMouseEvent(
521 WebInputEvent::Type type
, int x
, int y
, int modifiers
, bool pressed
) {
522 WebMouseEvent event
=
523 SyntheticWebMouseEventBuilder::Build(type
, x
, y
, modifiers
);
525 event
.button
= WebMouseEvent::ButtonLeft
;
526 event
.timeStampSeconds
= GetNextSimulatedEventTimeSeconds();
527 host_
->ForwardMouseEvent(event
);
530 // Inject simple synthetic WebGestureEvent instances.
531 void SimulateGestureEvent(WebInputEvent::Type type
,
532 WebGestureDevice sourceDevice
) {
533 host_
->ForwardGestureEvent(
534 SyntheticWebGestureEventBuilder::Build(type
, sourceDevice
));
537 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type
,
538 WebGestureDevice sourceDevice
,
539 const ui::LatencyInfo
& ui_latency
) {
540 host_
->ForwardGestureEventWithLatencyInfo(
541 SyntheticWebGestureEventBuilder::Build(type
, sourceDevice
),
545 // Set the timestamp for the touch-event.
546 void SetTouchTimestamp(base::TimeDelta timestamp
) {
547 touch_event_
.SetTimestamp(timestamp
);
550 // Sends a touch event (irrespective of whether the page has a touch-event
552 void SendTouchEvent() {
553 host_
->ForwardTouchEventWithLatencyInfo(touch_event_
, ui::LatencyInfo());
555 touch_event_
.ResetPoints();
558 int PressTouchPoint(int x
, int y
) {
559 return touch_event_
.PressPoint(x
, y
);
562 void MoveTouchPoint(int index
, int x
, int y
) {
563 touch_event_
.MovePoint(index
, x
, y
);
566 void ReleaseTouchPoint(int index
) {
567 touch_event_
.ReleasePoint(index
);
570 const WebInputEvent
* GetInputEventFromMessage(const IPC::Message
& message
) {
571 PickleIterator
iter(message
);
574 if (!iter
.ReadData(&data
, &data_length
))
576 return reinterpret_cast<const WebInputEvent
*>(data
);
579 base::MessageLoopForUI message_loop_
;
581 scoped_ptr
<TestBrowserContext
> browser_context_
;
582 RenderWidgetHostProcess
* process_
; // Deleted automatically by the widget.
583 scoped_ptr
<MockRenderWidgetHostDelegate
> delegate_
;
584 scoped_ptr
<MockRenderWidgetHost
> host_
;
585 scoped_ptr
<TestView
> view_
;
586 scoped_ptr
<gfx::Screen
> screen_
;
587 bool handle_key_press_event_
;
588 bool handle_mouse_event_
;
589 double last_simulated_event_time_seconds_
;
590 double simulated_event_time_delta_seconds_
;
593 SyntheticWebTouchEvent touch_event_
;
595 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest
);
598 #if GTEST_HAS_PARAM_TEST
599 // RenderWidgetHostWithSourceTest ----------------------------------------------
601 // This is for tests that are to be run for all source devices.
602 class RenderWidgetHostWithSourceTest
603 : public RenderWidgetHostTest
,
604 public testing::WithParamInterface
<WebGestureDevice
> {};
605 #endif // GTEST_HAS_PARAM_TEST
609 // -----------------------------------------------------------------------------
611 TEST_F(RenderWidgetHostTest
, Resize
) {
612 // The initial bounds is the empty rect, and the screen info hasn't been sent
613 // yet, so setting it to the same thing shouldn't send the resize message.
614 view_
->set_bounds(gfx::Rect());
616 EXPECT_FALSE(host_
->resize_ack_pending_
);
617 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
619 // No resize ack if the physical backing gets set, but the view bounds are
621 view_
->SetMockPhysicalBackingSize(gfx::Size(200, 200));
623 EXPECT_FALSE(host_
->resize_ack_pending_
);
625 // Setting the view bounds to nonzero 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_
->old_resize_params_
->new_size
);
634 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
636 // Setting the bounds and physical backing size to nonzero should send out
637 // the notification and expect an ack.
638 process_
->sink().ClearMessages();
639 view_
->ClearMockPhysicalBackingSize();
641 EXPECT_TRUE(host_
->resize_ack_pending_
);
642 EXPECT_EQ(original_size
.size(), host_
->old_resize_params_
->new_size
);
643 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
644 ViewHostMsg_UpdateRect_Params params
;
645 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
646 params
.view_size
= original_size
.size();
647 host_
->OnUpdateRect(params
);
648 EXPECT_FALSE(host_
->resize_ack_pending_
);
650 // Send out a update that's not a resize ack after setting resize ack pending
651 // flag. This should not clean the resize ack pending flag.
652 process_
->sink().ClearMessages();
653 gfx::Rect
second_size(0, 0, 110, 110);
654 EXPECT_FALSE(host_
->resize_ack_pending_
);
655 view_
->set_bounds(second_size
);
657 EXPECT_TRUE(host_
->resize_ack_pending_
);
659 params
.view_size
= gfx::Size(100, 100);
660 host_
->OnUpdateRect(params
);
661 EXPECT_TRUE(host_
->resize_ack_pending_
);
662 EXPECT_EQ(second_size
.size(), host_
->old_resize_params_
->new_size
);
664 // Sending out a new notification should NOT send out a new IPC message since
665 // a resize ACK is pending.
666 gfx::Rect
third_size(0, 0, 120, 120);
667 process_
->sink().ClearMessages();
668 view_
->set_bounds(third_size
);
670 EXPECT_TRUE(host_
->resize_ack_pending_
);
671 EXPECT_EQ(second_size
.size(), host_
->old_resize_params_
->new_size
);
672 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
674 // Send a update that's a resize ack, but for the original_size we sent. Since
675 // this isn't the second_size, the message handler should immediately send
676 // a new resize message for the new size to the renderer.
677 process_
->sink().ClearMessages();
678 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
679 params
.view_size
= original_size
.size();
680 host_
->OnUpdateRect(params
);
681 EXPECT_TRUE(host_
->resize_ack_pending_
);
682 EXPECT_EQ(third_size
.size(), host_
->old_resize_params_
->new_size
);
683 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
685 // Send the resize ack for the latest size.
686 process_
->sink().ClearMessages();
687 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
688 params
.view_size
= third_size
.size();
689 host_
->OnUpdateRect(params
);
690 EXPECT_FALSE(host_
->resize_ack_pending_
);
691 EXPECT_EQ(third_size
.size(), host_
->old_resize_params_
->new_size
);
692 EXPECT_FALSE(process_
->sink().GetFirstMessageMatching(ViewMsg_Resize::ID
));
694 // Now clearing the bounds should send out a notification but we shouldn't
695 // expect a resize ack (since the renderer won't ack empty sizes). The message
696 // should contain the new size (0x0) and not the previous one that we skipped
697 process_
->sink().ClearMessages();
698 view_
->set_bounds(gfx::Rect());
700 EXPECT_FALSE(host_
->resize_ack_pending_
);
701 EXPECT_EQ(gfx::Size(), host_
->old_resize_params_
->new_size
);
702 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
704 // Send a rect that has no area but has either width or height set.
705 process_
->sink().ClearMessages();
706 view_
->set_bounds(gfx::Rect(0, 0, 0, 30));
708 EXPECT_FALSE(host_
->resize_ack_pending_
);
709 EXPECT_EQ(gfx::Size(0, 30), host_
->old_resize_params_
->new_size
);
710 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
712 // Set the same size again. It should not be sent again.
713 process_
->sink().ClearMessages();
715 EXPECT_FALSE(host_
->resize_ack_pending_
);
716 EXPECT_EQ(gfx::Size(0, 30), host_
->old_resize_params_
->new_size
);
717 EXPECT_FALSE(process_
->sink().GetFirstMessageMatching(ViewMsg_Resize::ID
));
719 // A different size should be sent again, however.
720 view_
->set_bounds(gfx::Rect(0, 0, 0, 31));
722 EXPECT_FALSE(host_
->resize_ack_pending_
);
723 EXPECT_EQ(gfx::Size(0, 31), host_
->old_resize_params_
->new_size
);
724 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
727 // Test for crbug.com/25097. If a renderer crashes between a resize and the
728 // corresponding update message, we must be sure to clear the resize ack logic.
729 TEST_F(RenderWidgetHostTest
, ResizeThenCrash
) {
730 // Clear the first Resize message that carried screen info.
731 process_
->sink().ClearMessages();
733 // Setting the bounds to a "real" rect should send out the notification.
734 gfx::Rect
original_size(0, 0, 100, 100);
735 view_
->set_bounds(original_size
);
737 EXPECT_TRUE(host_
->resize_ack_pending_
);
738 EXPECT_EQ(original_size
.size(), host_
->old_resize_params_
->new_size
);
739 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
741 // Simulate a renderer crash before the update message. Ensure all the
742 // resize ack logic is cleared. Must clear the view first so it doesn't get
744 host_
->SetView(NULL
);
745 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
746 EXPECT_FALSE(host_
->resize_ack_pending_
);
747 EXPECT_EQ(gfx::Size(), host_
->old_resize_params_
->new_size
);
749 // Reset the view so we can exit the test cleanly.
750 host_
->SetView(view_
.get());
753 // Unable to include render_widget_host_view_mac.h and compile.
754 #if !defined(OS_MACOSX)
755 // Tests setting background transparency.
756 TEST_F(RenderWidgetHostTest
, Background
) {
757 scoped_ptr
<RenderWidgetHostViewBase
> view
;
758 #if defined(USE_AURA)
759 view
.reset(new RenderWidgetHostViewAura(host_
.get(), false));
760 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
761 view
->InitAsChild(NULL
);
762 #elif defined(OS_ANDROID)
763 view
.reset(new RenderWidgetHostViewAndroid(host_
.get(), NULL
));
765 host_
->SetView(view
.get());
767 EXPECT_TRUE(view
->GetBackgroundOpaque());
768 view
->SetBackgroundColor(SK_ColorTRANSPARENT
);
769 EXPECT_FALSE(view
->GetBackgroundOpaque());
771 const IPC::Message
* set_background
=
772 process_
->sink().GetUniqueMessageMatching(
773 ViewMsg_SetBackgroundOpaque::ID
);
774 ASSERT_TRUE(set_background
);
775 Tuple
<bool> sent_background
;
776 ViewMsg_SetBackgroundOpaque::Read(set_background
, &sent_background
);
777 EXPECT_FALSE(get
<0>(sent_background
));
779 #if defined(USE_AURA)
780 // See the comment above |InitAsChild(NULL)|.
781 host_
->SetView(NULL
);
782 static_cast<RenderWidgetHostViewBase
*>(view
.release())->Destroy();
787 // Test that we don't paint when we're hidden, but we still send the ACK. Most
788 // of the rest of the painting is tested in the GetBackingStore* ones.
789 TEST_F(RenderWidgetHostTest
, HiddenPaint
) {
790 BrowserThreadImpl
ui_thread(BrowserThread::UI
, base::MessageLoop::current());
791 // Hide the widget, it should have sent out a message to the renderer.
792 EXPECT_FALSE(host_
->is_hidden_
);
794 EXPECT_TRUE(host_
->is_hidden_
);
795 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID
));
797 // Send it an update as from the renderer.
798 process_
->sink().ClearMessages();
799 ViewHostMsg_UpdateRect_Params params
;
800 params
.view_size
= gfx::Size(100, 100);
801 host_
->OnUpdateRect(params
);
804 process_
->sink().ClearMessages();
805 host_
->WasShown(ui::LatencyInfo());
806 EXPECT_FALSE(host_
->is_hidden_
);
808 // It should have sent out a restored message with a request to paint.
809 const IPC::Message
* restored
= process_
->sink().GetUniqueMessageMatching(
810 ViewMsg_WasShown::ID
);
811 ASSERT_TRUE(restored
);
812 Tuple
<bool, ui::LatencyInfo
> needs_repaint
;
813 ViewMsg_WasShown::Read(restored
, &needs_repaint
);
814 EXPECT_TRUE(get
<0>(needs_repaint
));
817 TEST_F(RenderWidgetHostTest
, IgnoreKeyEventsHandledByRenderer
) {
818 // Simulate a keyboard event.
819 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
821 // Make sure we sent the input event to the renderer.
822 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
823 InputMsg_HandleInputEvent::ID
));
824 process_
->sink().ClearMessages();
826 // Send the simulated response from the renderer back.
827 SendInputEventACK(WebInputEvent::RawKeyDown
,
828 INPUT_EVENT_ACK_STATE_CONSUMED
);
829 EXPECT_FALSE(delegate_
->unhandled_keyboard_event_called());
832 TEST_F(RenderWidgetHostTest
, PreHandleRawKeyDownEvent
) {
833 // Simluate the situation that the browser handled the key down event during
834 // pre-handle phrase.
835 delegate_
->set_prehandle_keyboard_event(true);
836 process_
->sink().ClearMessages();
838 // Simulate a keyboard event.
839 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
841 EXPECT_TRUE(delegate_
->prehandle_keyboard_event_called());
842 EXPECT_EQ(WebInputEvent::RawKeyDown
,
843 delegate_
->prehandle_keyboard_event_type());
845 // Make sure the RawKeyDown event is not sent to the renderer.
846 EXPECT_EQ(0U, process_
->sink().message_count());
848 // The browser won't pre-handle a Char event.
849 delegate_
->set_prehandle_keyboard_event(false);
851 // Forward the Char event.
852 SimulateKeyboardEvent(WebInputEvent::Char
);
854 // Make sure the Char event is suppressed.
855 EXPECT_EQ(0U, process_
->sink().message_count());
857 // Forward the KeyUp event.
858 SimulateKeyboardEvent(WebInputEvent::KeyUp
);
860 // Make sure only KeyUp was sent to the renderer.
861 EXPECT_EQ(1U, process_
->sink().message_count());
862 EXPECT_EQ(InputMsg_HandleInputEvent::ID
,
863 process_
->sink().GetMessageAt(0)->type());
864 process_
->sink().ClearMessages();
866 // Send the simulated response from the renderer back.
867 SendInputEventACK(WebInputEvent::KeyUp
,
868 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
870 EXPECT_TRUE(delegate_
->unhandled_keyboard_event_called());
871 EXPECT_EQ(WebInputEvent::KeyUp
, delegate_
->unhandled_keyboard_event_type());
874 TEST_F(RenderWidgetHostTest
, UnhandledWheelEvent
) {
875 SimulateWheelEvent(-5, 0, 0, true);
877 // Make sure we sent the input event to the renderer.
878 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
879 InputMsg_HandleInputEvent::ID
));
880 process_
->sink().ClearMessages();
882 // Send the simulated response from the renderer back.
883 SendInputEventACK(WebInputEvent::MouseWheel
,
884 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
885 EXPECT_TRUE(delegate_
->handle_wheel_event_called());
886 EXPECT_EQ(1, view_
->unhandled_wheel_event_count());
887 EXPECT_EQ(-5, view_
->unhandled_wheel_event().deltaX
);
890 TEST_F(RenderWidgetHostTest
, HandleWheelEvent
) {
891 // Indicate that we're going to handle this wheel event
892 delegate_
->set_handle_wheel_event(true);
894 SimulateWheelEvent(-5, 0, 0, true);
896 // Make sure we sent the input event to the renderer.
897 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
898 InputMsg_HandleInputEvent::ID
));
899 process_
->sink().ClearMessages();
901 // Send the simulated response from the renderer back.
902 SendInputEventACK(WebInputEvent::MouseWheel
,
903 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
905 // ensure the wheel event handler was invoked
906 EXPECT_TRUE(delegate_
->handle_wheel_event_called());
908 // and that it suppressed the unhandled wheel event handler.
909 EXPECT_EQ(0, view_
->unhandled_wheel_event_count());
912 TEST_F(RenderWidgetHostTest
, UnhandledGestureEvent
) {
913 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap
,
914 blink::WebGestureDeviceTouchscreen
);
916 // Make sure we sent the input event to the renderer.
917 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
918 InputMsg_HandleInputEvent::ID
));
919 process_
->sink().ClearMessages();
921 // Send the simulated response from the renderer back.
922 SendInputEventACK(WebInputEvent::GestureTwoFingerTap
,
923 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
924 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap
, view_
->gesture_event_type());
925 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED
, view_
->ack_result());
928 // Test that the hang monitor timer expires properly if a new timer is started
929 // while one is in progress (see crbug.com/11007).
930 TEST_F(RenderWidgetHostTest
, DontPostponeHangMonitorTimeout
) {
931 // Start with a short timeout.
932 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
934 // Immediately try to add a long 30 second timeout.
935 EXPECT_FALSE(host_
->unresponsive_timer_fired());
936 host_
->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
938 // Wait long enough for first timeout and see if it fired.
939 base::MessageLoop::current()->PostDelayedTask(
941 base::MessageLoop::QuitClosure(),
942 TimeDelta::FromMilliseconds(10));
943 base::MessageLoop::current()->Run();
944 EXPECT_TRUE(host_
->unresponsive_timer_fired());
947 // Test that the hang monitor timer expires properly if it is started, stopped,
948 // and then started again.
949 TEST_F(RenderWidgetHostTest
, StopAndStartHangMonitorTimeout
) {
950 // Start with a short timeout, then stop it.
951 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
952 host_
->StopHangMonitorTimeout();
954 // Start it again to ensure it still works.
955 EXPECT_FALSE(host_
->unresponsive_timer_fired());
956 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
958 // Wait long enough for first timeout and see if it fired.
959 base::MessageLoop::current()->PostDelayedTask(
961 base::MessageLoop::QuitClosure(),
962 TimeDelta::FromMilliseconds(40));
963 base::MessageLoop::current()->Run();
964 EXPECT_TRUE(host_
->unresponsive_timer_fired());
967 // Test that the hang monitor timer expires properly if it is started, then
968 // updated to a shorter duration.
969 TEST_F(RenderWidgetHostTest
, ShorterDelayHangMonitorTimeout
) {
970 // Start with a timeout.
971 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
973 // Start it again with shorter delay.
974 EXPECT_FALSE(host_
->unresponsive_timer_fired());
975 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
977 // Wait long enough for the second timeout and see if it fired.
978 base::MessageLoop::current()->PostDelayedTask(
980 base::MessageLoop::QuitClosure(),
981 TimeDelta::FromMilliseconds(25));
982 base::MessageLoop::current()->Run();
983 EXPECT_TRUE(host_
->unresponsive_timer_fired());
986 // Test that the hang monitor catches two input events but only one ack.
987 // This can happen if the second input event causes the renderer to hang.
988 // This test will catch a regression of crbug.com/111185.
989 TEST_F(RenderWidgetHostTest
, MultipleInputEvents
) {
990 // Configure the host to wait 10ms before considering
991 // the renderer hung.
992 host_
->set_hung_renderer_delay_ms(10);
994 // Send two events but only one ack.
995 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
996 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
997 SendInputEventACK(WebInputEvent::RawKeyDown
,
998 INPUT_EVENT_ACK_STATE_CONSUMED
);
1000 // Wait long enough for first timeout and see if it fired.
1001 base::MessageLoop::current()->PostDelayedTask(
1003 base::MessageLoop::QuitClosure(),
1004 TimeDelta::FromMilliseconds(40));
1005 base::MessageLoop::current()->Run();
1006 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1009 std::string
GetInputMessageTypes(RenderWidgetHostProcess
* process
) {
1011 for (size_t i
= 0; i
< process
->sink().message_count(); ++i
) {
1012 const IPC::Message
*message
= process
->sink().GetMessageAt(i
);
1013 EXPECT_EQ(InputMsg_HandleInputEvent::ID
, message
->type());
1014 InputMsg_HandleInputEvent::Param params
;
1015 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message
, ¶ms
));
1016 const WebInputEvent
* event
= get
<0>(params
);
1019 result
+= WebInputEventTraits::GetName(event
->type
);
1021 process
->sink().ClearMessages();
1025 TEST_F(RenderWidgetHostTest
, TouchEmulator
) {
1026 simulated_event_time_delta_seconds_
= 0.1;
1027 // Immediately ack all touches instead of sending them to the renderer.
1028 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1029 host_
->SetTouchEventEmulationEnabled(
1030 true, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1031 process_
->sink().ClearMessages();
1032 view_
->set_bounds(gfx::Rect(0, 0, 400, 200));
1035 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1036 EXPECT_EQ(0U, process_
->sink().message_count());
1038 // Mouse press becomes touch start which in turn becomes tap.
1039 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 10, 0, true);
1040 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1041 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1043 // Mouse drag generates touch move, cancels tap and starts scroll.
1044 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 30, 0, true);
1045 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1047 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1048 GetInputMessageTypes(process_
));
1049 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1050 INPUT_EVENT_ACK_STATE_CONSUMED
);
1051 EXPECT_EQ(0U, process_
->sink().message_count());
1053 // Mouse drag with shift becomes pinch.
1055 WebInputEvent::MouseMove
, 10, 40, WebInputEvent::ShiftKey
, true);
1056 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1057 EXPECT_EQ("GesturePinchBegin",
1058 GetInputMessageTypes(process_
));
1059 EXPECT_EQ(0U, process_
->sink().message_count());
1062 WebInputEvent::MouseMove
, 10, 50, WebInputEvent::ShiftKey
, true);
1063 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1064 EXPECT_EQ("GesturePinchUpdate",
1065 GetInputMessageTypes(process_
));
1066 SendInputEventACK(WebInputEvent::GesturePinchUpdate
,
1067 INPUT_EVENT_ACK_STATE_CONSUMED
);
1068 EXPECT_EQ(0U, process_
->sink().message_count());
1070 // Mouse drag without shift becomes scroll again.
1071 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 60, 0, true);
1072 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1073 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1074 GetInputMessageTypes(process_
));
1075 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1076 INPUT_EVENT_ACK_STATE_CONSUMED
);
1077 EXPECT_EQ(0U, process_
->sink().message_count());
1079 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 70, 0, true);
1080 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1081 EXPECT_EQ("GestureScrollUpdate",
1082 GetInputMessageTypes(process_
));
1083 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1084 INPUT_EVENT_ACK_STATE_CONSUMED
);
1085 EXPECT_EQ(0U, process_
->sink().message_count());
1087 SimulateMouseEvent(WebInputEvent::MouseUp
, 10, 70, 0, true);
1088 EXPECT_EQ(WebInputEvent::TouchEnd
, host_
->acked_touch_event_type());
1089 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_
));
1090 EXPECT_EQ(0U, process_
->sink().message_count());
1092 // Mouse move does nothing.
1093 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 80, 0, false);
1094 EXPECT_EQ(0U, process_
->sink().message_count());
1096 // Another mouse down continues scroll.
1097 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 80, 0, true);
1098 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1099 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1100 EXPECT_EQ(0U, process_
->sink().message_count());
1102 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 100, 0, true);
1103 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1105 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1106 GetInputMessageTypes(process_
));
1107 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1108 INPUT_EVENT_ACK_STATE_CONSUMED
);
1109 EXPECT_EQ(0U, process_
->sink().message_count());
1113 WebInputEvent::MouseMove
, 10, 110, WebInputEvent::ShiftKey
, true);
1114 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1115 EXPECT_EQ("GesturePinchBegin",
1116 GetInputMessageTypes(process_
));
1117 EXPECT_EQ(0U, process_
->sink().message_count());
1120 WebInputEvent::MouseMove
, 10, 120, WebInputEvent::ShiftKey
, true);
1121 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1122 EXPECT_EQ("GesturePinchUpdate",
1123 GetInputMessageTypes(process_
));
1124 SendInputEventACK(WebInputEvent::GesturePinchUpdate
,
1125 INPUT_EVENT_ACK_STATE_CONSUMED
);
1126 EXPECT_EQ(0U, process_
->sink().message_count());
1128 // Turn off emulation during a pinch.
1129 host_
->SetTouchEventEmulationEnabled(
1130 false, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1131 EXPECT_EQ(WebInputEvent::TouchCancel
, host_
->acked_touch_event_type());
1132 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1133 GetInputMessageTypes(process_
));
1134 EXPECT_EQ(0U, process_
->sink().message_count());
1136 // Mouse event should pass untouched.
1138 WebInputEvent::MouseMove
, 10, 10, WebInputEvent::ShiftKey
, true);
1139 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_
));
1140 SendInputEventACK(WebInputEvent::MouseMove
,
1141 INPUT_EVENT_ACK_STATE_CONSUMED
);
1142 EXPECT_EQ(0U, process_
->sink().message_count());
1144 // Turn on emulation.
1145 host_
->SetTouchEventEmulationEnabled(
1146 true, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1147 EXPECT_EQ(0U, process_
->sink().message_count());
1150 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 10, 0, true);
1151 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1152 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1153 EXPECT_EQ(0U, process_
->sink().message_count());
1156 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 30, 0, true);
1157 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1159 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1160 GetInputMessageTypes(process_
));
1161 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1162 INPUT_EVENT_ACK_STATE_CONSUMED
);
1164 // Turn off emulation during a scroll.
1165 host_
->SetTouchEventEmulationEnabled(
1166 false, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1167 EXPECT_EQ(WebInputEvent::TouchCancel
, host_
->acked_touch_event_type());
1169 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_
));
1170 EXPECT_EQ(0U, process_
->sink().message_count());
1173 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1174 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1175 host_->SetupForInputRouterTest(); \
1176 host_->INPUTMSG(); \
1177 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1180 TEST_InputRouterRoutes_NOARGS(Focus
);
1181 TEST_InputRouterRoutes_NOARGS(Blur
);
1182 TEST_InputRouterRoutes_NOARGS(LostCapture
);
1184 #undef TEST_InputRouterRoutes_NOARGS
1186 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1187 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1188 host_->SetupForInputRouterTest(); \
1189 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1190 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1193 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo
);
1194 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo
);
1195 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut
);
1196 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy
);
1197 #if defined(OS_MACOSX)
1198 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard
);
1200 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste
);
1201 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle
);
1202 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete
);
1203 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll
);
1204 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect
);
1206 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1208 TEST_F(RenderWidgetHostTest
, InputRouterRoutesReplace
) {
1209 host_
->SetupForInputRouterTest();
1210 host_
->Send(new InputMsg_Replace(host_
->GetRoutingID(), base::string16()));
1211 EXPECT_TRUE(host_
->mock_input_router()->send_event_called_
);
1214 TEST_F(RenderWidgetHostTest
, InputRouterRoutesReplaceMisspelling
) {
1215 host_
->SetupForInputRouterTest();
1216 host_
->Send(new InputMsg_ReplaceMisspelling(host_
->GetRoutingID(),
1218 EXPECT_TRUE(host_
->mock_input_router()->send_event_called_
);
1221 TEST_F(RenderWidgetHostTest
, IgnoreInputEvent
) {
1222 host_
->SetupForInputRouterTest();
1224 host_
->SetIgnoreInputEvents(true);
1226 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1227 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1229 SimulateMouseEvent(WebInputEvent::MouseMove
);
1230 EXPECT_FALSE(host_
->mock_input_router()->sent_mouse_event_
);
1232 SimulateWheelEvent(0, 100, 0, true);
1233 EXPECT_FALSE(host_
->mock_input_router()->sent_wheel_event_
);
1235 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
1236 blink::WebGestureDeviceTouchpad
);
1237 EXPECT_FALSE(host_
->mock_input_router()->sent_gesture_event_
);
1239 PressTouchPoint(100, 100);
1241 EXPECT_FALSE(host_
->mock_input_router()->send_touch_event_not_cancelled_
);
1244 TEST_F(RenderWidgetHostTest
, KeyboardListenerIgnoresEvent
) {
1245 host_
->SetupForInputRouterTest();
1246 host_
->AddKeyPressEventCallback(
1247 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback
,
1248 base::Unretained(this)));
1249 handle_key_press_event_
= false;
1250 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1252 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1255 TEST_F(RenderWidgetHostTest
, KeyboardListenerSuppressFollowingEvents
) {
1256 host_
->SetupForInputRouterTest();
1258 host_
->AddKeyPressEventCallback(
1259 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback
,
1260 base::Unretained(this)));
1262 // The callback handles the first event
1263 handle_key_press_event_
= true;
1264 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1266 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1268 // Following Char events should be suppressed
1269 handle_key_press_event_
= false;
1270 SimulateKeyboardEvent(WebInputEvent::Char
);
1271 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1272 SimulateKeyboardEvent(WebInputEvent::Char
);
1273 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1275 // Sending RawKeyDown event should stop suppression
1276 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1277 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1279 host_
->mock_input_router()->sent_keyboard_event_
= false;
1280 SimulateKeyboardEvent(WebInputEvent::Char
);
1281 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1284 TEST_F(RenderWidgetHostTest
, MouseEventCallbackCanHandleEvent
) {
1285 host_
->SetupForInputRouterTest();
1287 host_
->AddMouseEventCallback(
1288 base::Bind(&RenderWidgetHostTest::MouseEventCallback
,
1289 base::Unretained(this)));
1291 handle_mouse_event_
= true;
1292 SimulateMouseEvent(WebInputEvent::MouseDown
);
1294 EXPECT_FALSE(host_
->mock_input_router()->sent_mouse_event_
);
1296 handle_mouse_event_
= false;
1297 SimulateMouseEvent(WebInputEvent::MouseDown
);
1299 EXPECT_TRUE(host_
->mock_input_router()->sent_mouse_event_
);
1302 TEST_F(RenderWidgetHostTest
, InputRouterReceivesHandleInputEvent_ACK
) {
1303 host_
->SetupForInputRouterTest();
1305 SendInputEventACK(WebInputEvent::RawKeyDown
,
1306 INPUT_EVENT_ACK_STATE_CONSUMED
);
1308 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1311 TEST_F(RenderWidgetHostTest
, InputRouterReceivesMoveCaret_ACK
) {
1312 host_
->SetupForInputRouterTest();
1314 host_
->OnMessageReceived(InputHostMsg_MoveCaret_ACK(0));
1316 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1319 TEST_F(RenderWidgetHostTest
, InputRouterReceivesSelectRange_ACK
) {
1320 host_
->SetupForInputRouterTest();
1322 host_
->OnMessageReceived(InputHostMsg_SelectRange_ACK(0));
1324 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1327 TEST_F(RenderWidgetHostTest
, InputRouterReceivesHasTouchEventHandlers
) {
1328 host_
->SetupForInputRouterTest();
1330 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1332 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1335 ui::LatencyInfo
GetLatencyInfoFromInputEvent(RenderWidgetHostProcess
* process
) {
1336 const IPC::Message
* message
= process
->sink().GetUniqueMessageMatching(
1337 InputMsg_HandleInputEvent::ID
);
1338 EXPECT_TRUE(message
);
1339 InputMsg_HandleInputEvent::Param params
;
1340 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message
, ¶ms
));
1341 process
->sink().ClearMessages();
1342 return get
<1>(params
);
1345 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess
* process
,
1347 WebInputEvent::Type input_type
) {
1348 ui::LatencyInfo latency_info
= GetLatencyInfoFromInputEvent(process
);
1349 EXPECT_TRUE(latency_info
.FindLatency(
1350 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
,
1355 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1356 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1357 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1358 // event's LatencyInfo.
1359 TEST_F(RenderWidgetHostTest
, InputEventRWHLatencyComponent
) {
1360 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1361 process_
->sink().ClearMessages();
1363 // Tests RWHI::ForwardWheelEvent().
1364 SimulateWheelEvent(-5, 0, 0, true);
1365 CheckLatencyInfoComponentInMessage(
1366 process_
, GetLatencyComponentId(), WebInputEvent::MouseWheel
);
1367 SendInputEventACK(WebInputEvent::MouseWheel
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1369 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1370 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1371 CheckLatencyInfoComponentInMessage(
1372 process_
, GetLatencyComponentId(), WebInputEvent::MouseWheel
);
1373 SendInputEventACK(WebInputEvent::MouseWheel
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1375 // Tests RWHI::ForwardMouseEvent().
1376 SimulateMouseEvent(WebInputEvent::MouseMove
);
1377 CheckLatencyInfoComponentInMessage(
1378 process_
, GetLatencyComponentId(), WebInputEvent::MouseMove
);
1379 SendInputEventACK(WebInputEvent::MouseMove
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1381 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1382 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove
,
1384 CheckLatencyInfoComponentInMessage(
1385 process_
, GetLatencyComponentId(), WebInputEvent::MouseMove
);
1386 SendInputEventACK(WebInputEvent::MouseMove
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1388 // Tests RWHI::ForwardGestureEvent().
1389 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
1390 blink::WebGestureDeviceTouchscreen
);
1391 CheckLatencyInfoComponentInMessage(
1392 process_
, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin
);
1394 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1395 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate
,
1396 blink::WebGestureDeviceTouchscreen
,
1398 CheckLatencyInfoComponentInMessage(
1399 process_
, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate
);
1400 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1401 INPUT_EVENT_ACK_STATE_CONSUMED
);
1403 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1404 PressTouchPoint(0, 1);
1406 CheckLatencyInfoComponentInMessage(
1407 process_
, GetLatencyComponentId(), WebInputEvent::TouchStart
);
1408 SendInputEventACK(WebInputEvent::TouchStart
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1411 TEST_F(RenderWidgetHostTest
, RendererExitedResetsInputRouter
) {
1412 // RendererExited will delete the view.
1413 host_
->SetView(new TestView(host_
.get()));
1414 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
1416 // Make sure the input router is in a fresh state.
1417 ASSERT_FALSE(host_
->input_router()->HasPendingEvents());
1420 // Regression test for http://crbug.com/401859.
1421 TEST_F(RenderWidgetHostTest
, RendererExitedResetsIsHidden
) {
1422 // RendererExited will delete the view.
1423 host_
->SetView(new TestView(host_
.get()));
1426 ASSERT_TRUE(host_
->is_hidden());
1427 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
1428 ASSERT_FALSE(host_
->is_hidden());
1430 // Make sure the input router is in a fresh state.
1431 ASSERT_FALSE(host_
->input_router()->HasPendingEvents());
1434 TEST_F(RenderWidgetHostTest
, ResizeParams
) {
1435 gfx::Rect
bounds(0, 0, 100, 100);
1436 gfx::Size
physical_backing_size(40, 50);
1437 view_
->set_bounds(bounds
);
1438 view_
->SetMockPhysicalBackingSize(physical_backing_size
);
1440 ViewMsg_Resize_Params resize_params
;
1441 host_
->GetResizeParams(&resize_params
);
1442 EXPECT_EQ(bounds
.size(), resize_params
.new_size
);
1443 EXPECT_EQ(physical_backing_size
, resize_params
.physical_backing_size
);
1446 class RenderWidgetHostInitialSizeTest
: public RenderWidgetHostTest
{
1448 RenderWidgetHostInitialSizeTest()
1449 : RenderWidgetHostTest(), initial_size_(200, 100) {}
1451 void ConfigureView(TestView
* view
) override
{
1452 view
->set_bounds(gfx::Rect(initial_size_
));
1456 gfx::Size initial_size_
;
1459 TEST_F(RenderWidgetHostInitialSizeTest
, InitialSize
) {
1460 // Having an initial size set means that the size information had been sent
1461 // with the reqiest to new up the RenderView and so subsequent WasResized
1462 // calls should not result in new IPC (unless the size has actually changed).
1463 host_
->WasResized();
1464 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
1465 EXPECT_EQ(initial_size_
, host_
->old_resize_params_
->new_size
);
1466 EXPECT_TRUE(host_
->resize_ack_pending_
);
1469 } // namespace content