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/location.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/shared_memory.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "base/timer/timer.h"
14 #include "content/browser/browser_thread_impl.h"
15 #include "content/browser/gpu/compositor_util.h"
16 #include "content/browser/renderer_host/input/input_router_impl.h"
17 #include "content/browser/renderer_host/render_widget_host_delegate.h"
18 #include "content/browser/renderer_host/render_widget_host_view_base.h"
19 #include "content/common/input/synthetic_web_input_event_builders.h"
20 #include "content/common/input_messages.h"
21 #include "content/common/view_messages.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/test/mock_render_process_host.h"
24 #include "content/public/test/test_browser_context.h"
25 #include "content/test/test_render_view_host.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/events/keycodes/keyboard_codes.h"
28 #include "ui/gfx/canvas.h"
29 #include "ui/gfx/screen.h"
31 #if defined(OS_ANDROID)
32 #include "content/browser/renderer_host/render_widget_host_view_android.h"
35 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
36 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
40 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
41 #include "content/browser/renderer_host/ui_events_helper.h"
42 #include "ui/aura/env.h"
43 #include "ui/aura/test/test_screen.h"
44 #include "ui/events/event.h"
47 using base::TimeDelta
;
48 using blink::WebGestureDevice
;
49 using blink::WebGestureEvent
;
50 using blink::WebInputEvent
;
51 using blink::WebKeyboardEvent
;
52 using blink::WebMouseEvent
;
53 using blink::WebMouseWheelEvent
;
54 using blink::WebTouchEvent
;
55 using blink::WebTouchPoint
;
59 // MockInputRouter -------------------------------------------------------------
61 class MockInputRouter
: public InputRouter
{
63 explicit MockInputRouter(InputRouterClient
* client
)
64 : send_event_called_(false),
65 sent_mouse_event_(false),
66 sent_wheel_event_(false),
67 sent_keyboard_event_(false),
68 sent_gesture_event_(false),
69 send_touch_event_not_cancelled_(false),
70 message_received_(false),
73 ~MockInputRouter() override
{}
76 bool SendInput(scoped_ptr
<IPC::Message
> message
) override
{
77 send_event_called_
= true;
80 void SendMouseEvent(const MouseEventWithLatencyInfo
& mouse_event
) override
{
81 sent_mouse_event_
= true;
84 const MouseWheelEventWithLatencyInfo
& wheel_event
) override
{
85 sent_wheel_event_
= true;
87 void SendKeyboardEvent(const NativeWebKeyboardEvent
& key_event
,
88 const ui::LatencyInfo
& latency_info
,
89 bool is_shortcut
) override
{
90 sent_keyboard_event_
= true;
92 void SendGestureEvent(
93 const GestureEventWithLatencyInfo
& gesture_event
) override
{
94 sent_gesture_event_
= true;
96 void SendTouchEvent(const TouchEventWithLatencyInfo
& touch_event
) override
{
97 send_touch_event_not_cancelled_
=
98 client_
->FilterInputEvent(touch_event
.event
, touch_event
.latency
) ==
99 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
101 const NativeWebKeyboardEvent
* GetLastKeyboardEvent() const override
{
105 void NotifySiteIsMobileOptimized(bool is_mobile_optimized
) override
{}
106 void RequestNotificationWhenFlushed() override
{}
107 bool HasPendingEvents() const override
{ return false; }
110 bool OnMessageReceived(const IPC::Message
& message
) override
{
111 message_received_
= true;
115 bool send_event_called_
;
116 bool sent_mouse_event_
;
117 bool sent_wheel_event_
;
118 bool sent_keyboard_event_
;
119 bool sent_gesture_event_
;
120 bool send_touch_event_not_cancelled_
;
121 bool message_received_
;
124 InputRouterClient
* client_
;
126 DISALLOW_COPY_AND_ASSIGN(MockInputRouter
);
129 // MockRenderWidgetHost ----------------------------------------------------
131 class MockRenderWidgetHost
: public RenderWidgetHostImpl
{
133 MockRenderWidgetHost(
134 RenderWidgetHostDelegate
* delegate
,
135 RenderProcessHost
* process
,
137 : RenderWidgetHostImpl(delegate
, process
, routing_id
, false),
138 unresponsive_timer_fired_(false) {
139 acked_touch_event_type_
= blink::WebInputEvent::Undefined
;
142 // Allow poking at a few private members.
143 using RenderWidgetHostImpl::GetResizeParams
;
144 using RenderWidgetHostImpl::OnUpdateRect
;
145 using RenderWidgetHostImpl::RendererExited
;
146 using RenderWidgetHostImpl::SetInitialRenderSizeParams
;
147 using RenderWidgetHostImpl::old_resize_params_
;
148 using RenderWidgetHostImpl::is_hidden_
;
149 using RenderWidgetHostImpl::resize_ack_pending_
;
150 using RenderWidgetHostImpl::input_router_
;
152 void OnTouchEventAck(const TouchEventWithLatencyInfo
& event
,
153 InputEventAckState ack_result
) override
{
155 acked_touch_event_type_
= event
.event
.type
;
156 RenderWidgetHostImpl::OnTouchEventAck(event
, ack_result
);
159 bool unresponsive_timer_fired() const {
160 return unresponsive_timer_fired_
;
163 void DisableGestureDebounce() {
164 input_router_
.reset(new InputRouterImpl(
165 process_
, this, this, routing_id_
, InputRouterImpl::Config()));
168 WebInputEvent::Type
acked_touch_event_type() const {
169 return acked_touch_event_type_
;
172 void SetupForInputRouterTest() {
173 input_router_
.reset(new MockInputRouter(this));
176 MockInputRouter
* mock_input_router() {
177 return static_cast<MockInputRouter
*>(input_router_
.get());
181 void NotifyRendererUnresponsive() override
{
182 unresponsive_timer_fired_
= true;
185 bool unresponsive_timer_fired_
;
186 WebInputEvent::Type acked_touch_event_type_
;
188 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost
);
193 // RenderWidgetHostProcess -----------------------------------------------------
195 class RenderWidgetHostProcess
: public MockRenderProcessHost
{
197 explicit RenderWidgetHostProcess(BrowserContext
* browser_context
)
198 : MockRenderProcessHost(browser_context
) {
200 ~RenderWidgetHostProcess() override
{}
202 bool HasConnection() const override
{ return true; }
205 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess
);
208 // TestView --------------------------------------------------------------------
210 // This test view allows us to specify the size, and keep track of acked
212 class TestView
: public TestRenderWidgetHostView
{
214 explicit TestView(RenderWidgetHostImpl
* rwh
)
215 : TestRenderWidgetHostView(rwh
),
216 unhandled_wheel_event_count_(0),
217 acked_event_count_(0),
218 gesture_event_type_(-1),
219 use_fake_physical_backing_size_(false),
220 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN
) {
223 // Sets the bounds returned by GetViewBounds.
224 void set_bounds(const gfx::Rect
& bounds
) {
228 const WebTouchEvent
& acked_event() const { return acked_event_
; }
229 int acked_event_count() const { return acked_event_count_
; }
230 void ClearAckedEvent() {
231 acked_event_
.type
= blink::WebInputEvent::Undefined
;
232 acked_event_count_
= 0;
235 const WebMouseWheelEvent
& unhandled_wheel_event() const {
236 return unhandled_wheel_event_
;
238 int unhandled_wheel_event_count() const {
239 return unhandled_wheel_event_count_
;
241 int gesture_event_type() const { return gesture_event_type_
; }
242 InputEventAckState
ack_result() const { return ack_result_
; }
244 void SetMockPhysicalBackingSize(const gfx::Size
& mock_physical_backing_size
) {
245 use_fake_physical_backing_size_
= true;
246 mock_physical_backing_size_
= mock_physical_backing_size
;
248 void ClearMockPhysicalBackingSize() {
249 use_fake_physical_backing_size_
= false;
251 void SetScreenInfo(const blink::WebScreenInfo
& screen_info
) {
252 screen_info_
= screen_info
;
255 // RenderWidgetHostView override.
256 gfx::Rect
GetViewBounds() const override
{ return bounds_
; }
257 void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo
& touch
,
258 InputEventAckState ack_result
) override
{
259 acked_event_
= touch
.event
;
260 ++acked_event_count_
;
262 void WheelEventAck(const WebMouseWheelEvent
& event
,
263 InputEventAckState ack_result
) override
{
264 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
)
266 unhandled_wheel_event_count_
++;
267 unhandled_wheel_event_
= event
;
269 void GestureEventAck(const WebGestureEvent
& event
,
270 InputEventAckState ack_result
) override
{
271 gesture_event_type_
= event
.type
;
272 ack_result_
= ack_result
;
274 gfx::Size
GetPhysicalBackingSize() const override
{
275 if (use_fake_physical_backing_size_
)
276 return mock_physical_backing_size_
;
277 return TestRenderWidgetHostView::GetPhysicalBackingSize();
279 void GetScreenInfo(blink::WebScreenInfo
* screen_info
) override
{
280 *screen_info
= screen_info_
;
282 #if defined(USE_AURA)
283 ~TestView() override
{
284 // Simulate the mouse exit event dispatched when an aura window is
285 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
286 // into WebInputEvent::MouseMove.)
287 rwh_
->input_router()->SendMouseEvent(
288 MouseEventWithLatencyInfo(
289 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove
),
295 WebMouseWheelEvent unhandled_wheel_event_
;
296 int unhandled_wheel_event_count_
;
297 WebTouchEvent acked_event_
;
298 int acked_event_count_
;
299 int gesture_event_type_
;
301 bool use_fake_physical_backing_size_
;
302 gfx::Size mock_physical_backing_size_
;
303 InputEventAckState ack_result_
;
304 blink::WebScreenInfo screen_info_
;
306 DISALLOW_COPY_AND_ASSIGN(TestView
);
309 // MockRenderWidgetHostDelegate --------------------------------------------
311 class MockRenderWidgetHostDelegate
: public RenderWidgetHostDelegate
{
313 MockRenderWidgetHostDelegate()
314 : prehandle_keyboard_event_(false),
315 prehandle_keyboard_event_called_(false),
316 prehandle_keyboard_event_type_(WebInputEvent::Undefined
),
317 unhandled_keyboard_event_called_(false),
318 unhandled_keyboard_event_type_(WebInputEvent::Undefined
),
319 handle_wheel_event_(false),
320 handle_wheel_event_called_(false) {
322 ~MockRenderWidgetHostDelegate() override
{}
324 // Tests that make sure we ignore keyboard event acknowledgments to events we
325 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
326 bool unhandled_keyboard_event_called() const {
327 return unhandled_keyboard_event_called_
;
330 WebInputEvent::Type
unhandled_keyboard_event_type() const {
331 return unhandled_keyboard_event_type_
;
334 bool prehandle_keyboard_event_called() const {
335 return prehandle_keyboard_event_called_
;
338 WebInputEvent::Type
prehandle_keyboard_event_type() const {
339 return prehandle_keyboard_event_type_
;
342 void set_prehandle_keyboard_event(bool handle
) {
343 prehandle_keyboard_event_
= handle
;
346 void set_handle_wheel_event(bool handle
) {
347 handle_wheel_event_
= handle
;
350 bool handle_wheel_event_called() {
351 return handle_wheel_event_called_
;
355 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent
& event
,
356 bool* is_keyboard_shortcut
) override
{
357 prehandle_keyboard_event_type_
= event
.type
;
358 prehandle_keyboard_event_called_
= true;
359 return prehandle_keyboard_event_
;
362 void HandleKeyboardEvent(const NativeWebKeyboardEvent
& event
) override
{
363 unhandled_keyboard_event_type_
= event
.type
;
364 unhandled_keyboard_event_called_
= true;
367 bool HandleWheelEvent(const blink::WebMouseWheelEvent
& event
) override
{
368 handle_wheel_event_called_
= true;
369 return handle_wheel_event_
;
373 bool prehandle_keyboard_event_
;
374 bool prehandle_keyboard_event_called_
;
375 WebInputEvent::Type prehandle_keyboard_event_type_
;
377 bool unhandled_keyboard_event_called_
;
378 WebInputEvent::Type unhandled_keyboard_event_type_
;
380 bool handle_wheel_event_
;
381 bool handle_wheel_event_called_
;
384 // RenderWidgetHostTest --------------------------------------------------------
386 class RenderWidgetHostTest
: public testing::Test
{
388 RenderWidgetHostTest()
390 handle_key_press_event_(false),
391 handle_mouse_event_(false),
392 simulated_event_time_delta_seconds_(0) {
393 last_simulated_event_time_seconds_
=
394 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
396 ~RenderWidgetHostTest() override
{}
398 bool KeyPressEventCallback(const NativeWebKeyboardEvent
& /* event */) {
399 return handle_key_press_event_
;
401 bool MouseEventCallback(const blink::WebMouseEvent
& /* event */) {
402 return handle_mouse_event_
;
407 void SetUp() override
{
408 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
409 command_line
->AppendSwitch(switches::kValidateInputEventStream
);
411 browser_context_
.reset(new TestBrowserContext());
412 delegate_
.reset(new MockRenderWidgetHostDelegate());
413 process_
= new RenderWidgetHostProcess(browser_context_
.get());
414 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
415 if (IsDelegatedRendererEnabled()) {
416 ImageTransportFactory::InitializeForUnitTests(
417 scoped_ptr
<ImageTransportFactory
>(
418 new NoTransportImageTransportFactory
));
421 #if defined(USE_AURA)
422 aura::Env::CreateInstance(true);
423 screen_
.reset(aura::TestScreen::Create(gfx::Size()));
424 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
.get());
427 new MockRenderWidgetHost(delegate_
.get(), process_
, MSG_ROUTING_NONE
));
428 view_
.reset(new TestView(host_
.get()));
429 ConfigureView(view_
.get());
430 host_
->SetView(view_
.get());
431 SetInitialRenderSizeParams();
433 host_
->DisableGestureDebounce();
436 void TearDown() override
{
441 browser_context_
.reset();
443 #if defined(USE_AURA)
444 aura::Env::DeleteInstance();
445 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, nullptr);
448 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
449 if (IsDelegatedRendererEnabled())
450 ImageTransportFactory::Terminate();
453 // Process all pending tasks to avoid leaks.
454 base::MessageLoop::current()->RunUntilIdle();
457 void SetInitialRenderSizeParams() {
458 ViewMsg_Resize_Params render_size_params
;
459 host_
->GetResizeParams(&render_size_params
);
460 host_
->SetInitialRenderSizeParams(render_size_params
);
463 virtual void ConfigureView(TestView
* view
) {
466 int64
GetLatencyComponentId() {
467 return host_
->GetLatencyComponentId();
470 void SendInputEventACK(WebInputEvent::Type type
,
471 InputEventAckState ack_result
) {
472 DCHECK(!WebInputEvent::isTouchEventType(type
));
473 InputEventAck
ack(type
, ack_result
);
474 host_
->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack
));
477 double GetNextSimulatedEventTimeSeconds() {
478 last_simulated_event_time_seconds_
+= simulated_event_time_delta_seconds_
;
479 return last_simulated_event_time_seconds_
;
482 void SimulateKeyboardEvent(WebInputEvent::Type type
) {
483 SimulateKeyboardEvent(type
, 0);
486 void SimulateKeyboardEvent(WebInputEvent::Type type
, int modifiers
) {
487 WebKeyboardEvent event
= SyntheticWebKeyboardEventBuilder::Build(type
);
488 event
.modifiers
= modifiers
;
489 NativeWebKeyboardEvent native_event
;
490 memcpy(&native_event
, &event
, sizeof(event
));
491 host_
->ForwardKeyboardEvent(native_event
);
494 void SimulateMouseEvent(WebInputEvent::Type type
) {
495 host_
->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type
));
498 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type
,
499 const ui::LatencyInfo
& ui_latency
) {
500 host_
->ForwardMouseEventWithLatencyInfo(
501 SyntheticWebMouseEventBuilder::Build(type
),
505 void SimulateWheelEvent(float dX
, float dY
, int modifiers
, bool precise
) {
506 host_
->ForwardWheelEvent(
507 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
));
510 void SimulateWheelEventWithLatencyInfo(float dX
,
514 const ui::LatencyInfo
& ui_latency
) {
515 host_
->ForwardWheelEventWithLatencyInfo(
516 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
),
520 void SimulateMouseMove(int x
, int y
, int modifiers
) {
521 SimulateMouseEvent(WebInputEvent::MouseMove
, x
, y
, modifiers
, false);
524 void SimulateMouseEvent(
525 WebInputEvent::Type type
, int x
, int y
, int modifiers
, bool pressed
) {
526 WebMouseEvent event
=
527 SyntheticWebMouseEventBuilder::Build(type
, x
, y
, modifiers
);
529 event
.button
= WebMouseEvent::ButtonLeft
;
530 event
.timeStampSeconds
= GetNextSimulatedEventTimeSeconds();
531 host_
->ForwardMouseEvent(event
);
534 // Inject simple synthetic WebGestureEvent instances.
535 void SimulateGestureEvent(WebInputEvent::Type type
,
536 WebGestureDevice sourceDevice
) {
537 host_
->ForwardGestureEvent(
538 SyntheticWebGestureEventBuilder::Build(type
, sourceDevice
));
541 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type
,
542 WebGestureDevice sourceDevice
,
543 const ui::LatencyInfo
& ui_latency
) {
544 host_
->ForwardGestureEventWithLatencyInfo(
545 SyntheticWebGestureEventBuilder::Build(type
, sourceDevice
),
549 // Set the timestamp for the touch-event.
550 void SetTouchTimestamp(base::TimeDelta timestamp
) {
551 touch_event_
.SetTimestamp(timestamp
);
554 // Sends a touch event (irrespective of whether the page has a touch-event
556 uint32
SendTouchEvent() {
557 uint32 touch_event_id
= touch_event_
.uniqueTouchEventId
;
558 host_
->ForwardTouchEventWithLatencyInfo(touch_event_
, ui::LatencyInfo());
560 touch_event_
.ResetPoints();
561 return touch_event_id
;
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 base::PickleIterator
iter(message
);
580 if (!iter
.ReadData(&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, so setting it to the same thing
619 // 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 // No resize ack if the physical backing gets set, but the view bounds are
627 view_
->SetMockPhysicalBackingSize(gfx::Size(200, 200));
629 EXPECT_FALSE(host_
->resize_ack_pending_
);
631 // Setting the view bounds to nonzero should send out the notification.
632 // but should not expect ack for empty physical backing size.
633 gfx::Rect
original_size(0, 0, 100, 100);
634 process_
->sink().ClearMessages();
635 view_
->set_bounds(original_size
);
636 view_
->SetMockPhysicalBackingSize(gfx::Size());
638 EXPECT_FALSE(host_
->resize_ack_pending_
);
639 EXPECT_EQ(original_size
.size(), host_
->old_resize_params_
->new_size
);
640 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
642 // Setting the bounds and physical backing size to nonzero should send out
643 // the notification and expect an ack.
644 process_
->sink().ClearMessages();
645 view_
->ClearMockPhysicalBackingSize();
647 EXPECT_TRUE(host_
->resize_ack_pending_
);
648 EXPECT_EQ(original_size
.size(), host_
->old_resize_params_
->new_size
);
649 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
650 ViewHostMsg_UpdateRect_Params params
;
651 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
652 params
.view_size
= original_size
.size();
653 host_
->OnUpdateRect(params
);
654 EXPECT_FALSE(host_
->resize_ack_pending_
);
656 // Send out a update that's not a resize ack after setting resize ack pending
657 // flag. This should not clean the resize ack pending flag.
658 process_
->sink().ClearMessages();
659 gfx::Rect
second_size(0, 0, 110, 110);
660 EXPECT_FALSE(host_
->resize_ack_pending_
);
661 view_
->set_bounds(second_size
);
663 EXPECT_TRUE(host_
->resize_ack_pending_
);
665 params
.view_size
= gfx::Size(100, 100);
666 host_
->OnUpdateRect(params
);
667 EXPECT_TRUE(host_
->resize_ack_pending_
);
668 EXPECT_EQ(second_size
.size(), host_
->old_resize_params_
->new_size
);
670 // Sending out a new notification should NOT send out a new IPC message since
671 // a resize ACK is pending.
672 gfx::Rect
third_size(0, 0, 120, 120);
673 process_
->sink().ClearMessages();
674 view_
->set_bounds(third_size
);
676 EXPECT_TRUE(host_
->resize_ack_pending_
);
677 EXPECT_EQ(second_size
.size(), host_
->old_resize_params_
->new_size
);
678 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
680 // Send a update that's a resize ack, but for the original_size we sent. Since
681 // this isn't the second_size, the message handler should immediately send
682 // a new resize message for the new size to the renderer.
683 process_
->sink().ClearMessages();
684 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
685 params
.view_size
= original_size
.size();
686 host_
->OnUpdateRect(params
);
687 EXPECT_TRUE(host_
->resize_ack_pending_
);
688 EXPECT_EQ(third_size
.size(), host_
->old_resize_params_
->new_size
);
689 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
691 // Send the resize ack for the latest size.
692 process_
->sink().ClearMessages();
693 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
694 params
.view_size
= third_size
.size();
695 host_
->OnUpdateRect(params
);
696 EXPECT_FALSE(host_
->resize_ack_pending_
);
697 EXPECT_EQ(third_size
.size(), host_
->old_resize_params_
->new_size
);
698 EXPECT_FALSE(process_
->sink().GetFirstMessageMatching(ViewMsg_Resize::ID
));
700 // Now clearing the bounds should send out a notification but we shouldn't
701 // expect a resize ack (since the renderer won't ack empty sizes). The message
702 // should contain the new size (0x0) and not the previous one that we skipped
703 process_
->sink().ClearMessages();
704 view_
->set_bounds(gfx::Rect());
706 EXPECT_FALSE(host_
->resize_ack_pending_
);
707 EXPECT_EQ(gfx::Size(), host_
->old_resize_params_
->new_size
);
708 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
710 // Send a rect that has no area but has either width or height set.
711 process_
->sink().ClearMessages();
712 view_
->set_bounds(gfx::Rect(0, 0, 0, 30));
714 EXPECT_FALSE(host_
->resize_ack_pending_
);
715 EXPECT_EQ(gfx::Size(0, 30), host_
->old_resize_params_
->new_size
);
716 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
718 // Set the same size again. It should not be sent again.
719 process_
->sink().ClearMessages();
721 EXPECT_FALSE(host_
->resize_ack_pending_
);
722 EXPECT_EQ(gfx::Size(0, 30), host_
->old_resize_params_
->new_size
);
723 EXPECT_FALSE(process_
->sink().GetFirstMessageMatching(ViewMsg_Resize::ID
));
725 // A different size should be sent again, however.
726 view_
->set_bounds(gfx::Rect(0, 0, 0, 31));
728 EXPECT_FALSE(host_
->resize_ack_pending_
);
729 EXPECT_EQ(gfx::Size(0, 31), host_
->old_resize_params_
->new_size
);
730 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
733 // Test that a resize event is sent if WasResized() is called after a
734 // WebScreenInfo change.
735 TEST_F(RenderWidgetHostTest
, ResizeScreenInfo
) {
736 blink::WebScreenInfo screen_info
;
737 screen_info
.deviceScaleFactor
= 1.f
;
738 screen_info
.rect
= blink::WebRect(0, 0, 800, 600);
739 screen_info
.availableRect
= blink::WebRect(0, 0, 800, 600);
740 screen_info
.orientationAngle
= 0;
741 screen_info
.orientationType
= blink::WebScreenOrientationPortraitPrimary
;
743 view_
->SetScreenInfo(screen_info
);
745 EXPECT_FALSE(host_
->resize_ack_pending_
);
746 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
747 process_
->sink().ClearMessages();
749 screen_info
.orientationAngle
= 180;
750 screen_info
.orientationType
= blink::WebScreenOrientationLandscapePrimary
;
752 view_
->SetScreenInfo(screen_info
);
754 EXPECT_FALSE(host_
->resize_ack_pending_
);
755 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
756 process_
->sink().ClearMessages();
758 screen_info
.deviceScaleFactor
= 2.f
;
760 view_
->SetScreenInfo(screen_info
);
762 EXPECT_FALSE(host_
->resize_ack_pending_
);
763 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
764 process_
->sink().ClearMessages();
767 view_
->SetScreenInfo(screen_info
);
769 EXPECT_FALSE(host_
->resize_ack_pending_
);
770 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
773 // Test for crbug.com/25097. If a renderer crashes between a resize and the
774 // corresponding update message, we must be sure to clear the resize ack logic.
775 TEST_F(RenderWidgetHostTest
, ResizeThenCrash
) {
776 // Clear the first Resize message that carried screen info.
777 process_
->sink().ClearMessages();
779 // Setting the bounds to a "real" rect should send out the notification.
780 gfx::Rect
original_size(0, 0, 100, 100);
781 view_
->set_bounds(original_size
);
783 EXPECT_TRUE(host_
->resize_ack_pending_
);
784 EXPECT_EQ(original_size
.size(), host_
->old_resize_params_
->new_size
);
785 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
787 // Simulate a renderer crash before the update message. Ensure all the
788 // resize ack logic is cleared. Must clear the view first so it doesn't get
790 host_
->SetView(NULL
);
791 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
792 EXPECT_FALSE(host_
->resize_ack_pending_
);
793 EXPECT_EQ(gfx::Size(), host_
->old_resize_params_
->new_size
);
795 // Reset the view so we can exit the test cleanly.
796 host_
->SetView(view_
.get());
799 // Unable to include render_widget_host_view_mac.h and compile.
800 #if !defined(OS_MACOSX)
801 // Tests setting background transparency.
802 TEST_F(RenderWidgetHostTest
, Background
) {
803 scoped_ptr
<RenderWidgetHostViewBase
> view
;
804 #if defined(USE_AURA)
805 view
.reset(new RenderWidgetHostViewAura(host_
.get(), false));
806 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
807 view
->InitAsChild(NULL
);
808 #elif defined(OS_ANDROID)
809 view
.reset(new RenderWidgetHostViewAndroid(host_
.get(), NULL
));
811 host_
->SetView(view
.get());
813 EXPECT_TRUE(view
->GetBackgroundOpaque());
814 view
->SetBackgroundColor(SK_ColorTRANSPARENT
);
815 EXPECT_FALSE(view
->GetBackgroundOpaque());
817 const IPC::Message
* set_background
=
818 process_
->sink().GetUniqueMessageMatching(
819 ViewMsg_SetBackgroundOpaque::ID
);
820 ASSERT_TRUE(set_background
);
821 base::Tuple
<bool> sent_background
;
822 ViewMsg_SetBackgroundOpaque::Read(set_background
, &sent_background
);
823 EXPECT_FALSE(base::get
<0>(sent_background
));
825 #if defined(USE_AURA)
826 // See the comment above |InitAsChild(NULL)|.
827 host_
->SetView(NULL
);
828 static_cast<RenderWidgetHostViewBase
*>(view
.release())->Destroy();
833 // Test that we don't paint when we're hidden, but we still send the ACK. Most
834 // of the rest of the painting is tested in the GetBackingStore* ones.
835 TEST_F(RenderWidgetHostTest
, HiddenPaint
) {
836 BrowserThreadImpl
ui_thread(BrowserThread::UI
, base::MessageLoop::current());
837 // Hide the widget, it should have sent out a message to the renderer.
838 EXPECT_FALSE(host_
->is_hidden_
);
840 EXPECT_TRUE(host_
->is_hidden_
);
841 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID
));
843 // Send it an update as from the renderer.
844 process_
->sink().ClearMessages();
845 ViewHostMsg_UpdateRect_Params params
;
846 params
.view_size
= gfx::Size(100, 100);
847 host_
->OnUpdateRect(params
);
850 process_
->sink().ClearMessages();
851 host_
->WasShown(ui::LatencyInfo());
852 EXPECT_FALSE(host_
->is_hidden_
);
854 // It should have sent out a restored message with a request to paint.
855 const IPC::Message
* restored
= process_
->sink().GetUniqueMessageMatching(
856 ViewMsg_WasShown::ID
);
857 ASSERT_TRUE(restored
);
858 base::Tuple
<bool, ui::LatencyInfo
> needs_repaint
;
859 ViewMsg_WasShown::Read(restored
, &needs_repaint
);
860 EXPECT_TRUE(base::get
<0>(needs_repaint
));
863 TEST_F(RenderWidgetHostTest
, IgnoreKeyEventsHandledByRenderer
) {
864 // Simulate a keyboard event.
865 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
867 // Make sure we sent the input event to the renderer.
868 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
869 InputMsg_HandleInputEvent::ID
));
870 process_
->sink().ClearMessages();
872 // Send the simulated response from the renderer back.
873 SendInputEventACK(WebInputEvent::RawKeyDown
,
874 INPUT_EVENT_ACK_STATE_CONSUMED
);
875 EXPECT_FALSE(delegate_
->unhandled_keyboard_event_called());
878 TEST_F(RenderWidgetHostTest
, PreHandleRawKeyDownEvent
) {
879 // Simluate the situation that the browser handled the key down event during
880 // pre-handle phrase.
881 delegate_
->set_prehandle_keyboard_event(true);
882 process_
->sink().ClearMessages();
884 // Simulate a keyboard event.
885 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
887 EXPECT_TRUE(delegate_
->prehandle_keyboard_event_called());
888 EXPECT_EQ(WebInputEvent::RawKeyDown
,
889 delegate_
->prehandle_keyboard_event_type());
891 // Make sure the RawKeyDown event is not sent to the renderer.
892 EXPECT_EQ(0U, process_
->sink().message_count());
894 // The browser won't pre-handle a Char event.
895 delegate_
->set_prehandle_keyboard_event(false);
897 // Forward the Char event.
898 SimulateKeyboardEvent(WebInputEvent::Char
);
900 // Make sure the Char event is suppressed.
901 EXPECT_EQ(0U, process_
->sink().message_count());
903 // Forward the KeyUp event.
904 SimulateKeyboardEvent(WebInputEvent::KeyUp
);
906 // Make sure only KeyUp was sent to the renderer.
907 EXPECT_EQ(1U, process_
->sink().message_count());
908 EXPECT_EQ(InputMsg_HandleInputEvent::ID
,
909 process_
->sink().GetMessageAt(0)->type());
910 process_
->sink().ClearMessages();
912 // Send the simulated response from the renderer back.
913 SendInputEventACK(WebInputEvent::KeyUp
,
914 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
916 EXPECT_TRUE(delegate_
->unhandled_keyboard_event_called());
917 EXPECT_EQ(WebInputEvent::KeyUp
, delegate_
->unhandled_keyboard_event_type());
920 TEST_F(RenderWidgetHostTest
, UnhandledWheelEvent
) {
921 SimulateWheelEvent(-5, 0, 0, true);
923 // Make sure we sent the input event to the renderer.
924 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
925 InputMsg_HandleInputEvent::ID
));
926 process_
->sink().ClearMessages();
928 // Send the simulated response from the renderer back.
929 SendInputEventACK(WebInputEvent::MouseWheel
,
930 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
931 EXPECT_TRUE(delegate_
->handle_wheel_event_called());
932 EXPECT_EQ(1, view_
->unhandled_wheel_event_count());
933 EXPECT_EQ(-5, view_
->unhandled_wheel_event().deltaX
);
936 TEST_F(RenderWidgetHostTest
, HandleWheelEvent
) {
937 // Indicate that we're going to handle this wheel event
938 delegate_
->set_handle_wheel_event(true);
940 SimulateWheelEvent(-5, 0, 0, true);
942 // Make sure we sent the input event to the renderer.
943 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
944 InputMsg_HandleInputEvent::ID
));
945 process_
->sink().ClearMessages();
947 // Send the simulated response from the renderer back.
948 SendInputEventACK(WebInputEvent::MouseWheel
,
949 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
951 // ensure the wheel event handler was invoked
952 EXPECT_TRUE(delegate_
->handle_wheel_event_called());
954 // and that it suppressed the unhandled wheel event handler.
955 EXPECT_EQ(0, view_
->unhandled_wheel_event_count());
958 TEST_F(RenderWidgetHostTest
, UnhandledGestureEvent
) {
959 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap
,
960 blink::WebGestureDeviceTouchscreen
);
962 // Make sure we sent the input event to the renderer.
963 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
964 InputMsg_HandleInputEvent::ID
));
965 process_
->sink().ClearMessages();
967 // Send the simulated response from the renderer back.
968 SendInputEventACK(WebInputEvent::GestureTwoFingerTap
,
969 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
970 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap
, view_
->gesture_event_type());
971 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED
, view_
->ack_result());
974 // Test that the hang monitor timer expires properly if a new timer is started
975 // while one is in progress (see crbug.com/11007).
976 TEST_F(RenderWidgetHostTest
, DontPostponeHangMonitorTimeout
) {
977 // Start with a short timeout.
978 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
980 // Immediately try to add a long 30 second timeout.
981 EXPECT_FALSE(host_
->unresponsive_timer_fired());
982 host_
->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
984 // Wait long enough for first timeout and see if it fired.
985 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
986 FROM_HERE
, base::MessageLoop::QuitClosure(),
987 TimeDelta::FromMilliseconds(10));
988 base::MessageLoop::current()->Run();
989 EXPECT_TRUE(host_
->unresponsive_timer_fired());
992 // Test that the hang monitor timer expires properly if it is started, stopped,
993 // and then started again.
994 TEST_F(RenderWidgetHostTest
, StopAndStartHangMonitorTimeout
) {
995 // Start with a short timeout, then stop it.
996 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
997 host_
->StopHangMonitorTimeout();
999 // Start it again to ensure it still works.
1000 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1001 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1003 // Wait long enough for first timeout and see if it fired.
1004 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1005 FROM_HERE
, base::MessageLoop::QuitClosure(),
1006 TimeDelta::FromMilliseconds(40));
1007 base::MessageLoop::current()->Run();
1008 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1011 // Test that the hang monitor timer expires properly if it is started, then
1012 // updated to a shorter duration.
1013 TEST_F(RenderWidgetHostTest
, ShorterDelayHangMonitorTimeout
) {
1014 // Start with a timeout.
1015 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
1017 // Start it again with shorter delay.
1018 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1019 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
1021 // Wait long enough for the second timeout and see if it fired.
1022 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1023 FROM_HERE
, base::MessageLoop::QuitClosure(),
1024 TimeDelta::FromMilliseconds(25));
1025 base::MessageLoop::current()->Run();
1026 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1029 // Test that the hang monitor timer is effectively disabled when the widget is
1031 TEST_F(RenderWidgetHostTest
, HangMonitorTimeoutDisabledForInputWhenHidden
) {
1032 host_
->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(1));
1033 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1035 // Hiding the widget should deactivate the timeout.
1038 // The timeout should not fire.
1039 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1040 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1041 FROM_HERE
, base::MessageLoop::QuitClosure(),
1042 TimeDelta::FromMicroseconds(2));
1043 base::MessageLoop::current()->Run();
1044 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1046 // The timeout should never reactivate while hidden.
1047 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1048 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1049 FROM_HERE
, base::MessageLoop::QuitClosure(),
1050 TimeDelta::FromMicroseconds(2));
1051 base::MessageLoop::current()->Run();
1052 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1054 // Showing the widget should restore the timeout, as the events have
1055 // not yet been ack'ed.
1056 host_
->WasShown(ui::LatencyInfo());
1057 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1058 FROM_HERE
, base::MessageLoop::QuitClosure(),
1059 TimeDelta::FromMicroseconds(2));
1060 base::MessageLoop::current()->Run();
1061 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1064 // Test that the hang monitor catches two input events but only one ack.
1065 // This can happen if the second input event causes the renderer to hang.
1066 // This test will catch a regression of crbug.com/111185.
1067 TEST_F(RenderWidgetHostTest
, MultipleInputEvents
) {
1068 // Configure the host to wait 10ms before considering
1069 // the renderer hung.
1070 host_
->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(10));
1072 // Send two events but only one ack.
1073 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1074 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1075 SendInputEventACK(WebInputEvent::RawKeyDown
,
1076 INPUT_EVENT_ACK_STATE_CONSUMED
);
1078 // Wait long enough for first timeout and see if it fired.
1079 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1080 FROM_HERE
, base::MessageLoop::QuitClosure(),
1081 TimeDelta::FromMicroseconds(20));
1082 base::MessageLoop::current()->Run();
1083 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1086 std::string
GetInputMessageTypes(RenderWidgetHostProcess
* process
) {
1088 for (size_t i
= 0; i
< process
->sink().message_count(); ++i
) {
1089 const IPC::Message
*message
= process
->sink().GetMessageAt(i
);
1090 EXPECT_EQ(InputMsg_HandleInputEvent::ID
, message
->type());
1091 InputMsg_HandleInputEvent::Param params
;
1092 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message
, ¶ms
));
1093 const WebInputEvent
* event
= base::get
<0>(params
);
1096 result
+= WebInputEventTraits::GetName(event
->type
);
1098 process
->sink().ClearMessages();
1102 TEST_F(RenderWidgetHostTest
, TouchEmulator
) {
1103 simulated_event_time_delta_seconds_
= 0.1;
1104 // Immediately ack all touches instead of sending them to the renderer.
1105 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1106 host_
->SetTouchEventEmulationEnabled(
1107 true, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1108 process_
->sink().ClearMessages();
1109 view_
->set_bounds(gfx::Rect(0, 0, 400, 200));
1112 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1113 EXPECT_EQ(0U, process_
->sink().message_count());
1115 // Mouse press becomes touch start which in turn becomes tap.
1116 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 10, 0, true);
1117 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1118 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1120 // Mouse drag generates touch move, cancels tap and starts scroll.
1121 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 30, 0, true);
1122 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1124 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1125 GetInputMessageTypes(process_
));
1126 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1127 INPUT_EVENT_ACK_STATE_CONSUMED
);
1128 EXPECT_EQ(0U, process_
->sink().message_count());
1130 // Mouse drag with shift becomes pinch.
1132 WebInputEvent::MouseMove
, 10, 40, WebInputEvent::ShiftKey
, true);
1133 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1134 EXPECT_EQ("GesturePinchBegin",
1135 GetInputMessageTypes(process_
));
1136 EXPECT_EQ(0U, process_
->sink().message_count());
1139 WebInputEvent::MouseMove
, 10, 50, WebInputEvent::ShiftKey
, true);
1140 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1141 EXPECT_EQ("GesturePinchUpdate",
1142 GetInputMessageTypes(process_
));
1143 SendInputEventACK(WebInputEvent::GesturePinchUpdate
,
1144 INPUT_EVENT_ACK_STATE_CONSUMED
);
1145 EXPECT_EQ(0U, process_
->sink().message_count());
1147 // Mouse drag without shift becomes scroll again.
1148 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 60, 0, true);
1149 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1150 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1151 GetInputMessageTypes(process_
));
1152 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1153 INPUT_EVENT_ACK_STATE_CONSUMED
);
1154 EXPECT_EQ(0U, process_
->sink().message_count());
1156 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 70, 0, true);
1157 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1158 EXPECT_EQ("GestureScrollUpdate",
1159 GetInputMessageTypes(process_
));
1160 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1161 INPUT_EVENT_ACK_STATE_CONSUMED
);
1162 EXPECT_EQ(0U, process_
->sink().message_count());
1164 SimulateMouseEvent(WebInputEvent::MouseUp
, 10, 70, 0, true);
1165 EXPECT_EQ(WebInputEvent::TouchEnd
, host_
->acked_touch_event_type());
1166 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_
));
1167 EXPECT_EQ(0U, process_
->sink().message_count());
1169 // Mouse move does nothing.
1170 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 80, 0, false);
1171 EXPECT_EQ(0U, process_
->sink().message_count());
1173 // Another mouse down continues scroll.
1174 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 80, 0, true);
1175 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1176 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1177 EXPECT_EQ(0U, process_
->sink().message_count());
1179 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 100, 0, true);
1180 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1182 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1183 GetInputMessageTypes(process_
));
1184 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1185 INPUT_EVENT_ACK_STATE_CONSUMED
);
1186 EXPECT_EQ(0U, process_
->sink().message_count());
1190 WebInputEvent::MouseMove
, 10, 110, WebInputEvent::ShiftKey
, true);
1191 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1192 EXPECT_EQ("GesturePinchBegin",
1193 GetInputMessageTypes(process_
));
1194 EXPECT_EQ(0U, process_
->sink().message_count());
1197 WebInputEvent::MouseMove
, 10, 120, WebInputEvent::ShiftKey
, true);
1198 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1199 EXPECT_EQ("GesturePinchUpdate",
1200 GetInputMessageTypes(process_
));
1201 SendInputEventACK(WebInputEvent::GesturePinchUpdate
,
1202 INPUT_EVENT_ACK_STATE_CONSUMED
);
1203 EXPECT_EQ(0U, process_
->sink().message_count());
1205 // Turn off emulation during a pinch.
1206 host_
->SetTouchEventEmulationEnabled(
1207 false, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1208 EXPECT_EQ(WebInputEvent::TouchCancel
, host_
->acked_touch_event_type());
1209 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1210 GetInputMessageTypes(process_
));
1211 EXPECT_EQ(0U, process_
->sink().message_count());
1213 // Mouse event should pass untouched.
1215 WebInputEvent::MouseMove
, 10, 10, WebInputEvent::ShiftKey
, true);
1216 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_
));
1217 SendInputEventACK(WebInputEvent::MouseMove
,
1218 INPUT_EVENT_ACK_STATE_CONSUMED
);
1219 EXPECT_EQ(0U, process_
->sink().message_count());
1221 // Turn on emulation.
1222 host_
->SetTouchEventEmulationEnabled(
1223 true, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1224 EXPECT_EQ(0U, process_
->sink().message_count());
1227 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 10, 0, true);
1228 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1229 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1230 EXPECT_EQ(0U, process_
->sink().message_count());
1233 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 30, 0, true);
1234 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1236 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1237 GetInputMessageTypes(process_
));
1238 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1239 INPUT_EVENT_ACK_STATE_CONSUMED
);
1241 // Turn off emulation during a scroll.
1242 host_
->SetTouchEventEmulationEnabled(
1243 false, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1244 EXPECT_EQ(WebInputEvent::TouchCancel
, host_
->acked_touch_event_type());
1246 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_
));
1247 EXPECT_EQ(0U, process_
->sink().message_count());
1250 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1251 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1252 host_->SetupForInputRouterTest(); \
1253 host_->INPUTMSG(); \
1254 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1257 TEST_InputRouterRoutes_NOARGS(Focus
);
1258 TEST_InputRouterRoutes_NOARGS(Blur
);
1259 TEST_InputRouterRoutes_NOARGS(LostCapture
);
1261 #undef TEST_InputRouterRoutes_NOARGS
1263 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1264 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1265 host_->SetupForInputRouterTest(); \
1266 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1267 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1270 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo
);
1271 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo
);
1272 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut
);
1273 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy
);
1274 #if defined(OS_MACOSX)
1275 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard
);
1277 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste
);
1278 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle
);
1279 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete
);
1280 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll
);
1281 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect
);
1283 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1285 TEST_F(RenderWidgetHostTest
, InputRouterRoutesReplace
) {
1286 host_
->SetupForInputRouterTest();
1287 host_
->Send(new InputMsg_Replace(host_
->GetRoutingID(), base::string16()));
1288 EXPECT_TRUE(host_
->mock_input_router()->send_event_called_
);
1291 TEST_F(RenderWidgetHostTest
, InputRouterRoutesReplaceMisspelling
) {
1292 host_
->SetupForInputRouterTest();
1293 host_
->Send(new InputMsg_ReplaceMisspelling(host_
->GetRoutingID(),
1295 EXPECT_TRUE(host_
->mock_input_router()->send_event_called_
);
1298 TEST_F(RenderWidgetHostTest
, IgnoreInputEvent
) {
1299 host_
->SetupForInputRouterTest();
1301 host_
->SetIgnoreInputEvents(true);
1303 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1304 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1306 SimulateMouseEvent(WebInputEvent::MouseMove
);
1307 EXPECT_FALSE(host_
->mock_input_router()->sent_mouse_event_
);
1309 SimulateWheelEvent(0, 100, 0, true);
1310 EXPECT_FALSE(host_
->mock_input_router()->sent_wheel_event_
);
1312 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
1313 blink::WebGestureDeviceTouchpad
);
1314 EXPECT_FALSE(host_
->mock_input_router()->sent_gesture_event_
);
1316 PressTouchPoint(100, 100);
1318 EXPECT_FALSE(host_
->mock_input_router()->send_touch_event_not_cancelled_
);
1321 TEST_F(RenderWidgetHostTest
, KeyboardListenerIgnoresEvent
) {
1322 host_
->SetupForInputRouterTest();
1323 host_
->AddKeyPressEventCallback(
1324 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback
,
1325 base::Unretained(this)));
1326 handle_key_press_event_
= false;
1327 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1329 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1332 TEST_F(RenderWidgetHostTest
, KeyboardListenerSuppressFollowingEvents
) {
1333 host_
->SetupForInputRouterTest();
1335 host_
->AddKeyPressEventCallback(
1336 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback
,
1337 base::Unretained(this)));
1339 // The callback handles the first event
1340 handle_key_press_event_
= true;
1341 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1343 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1345 // Following Char events should be suppressed
1346 handle_key_press_event_
= false;
1347 SimulateKeyboardEvent(WebInputEvent::Char
);
1348 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1349 SimulateKeyboardEvent(WebInputEvent::Char
);
1350 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1352 // Sending RawKeyDown event should stop suppression
1353 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1354 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1356 host_
->mock_input_router()->sent_keyboard_event_
= false;
1357 SimulateKeyboardEvent(WebInputEvent::Char
);
1358 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1361 TEST_F(RenderWidgetHostTest
, MouseEventCallbackCanHandleEvent
) {
1362 host_
->SetupForInputRouterTest();
1364 host_
->AddMouseEventCallback(
1365 base::Bind(&RenderWidgetHostTest::MouseEventCallback
,
1366 base::Unretained(this)));
1368 handle_mouse_event_
= true;
1369 SimulateMouseEvent(WebInputEvent::MouseDown
);
1371 EXPECT_FALSE(host_
->mock_input_router()->sent_mouse_event_
);
1373 handle_mouse_event_
= false;
1374 SimulateMouseEvent(WebInputEvent::MouseDown
);
1376 EXPECT_TRUE(host_
->mock_input_router()->sent_mouse_event_
);
1379 TEST_F(RenderWidgetHostTest
, InputRouterReceivesHandleInputEvent_ACK
) {
1380 host_
->SetupForInputRouterTest();
1382 SendInputEventACK(WebInputEvent::RawKeyDown
,
1383 INPUT_EVENT_ACK_STATE_CONSUMED
);
1385 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1388 TEST_F(RenderWidgetHostTest
, InputRouterReceivesMoveCaret_ACK
) {
1389 host_
->SetupForInputRouterTest();
1391 host_
->OnMessageReceived(InputHostMsg_MoveCaret_ACK(0));
1393 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1396 TEST_F(RenderWidgetHostTest
, InputRouterReceivesSelectRange_ACK
) {
1397 host_
->SetupForInputRouterTest();
1399 host_
->OnMessageReceived(InputHostMsg_SelectRange_ACK(0));
1401 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1404 TEST_F(RenderWidgetHostTest
, InputRouterReceivesHasTouchEventHandlers
) {
1405 host_
->SetupForInputRouterTest();
1407 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1409 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1412 ui::LatencyInfo
GetLatencyInfoFromInputEvent(RenderWidgetHostProcess
* process
) {
1413 const IPC::Message
* message
= process
->sink().GetUniqueMessageMatching(
1414 InputMsg_HandleInputEvent::ID
);
1415 EXPECT_TRUE(message
);
1416 InputMsg_HandleInputEvent::Param params
;
1417 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message
, ¶ms
));
1418 process
->sink().ClearMessages();
1419 return base::get
<1>(params
);
1422 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess
* process
,
1424 WebInputEvent::Type input_type
) {
1425 ui::LatencyInfo latency_info
= GetLatencyInfoFromInputEvent(process
);
1426 EXPECT_TRUE(latency_info
.FindLatency(
1427 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
,
1432 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1433 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1434 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1435 // event's LatencyInfo.
1436 TEST_F(RenderWidgetHostTest
, InputEventRWHLatencyComponent
) {
1437 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1438 process_
->sink().ClearMessages();
1440 // Tests RWHI::ForwardWheelEvent().
1441 SimulateWheelEvent(-5, 0, 0, true);
1442 CheckLatencyInfoComponentInMessage(
1443 process_
, GetLatencyComponentId(), WebInputEvent::MouseWheel
);
1444 SendInputEventACK(WebInputEvent::MouseWheel
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1446 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1447 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1448 CheckLatencyInfoComponentInMessage(
1449 process_
, GetLatencyComponentId(), WebInputEvent::MouseWheel
);
1450 SendInputEventACK(WebInputEvent::MouseWheel
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1452 // Tests RWHI::ForwardMouseEvent().
1453 SimulateMouseEvent(WebInputEvent::MouseMove
);
1454 CheckLatencyInfoComponentInMessage(
1455 process_
, GetLatencyComponentId(), WebInputEvent::MouseMove
);
1456 SendInputEventACK(WebInputEvent::MouseMove
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1458 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1459 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove
,
1461 CheckLatencyInfoComponentInMessage(
1462 process_
, GetLatencyComponentId(), WebInputEvent::MouseMove
);
1463 SendInputEventACK(WebInputEvent::MouseMove
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1465 // Tests RWHI::ForwardGestureEvent().
1466 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
1467 blink::WebGestureDeviceTouchscreen
);
1468 CheckLatencyInfoComponentInMessage(
1469 process_
, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin
);
1471 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1472 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate
,
1473 blink::WebGestureDeviceTouchscreen
,
1475 CheckLatencyInfoComponentInMessage(
1476 process_
, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate
);
1477 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1478 INPUT_EVENT_ACK_STATE_CONSUMED
);
1480 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1481 PressTouchPoint(0, 1);
1482 uint32 touch_event_id
= SendTouchEvent();
1483 InputEventAck
ack(WebInputEvent::TouchStart
, INPUT_EVENT_ACK_STATE_CONSUMED
,
1485 host_
->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack
));
1486 CheckLatencyInfoComponentInMessage(
1487 process_
, GetLatencyComponentId(), WebInputEvent::TouchStart
);
1490 TEST_F(RenderWidgetHostTest
, RendererExitedResetsInputRouter
) {
1491 // RendererExited will delete the view.
1492 host_
->SetView(new TestView(host_
.get()));
1493 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
1495 // Make sure the input router is in a fresh state.
1496 ASSERT_FALSE(host_
->input_router()->HasPendingEvents());
1499 // Regression test for http://crbug.com/401859.
1500 TEST_F(RenderWidgetHostTest
, RendererExitedResetsIsHidden
) {
1501 // RendererExited will delete the view.
1502 host_
->SetView(new TestView(host_
.get()));
1505 ASSERT_TRUE(host_
->is_hidden());
1506 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
1507 ASSERT_FALSE(host_
->is_hidden());
1509 // Make sure the input router is in a fresh state.
1510 ASSERT_FALSE(host_
->input_router()->HasPendingEvents());
1513 TEST_F(RenderWidgetHostTest
, ResizeParams
) {
1514 gfx::Rect
bounds(0, 0, 100, 100);
1515 gfx::Size
physical_backing_size(40, 50);
1516 view_
->set_bounds(bounds
);
1517 view_
->SetMockPhysicalBackingSize(physical_backing_size
);
1519 ViewMsg_Resize_Params resize_params
;
1520 host_
->GetResizeParams(&resize_params
);
1521 EXPECT_EQ(bounds
.size(), resize_params
.new_size
);
1522 EXPECT_EQ(physical_backing_size
, resize_params
.physical_backing_size
);
1525 class RenderWidgetHostInitialSizeTest
: public RenderWidgetHostTest
{
1527 RenderWidgetHostInitialSizeTest()
1528 : RenderWidgetHostTest(), initial_size_(200, 100) {}
1530 void ConfigureView(TestView
* view
) override
{
1531 view
->set_bounds(gfx::Rect(initial_size_
));
1535 gfx::Size initial_size_
;
1538 TEST_F(RenderWidgetHostInitialSizeTest
, InitialSize
) {
1539 // Having an initial size set means that the size information had been sent
1540 // with the reqiest to new up the RenderView and so subsequent WasResized
1541 // calls should not result in new IPC (unless the size has actually changed).
1542 host_
->WasResized();
1543 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
1544 EXPECT_EQ(initial_size_
, host_
->old_resize_params_
->new_size
);
1545 EXPECT_TRUE(host_
->resize_ack_pending_
);
1548 } // namespace content