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/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "base/timer/timer.h"
13 #include "content/browser/browser_thread_impl.h"
14 #include "content/browser/gpu/compositor_util.h"
15 #include "content/browser/gpu/gpu_surface_tracker.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/test/test_screen.h"
43 #include "ui/events/event.h"
46 using base::TimeDelta
;
47 using blink::WebGestureDevice
;
48 using blink::WebGestureEvent
;
49 using blink::WebInputEvent
;
50 using blink::WebKeyboardEvent
;
51 using blink::WebMouseEvent
;
52 using blink::WebMouseWheelEvent
;
53 using blink::WebTouchEvent
;
54 using blink::WebTouchPoint
;
58 // MockInputRouter -------------------------------------------------------------
60 class MockInputRouter
: public InputRouter
{
62 explicit MockInputRouter(InputRouterClient
* client
)
63 : send_event_called_(false),
64 sent_mouse_event_(false),
65 sent_wheel_event_(false),
66 sent_keyboard_event_(false),
67 sent_gesture_event_(false),
68 send_touch_event_not_cancelled_(false),
69 message_received_(false),
72 ~MockInputRouter() override
{}
75 bool SendInput(scoped_ptr
<IPC::Message
> message
) override
{
76 send_event_called_
= true;
79 void SendMouseEvent(const MouseEventWithLatencyInfo
& mouse_event
) override
{
80 sent_mouse_event_
= true;
83 const MouseWheelEventWithLatencyInfo
& wheel_event
) override
{
84 sent_wheel_event_
= true;
86 void SendKeyboardEvent(const NativeWebKeyboardEventWithLatencyInfo
& key_event
,
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 NotifySiteIsMobileOptimized(bool is_mobile_optimized
) override
{}
104 void RequestNotificationWhenFlushed() override
{}
105 bool HasPendingEvents() const override
{ return false; }
108 bool OnMessageReceived(const IPC::Message
& message
) override
{
109 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(RenderWidgetHostDelegate
* delegate
,
132 RenderProcessHost
* process
,
134 : RenderWidgetHostImpl(
138 GpuSurfaceTracker::Get()->AddSurfaceForRenderer(process
->GetID(),
141 unresponsive_timer_fired_(false),
142 new_content_rendering_timeout_fired_(false) {
143 acked_touch_event_type_
= blink::WebInputEvent::Undefined
;
146 // Allow poking at a few private members.
147 using RenderWidgetHostImpl::GetResizeParams
;
148 using RenderWidgetHostImpl::OnUpdateRect
;
149 using RenderWidgetHostImpl::RendererExited
;
150 using RenderWidgetHostImpl::SetInitialRenderSizeParams
;
151 using RenderWidgetHostImpl::old_resize_params_
;
152 using RenderWidgetHostImpl::is_hidden_
;
153 using RenderWidgetHostImpl::resize_ack_pending_
;
154 using RenderWidgetHostImpl::input_router_
;
156 void OnTouchEventAck(const TouchEventWithLatencyInfo
& event
,
157 InputEventAckState ack_result
) override
{
159 acked_touch_event_type_
= event
.event
.type
;
160 RenderWidgetHostImpl::OnTouchEventAck(event
, ack_result
);
163 bool unresponsive_timer_fired() const {
164 return unresponsive_timer_fired_
;
167 bool new_content_rendering_timeout_fired() const {
168 return new_content_rendering_timeout_fired_
;
171 void DisableGestureDebounce() {
172 input_router_
.reset(new InputRouterImpl(
173 process_
, this, this, routing_id_
, InputRouterImpl::Config()));
176 WebInputEvent::Type
acked_touch_event_type() const {
177 return acked_touch_event_type_
;
180 void SetupForInputRouterTest() {
181 input_router_
.reset(new MockInputRouter(this));
184 MockInputRouter
* mock_input_router() {
185 return static_cast<MockInputRouter
*>(input_router_
.get());
189 void NotifyRendererUnresponsive() override
{
190 unresponsive_timer_fired_
= true;
193 void NotifyNewContentRenderingTimeoutForTesting() override
{
194 new_content_rendering_timeout_fired_
= true;
197 bool unresponsive_timer_fired_
;
198 bool new_content_rendering_timeout_fired_
;
199 WebInputEvent::Type acked_touch_event_type_
;
202 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost
);
207 // RenderWidgetHostProcess -----------------------------------------------------
209 class RenderWidgetHostProcess
: public MockRenderProcessHost
{
211 explicit RenderWidgetHostProcess(BrowserContext
* browser_context
)
212 : MockRenderProcessHost(browser_context
) {
214 ~RenderWidgetHostProcess() override
{}
216 bool HasConnection() const override
{ return true; }
219 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess
);
222 // TestView --------------------------------------------------------------------
224 // This test view allows us to specify the size, and keep track of acked
226 class TestView
: public TestRenderWidgetHostView
{
228 explicit TestView(RenderWidgetHostImpl
* rwh
)
229 : TestRenderWidgetHostView(rwh
),
230 unhandled_wheel_event_count_(0),
231 acked_event_count_(0),
232 gesture_event_type_(-1),
233 use_fake_physical_backing_size_(false),
234 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN
) {
237 // Sets the bounds returned by GetViewBounds.
238 void set_bounds(const gfx::Rect
& bounds
) {
242 const WebTouchEvent
& acked_event() const { return acked_event_
; }
243 int acked_event_count() const { return acked_event_count_
; }
244 void ClearAckedEvent() {
245 acked_event_
.type
= blink::WebInputEvent::Undefined
;
246 acked_event_count_
= 0;
249 const WebMouseWheelEvent
& unhandled_wheel_event() const {
250 return unhandled_wheel_event_
;
252 int unhandled_wheel_event_count() const {
253 return unhandled_wheel_event_count_
;
255 int gesture_event_type() const { return gesture_event_type_
; }
256 InputEventAckState
ack_result() const { return ack_result_
; }
258 void SetMockPhysicalBackingSize(const gfx::Size
& mock_physical_backing_size
) {
259 use_fake_physical_backing_size_
= true;
260 mock_physical_backing_size_
= mock_physical_backing_size
;
262 void ClearMockPhysicalBackingSize() {
263 use_fake_physical_backing_size_
= false;
265 void SetScreenInfo(const blink::WebScreenInfo
& screen_info
) {
266 screen_info_
= screen_info
;
269 // RenderWidgetHostView override.
270 gfx::Rect
GetViewBounds() const override
{ return bounds_
; }
271 void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo
& touch
,
272 InputEventAckState ack_result
) override
{
273 acked_event_
= touch
.event
;
274 ++acked_event_count_
;
276 void WheelEventAck(const WebMouseWheelEvent
& event
,
277 InputEventAckState ack_result
) override
{
278 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
)
280 unhandled_wheel_event_count_
++;
281 unhandled_wheel_event_
= event
;
283 void GestureEventAck(const WebGestureEvent
& event
,
284 InputEventAckState ack_result
) override
{
285 gesture_event_type_
= event
.type
;
286 ack_result_
= ack_result
;
288 gfx::Size
GetPhysicalBackingSize() const override
{
289 if (use_fake_physical_backing_size_
)
290 return mock_physical_backing_size_
;
291 return TestRenderWidgetHostView::GetPhysicalBackingSize();
293 void GetScreenInfo(blink::WebScreenInfo
* screen_info
) override
{
294 *screen_info
= screen_info_
;
296 #if defined(USE_AURA)
297 ~TestView() override
{
298 // Simulate the mouse exit event dispatched when an aura window is
299 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
300 // into WebInputEvent::MouseMove.)
301 WebMouseEvent event
=
302 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove
);
303 event
.timeStampSeconds
=
304 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
305 rwh_
->input_router()->SendMouseEvent(
306 MouseEventWithLatencyInfo(event
, ui::LatencyInfo()));
311 WebMouseWheelEvent unhandled_wheel_event_
;
312 int unhandled_wheel_event_count_
;
313 WebTouchEvent acked_event_
;
314 int acked_event_count_
;
315 int gesture_event_type_
;
317 bool use_fake_physical_backing_size_
;
318 gfx::Size mock_physical_backing_size_
;
319 InputEventAckState ack_result_
;
320 blink::WebScreenInfo screen_info_
;
323 DISALLOW_COPY_AND_ASSIGN(TestView
);
326 // MockRenderWidgetHostDelegate --------------------------------------------
328 class MockRenderWidgetHostDelegate
: public RenderWidgetHostDelegate
{
330 MockRenderWidgetHostDelegate()
331 : prehandle_keyboard_event_(false),
332 prehandle_keyboard_event_called_(false),
333 prehandle_keyboard_event_type_(WebInputEvent::Undefined
),
334 unhandled_keyboard_event_called_(false),
335 unhandled_keyboard_event_type_(WebInputEvent::Undefined
),
336 handle_wheel_event_(false),
337 handle_wheel_event_called_(false) {
339 ~MockRenderWidgetHostDelegate() override
{}
341 // Tests that make sure we ignore keyboard event acknowledgments to events we
342 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
343 bool unhandled_keyboard_event_called() const {
344 return unhandled_keyboard_event_called_
;
347 WebInputEvent::Type
unhandled_keyboard_event_type() const {
348 return unhandled_keyboard_event_type_
;
351 bool prehandle_keyboard_event_called() const {
352 return prehandle_keyboard_event_called_
;
355 WebInputEvent::Type
prehandle_keyboard_event_type() const {
356 return prehandle_keyboard_event_type_
;
359 void set_prehandle_keyboard_event(bool handle
) {
360 prehandle_keyboard_event_
= handle
;
363 void set_handle_wheel_event(bool handle
) {
364 handle_wheel_event_
= handle
;
367 bool handle_wheel_event_called() {
368 return handle_wheel_event_called_
;
372 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent
& event
,
373 bool* is_keyboard_shortcut
) override
{
374 prehandle_keyboard_event_type_
= event
.type
;
375 prehandle_keyboard_event_called_
= true;
376 return prehandle_keyboard_event_
;
379 void HandleKeyboardEvent(const NativeWebKeyboardEvent
& event
) override
{
380 unhandled_keyboard_event_type_
= event
.type
;
381 unhandled_keyboard_event_called_
= true;
384 bool HandleWheelEvent(const blink::WebMouseWheelEvent
& event
) override
{
385 handle_wheel_event_called_
= true;
386 return handle_wheel_event_
;
389 void Cut() override
{}
390 void Copy() override
{}
391 void Paste() override
{}
392 void SelectAll() override
{}
395 bool prehandle_keyboard_event_
;
396 bool prehandle_keyboard_event_called_
;
397 WebInputEvent::Type prehandle_keyboard_event_type_
;
399 bool unhandled_keyboard_event_called_
;
400 WebInputEvent::Type unhandled_keyboard_event_type_
;
402 bool handle_wheel_event_
;
403 bool handle_wheel_event_called_
;
406 // RenderWidgetHostTest --------------------------------------------------------
408 class RenderWidgetHostTest
: public testing::Test
{
410 RenderWidgetHostTest()
412 handle_key_press_event_(false),
413 handle_mouse_event_(false),
414 simulated_event_time_delta_seconds_(0) {
415 last_simulated_event_time_seconds_
=
416 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
418 ~RenderWidgetHostTest() override
{}
420 bool KeyPressEventCallback(const NativeWebKeyboardEvent
& /* event */) {
421 return handle_key_press_event_
;
423 bool MouseEventCallback(const blink::WebMouseEvent
& /* event */) {
424 return handle_mouse_event_
;
429 void SetUp() override
{
430 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
431 command_line
->AppendSwitch(switches::kValidateInputEventStream
);
433 browser_context_
.reset(new TestBrowserContext());
434 delegate_
.reset(new MockRenderWidgetHostDelegate());
435 process_
= new RenderWidgetHostProcess(browser_context_
.get());
436 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
437 if (IsDelegatedRendererEnabled()) {
438 ImageTransportFactory::InitializeForUnitTests(
439 scoped_ptr
<ImageTransportFactory
>(
440 new NoTransportImageTransportFactory
));
443 #if defined(USE_AURA)
444 screen_
.reset(aura::TestScreen::Create(gfx::Size()));
445 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
.get());
447 host_
.reset(new MockRenderWidgetHost(delegate_
.get(), process_
,
448 process_
->GetNextRoutingID()));
449 view_
.reset(new TestView(host_
.get()));
450 ConfigureView(view_
.get());
451 host_
->SetView(view_
.get());
452 SetInitialRenderSizeParams();
454 host_
->DisableGestureDebounce();
457 void TearDown() override
{
462 browser_context_
.reset();
464 #if defined(USE_AURA)
465 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, nullptr);
468 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
469 if (IsDelegatedRendererEnabled())
470 ImageTransportFactory::Terminate();
473 // Process all pending tasks to avoid leaks.
474 base::MessageLoop::current()->RunUntilIdle();
477 void SetInitialRenderSizeParams() {
478 ViewMsg_Resize_Params render_size_params
;
479 host_
->GetResizeParams(&render_size_params
);
480 host_
->SetInitialRenderSizeParams(render_size_params
);
483 virtual void ConfigureView(TestView
* view
) {
486 int64
GetLatencyComponentId() {
487 return host_
->GetLatencyComponentId();
490 void SendInputEventACK(WebInputEvent::Type type
,
491 InputEventAckState ack_result
) {
492 DCHECK(!WebInputEvent::isTouchEventType(type
));
493 InputEventAck
ack(type
, ack_result
);
494 host_
->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack
));
497 double GetNextSimulatedEventTimeSeconds() {
498 last_simulated_event_time_seconds_
+= simulated_event_time_delta_seconds_
;
499 return last_simulated_event_time_seconds_
;
502 void SimulateKeyboardEvent(WebInputEvent::Type type
) {
503 SimulateKeyboardEvent(type
, 0);
506 void SimulateKeyboardEvent(WebInputEvent::Type type
, int modifiers
) {
507 WebKeyboardEvent event
= SyntheticWebKeyboardEventBuilder::Build(type
);
508 event
.modifiers
= modifiers
;
509 NativeWebKeyboardEvent native_event
;
510 memcpy(&native_event
, &event
, sizeof(event
));
511 host_
->ForwardKeyboardEvent(native_event
);
514 void SimulateMouseEvent(WebInputEvent::Type type
) {
515 host_
->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type
));
518 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type
,
519 const ui::LatencyInfo
& ui_latency
) {
520 host_
->ForwardMouseEventWithLatencyInfo(
521 SyntheticWebMouseEventBuilder::Build(type
),
525 void SimulateWheelEvent(float dX
, float dY
, int modifiers
, bool precise
) {
526 host_
->ForwardWheelEvent(
527 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
));
530 void SimulateWheelEventWithLatencyInfo(float dX
,
534 const ui::LatencyInfo
& ui_latency
) {
535 host_
->ForwardWheelEventWithLatencyInfo(
536 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
),
540 void SimulateMouseMove(int x
, int y
, int modifiers
) {
541 SimulateMouseEvent(WebInputEvent::MouseMove
, x
, y
, modifiers
, false);
544 void SimulateMouseEvent(
545 WebInputEvent::Type type
, int x
, int y
, int modifiers
, bool pressed
) {
546 WebMouseEvent event
=
547 SyntheticWebMouseEventBuilder::Build(type
, x
, y
, modifiers
);
549 event
.button
= WebMouseEvent::ButtonLeft
;
550 event
.timeStampSeconds
= GetNextSimulatedEventTimeSeconds();
551 host_
->ForwardMouseEvent(event
);
554 // Inject simple synthetic WebGestureEvent instances.
555 void SimulateGestureEvent(WebInputEvent::Type type
,
556 WebGestureDevice sourceDevice
) {
557 host_
->ForwardGestureEvent(
558 SyntheticWebGestureEventBuilder::Build(type
, sourceDevice
));
561 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type
,
562 WebGestureDevice sourceDevice
,
563 const ui::LatencyInfo
& ui_latency
) {
564 host_
->ForwardGestureEventWithLatencyInfo(
565 SyntheticWebGestureEventBuilder::Build(type
, sourceDevice
),
569 // Set the timestamp for the touch-event.
570 void SetTouchTimestamp(base::TimeDelta timestamp
) {
571 touch_event_
.SetTimestamp(timestamp
);
574 // Sends a touch event (irrespective of whether the page has a touch-event
576 uint32
SendTouchEvent() {
577 uint32 touch_event_id
= touch_event_
.uniqueTouchEventId
;
578 host_
->ForwardTouchEventWithLatencyInfo(touch_event_
, ui::LatencyInfo());
580 touch_event_
.ResetPoints();
581 return touch_event_id
;
584 int PressTouchPoint(int x
, int y
) {
585 return touch_event_
.PressPoint(x
, y
);
588 void MoveTouchPoint(int index
, int x
, int y
) {
589 touch_event_
.MovePoint(index
, x
, y
);
592 void ReleaseTouchPoint(int index
) {
593 touch_event_
.ReleasePoint(index
);
596 const WebInputEvent
* GetInputEventFromMessage(const IPC::Message
& message
) {
597 base::PickleIterator
iter(message
);
600 if (!iter
.ReadData(&data
, &data_length
))
602 return reinterpret_cast<const WebInputEvent
*>(data
);
605 base::MessageLoopForUI message_loop_
;
607 scoped_ptr
<TestBrowserContext
> browser_context_
;
608 RenderWidgetHostProcess
* process_
; // Deleted automatically by the widget.
609 scoped_ptr
<MockRenderWidgetHostDelegate
> delegate_
;
610 scoped_ptr
<MockRenderWidgetHost
> host_
;
611 scoped_ptr
<TestView
> view_
;
612 scoped_ptr
<gfx::Screen
> screen_
;
613 bool handle_key_press_event_
;
614 bool handle_mouse_event_
;
615 double last_simulated_event_time_seconds_
;
616 double simulated_event_time_delta_seconds_
;
619 SyntheticWebTouchEvent touch_event_
;
621 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest
);
624 #if GTEST_HAS_PARAM_TEST
625 // RenderWidgetHostWithSourceTest ----------------------------------------------
627 // This is for tests that are to be run for all source devices.
628 class RenderWidgetHostWithSourceTest
629 : public RenderWidgetHostTest
,
630 public testing::WithParamInterface
<WebGestureDevice
> {};
631 #endif // GTEST_HAS_PARAM_TEST
635 // -----------------------------------------------------------------------------
637 TEST_F(RenderWidgetHostTest
, Resize
) {
638 // The initial bounds is the empty rect, so setting it to the same thing
639 // shouldn't send the resize message.
640 view_
->set_bounds(gfx::Rect());
642 EXPECT_FALSE(host_
->resize_ack_pending_
);
643 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
645 // No resize ack if the physical backing gets set, but the view bounds are
647 view_
->SetMockPhysicalBackingSize(gfx::Size(200, 200));
649 EXPECT_FALSE(host_
->resize_ack_pending_
);
651 // Setting the view bounds to nonzero should send out the notification.
652 // but should not expect ack for empty physical backing size.
653 gfx::Rect
original_size(0, 0, 100, 100);
654 process_
->sink().ClearMessages();
655 view_
->set_bounds(original_size
);
656 view_
->SetMockPhysicalBackingSize(gfx::Size());
658 EXPECT_FALSE(host_
->resize_ack_pending_
);
659 EXPECT_EQ(original_size
.size(), host_
->old_resize_params_
->new_size
);
660 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
662 // Setting the bounds and physical backing size to nonzero should send out
663 // the notification and expect an ack.
664 process_
->sink().ClearMessages();
665 view_
->ClearMockPhysicalBackingSize();
667 EXPECT_TRUE(host_
->resize_ack_pending_
);
668 EXPECT_EQ(original_size
.size(), host_
->old_resize_params_
->new_size
);
669 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
670 ViewHostMsg_UpdateRect_Params params
;
671 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
672 params
.view_size
= original_size
.size();
673 host_
->OnUpdateRect(params
);
674 EXPECT_FALSE(host_
->resize_ack_pending_
);
676 // Send out a update that's not a resize ack after setting resize ack pending
677 // flag. This should not clean the resize ack pending flag.
678 process_
->sink().ClearMessages();
679 gfx::Rect
second_size(0, 0, 110, 110);
680 EXPECT_FALSE(host_
->resize_ack_pending_
);
681 view_
->set_bounds(second_size
);
683 EXPECT_TRUE(host_
->resize_ack_pending_
);
685 params
.view_size
= gfx::Size(100, 100);
686 host_
->OnUpdateRect(params
);
687 EXPECT_TRUE(host_
->resize_ack_pending_
);
688 EXPECT_EQ(second_size
.size(), host_
->old_resize_params_
->new_size
);
690 // Sending out a new notification should NOT send out a new IPC message since
691 // a resize ACK is pending.
692 gfx::Rect
third_size(0, 0, 120, 120);
693 process_
->sink().ClearMessages();
694 view_
->set_bounds(third_size
);
696 EXPECT_TRUE(host_
->resize_ack_pending_
);
697 EXPECT_EQ(second_size
.size(), host_
->old_resize_params_
->new_size
);
698 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
700 // Send a update that's a resize ack, but for the original_size we sent. Since
701 // this isn't the second_size, the message handler should immediately send
702 // a new resize message for the new size to the renderer.
703 process_
->sink().ClearMessages();
704 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
705 params
.view_size
= original_size
.size();
706 host_
->OnUpdateRect(params
);
707 EXPECT_TRUE(host_
->resize_ack_pending_
);
708 EXPECT_EQ(third_size
.size(), host_
->old_resize_params_
->new_size
);
709 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
711 // Send the resize ack for the latest size.
712 process_
->sink().ClearMessages();
713 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
714 params
.view_size
= third_size
.size();
715 host_
->OnUpdateRect(params
);
716 EXPECT_FALSE(host_
->resize_ack_pending_
);
717 EXPECT_EQ(third_size
.size(), host_
->old_resize_params_
->new_size
);
718 EXPECT_FALSE(process_
->sink().GetFirstMessageMatching(ViewMsg_Resize::ID
));
720 // Now clearing the bounds should send out a notification but we shouldn't
721 // expect a resize ack (since the renderer won't ack empty sizes). The message
722 // should contain the new size (0x0) and not the previous one that we skipped
723 process_
->sink().ClearMessages();
724 view_
->set_bounds(gfx::Rect());
726 EXPECT_FALSE(host_
->resize_ack_pending_
);
727 EXPECT_EQ(gfx::Size(), host_
->old_resize_params_
->new_size
);
728 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
730 // Send a rect that has no area but has either width or height set.
731 process_
->sink().ClearMessages();
732 view_
->set_bounds(gfx::Rect(0, 0, 0, 30));
734 EXPECT_FALSE(host_
->resize_ack_pending_
);
735 EXPECT_EQ(gfx::Size(0, 30), host_
->old_resize_params_
->new_size
);
736 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
738 // Set the same size again. It should not be sent again.
739 process_
->sink().ClearMessages();
741 EXPECT_FALSE(host_
->resize_ack_pending_
);
742 EXPECT_EQ(gfx::Size(0, 30), host_
->old_resize_params_
->new_size
);
743 EXPECT_FALSE(process_
->sink().GetFirstMessageMatching(ViewMsg_Resize::ID
));
745 // A different size should be sent again, however.
746 view_
->set_bounds(gfx::Rect(0, 0, 0, 31));
748 EXPECT_FALSE(host_
->resize_ack_pending_
);
749 EXPECT_EQ(gfx::Size(0, 31), host_
->old_resize_params_
->new_size
);
750 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
753 // Test that a resize event is sent if WasResized() is called after a
754 // WebScreenInfo change.
755 TEST_F(RenderWidgetHostTest
, ResizeScreenInfo
) {
756 blink::WebScreenInfo screen_info
;
757 screen_info
.deviceScaleFactor
= 1.f
;
758 screen_info
.rect
= blink::WebRect(0, 0, 800, 600);
759 screen_info
.availableRect
= blink::WebRect(0, 0, 800, 600);
760 screen_info
.orientationAngle
= 0;
761 screen_info
.orientationType
= blink::WebScreenOrientationPortraitPrimary
;
763 view_
->SetScreenInfo(screen_info
);
765 EXPECT_FALSE(host_
->resize_ack_pending_
);
766 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
767 process_
->sink().ClearMessages();
769 screen_info
.orientationAngle
= 180;
770 screen_info
.orientationType
= blink::WebScreenOrientationLandscapePrimary
;
772 view_
->SetScreenInfo(screen_info
);
774 EXPECT_FALSE(host_
->resize_ack_pending_
);
775 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
776 process_
->sink().ClearMessages();
778 screen_info
.deviceScaleFactor
= 2.f
;
780 view_
->SetScreenInfo(screen_info
);
782 EXPECT_FALSE(host_
->resize_ack_pending_
);
783 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
784 process_
->sink().ClearMessages();
787 view_
->SetScreenInfo(screen_info
);
789 EXPECT_FALSE(host_
->resize_ack_pending_
);
790 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
793 // Test for crbug.com/25097. If a renderer crashes between a resize and the
794 // corresponding update message, we must be sure to clear the resize ack logic.
795 TEST_F(RenderWidgetHostTest
, ResizeThenCrash
) {
796 // Clear the first Resize message that carried screen info.
797 process_
->sink().ClearMessages();
799 // Setting the bounds to a "real" rect should send out the notification.
800 gfx::Rect
original_size(0, 0, 100, 100);
801 view_
->set_bounds(original_size
);
803 EXPECT_TRUE(host_
->resize_ack_pending_
);
804 EXPECT_EQ(original_size
.size(), host_
->old_resize_params_
->new_size
);
805 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
807 // Simulate a renderer crash before the update message. Ensure all the
808 // resize ack logic is cleared. Must clear the view first so it doesn't get
810 host_
->SetView(NULL
);
811 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
812 EXPECT_FALSE(host_
->resize_ack_pending_
);
813 EXPECT_EQ(gfx::Size(), host_
->old_resize_params_
->new_size
);
815 // Reset the view so we can exit the test cleanly.
816 host_
->SetView(view_
.get());
819 // Unable to include render_widget_host_view_mac.h and compile.
820 #if !defined(OS_MACOSX)
821 // Tests setting background transparency.
822 TEST_F(RenderWidgetHostTest
, Background
) {
823 scoped_ptr
<RenderWidgetHostViewBase
> view
;
824 #if defined(USE_AURA)
825 view
.reset(new RenderWidgetHostViewAura(host_
.get(), false));
826 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
827 view
->InitAsChild(NULL
);
828 #elif defined(OS_ANDROID)
829 view
.reset(new RenderWidgetHostViewAndroid(host_
.get(), NULL
));
831 host_
->SetView(view
.get());
833 EXPECT_TRUE(view
->GetBackgroundOpaque());
834 view
->SetBackgroundColor(SK_ColorTRANSPARENT
);
835 EXPECT_FALSE(view
->GetBackgroundOpaque());
837 const IPC::Message
* set_background
=
838 process_
->sink().GetUniqueMessageMatching(
839 ViewMsg_SetBackgroundOpaque::ID
);
840 ASSERT_TRUE(set_background
);
841 base::Tuple
<bool> sent_background
;
842 ViewMsg_SetBackgroundOpaque::Read(set_background
, &sent_background
);
843 EXPECT_FALSE(base::get
<0>(sent_background
));
845 #if defined(USE_AURA)
846 // See the comment above |InitAsChild(NULL)|.
847 host_
->SetView(NULL
);
848 static_cast<RenderWidgetHostViewBase
*>(view
.release())->Destroy();
853 // Test that we don't paint when we're hidden, but we still send the ACK. Most
854 // of the rest of the painting is tested in the GetBackingStore* ones.
855 TEST_F(RenderWidgetHostTest
, HiddenPaint
) {
856 BrowserThreadImpl
ui_thread(BrowserThread::UI
, base::MessageLoop::current());
857 // Hide the widget, it should have sent out a message to the renderer.
858 EXPECT_FALSE(host_
->is_hidden_
);
860 EXPECT_TRUE(host_
->is_hidden_
);
861 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID
));
863 // Send it an update as from the renderer.
864 process_
->sink().ClearMessages();
865 ViewHostMsg_UpdateRect_Params params
;
866 params
.view_size
= gfx::Size(100, 100);
867 host_
->OnUpdateRect(params
);
870 process_
->sink().ClearMessages();
871 host_
->WasShown(ui::LatencyInfo());
872 EXPECT_FALSE(host_
->is_hidden_
);
874 // It should have sent out a restored message with a request to paint.
875 const IPC::Message
* restored
= process_
->sink().GetUniqueMessageMatching(
876 ViewMsg_WasShown::ID
);
877 ASSERT_TRUE(restored
);
878 base::Tuple
<bool, ui::LatencyInfo
> needs_repaint
;
879 ViewMsg_WasShown::Read(restored
, &needs_repaint
);
880 EXPECT_TRUE(base::get
<0>(needs_repaint
));
883 TEST_F(RenderWidgetHostTest
, IgnoreKeyEventsHandledByRenderer
) {
884 // Simulate a keyboard event.
885 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
887 // Make sure we sent the input event to the renderer.
888 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
889 InputMsg_HandleInputEvent::ID
));
890 process_
->sink().ClearMessages();
892 // Send the simulated response from the renderer back.
893 SendInputEventACK(WebInputEvent::RawKeyDown
,
894 INPUT_EVENT_ACK_STATE_CONSUMED
);
895 EXPECT_FALSE(delegate_
->unhandled_keyboard_event_called());
898 TEST_F(RenderWidgetHostTest
, PreHandleRawKeyDownEvent
) {
899 // Simluate the situation that the browser handled the key down event during
900 // pre-handle phrase.
901 delegate_
->set_prehandle_keyboard_event(true);
902 process_
->sink().ClearMessages();
904 // Simulate a keyboard event.
905 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
907 EXPECT_TRUE(delegate_
->prehandle_keyboard_event_called());
908 EXPECT_EQ(WebInputEvent::RawKeyDown
,
909 delegate_
->prehandle_keyboard_event_type());
911 // Make sure the RawKeyDown event is not sent to the renderer.
912 EXPECT_EQ(0U, process_
->sink().message_count());
914 // The browser won't pre-handle a Char event.
915 delegate_
->set_prehandle_keyboard_event(false);
917 // Forward the Char event.
918 SimulateKeyboardEvent(WebInputEvent::Char
);
920 // Make sure the Char event is suppressed.
921 EXPECT_EQ(0U, process_
->sink().message_count());
923 // Forward the KeyUp event.
924 SimulateKeyboardEvent(WebInputEvent::KeyUp
);
926 // Make sure only KeyUp was sent to the renderer.
927 EXPECT_EQ(1U, process_
->sink().message_count());
928 EXPECT_EQ(InputMsg_HandleInputEvent::ID
,
929 process_
->sink().GetMessageAt(0)->type());
930 process_
->sink().ClearMessages();
932 // Send the simulated response from the renderer back.
933 SendInputEventACK(WebInputEvent::KeyUp
,
934 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
936 EXPECT_TRUE(delegate_
->unhandled_keyboard_event_called());
937 EXPECT_EQ(WebInputEvent::KeyUp
, delegate_
->unhandled_keyboard_event_type());
940 TEST_F(RenderWidgetHostTest
, UnhandledWheelEvent
) {
941 SimulateWheelEvent(-5, 0, 0, true);
943 // Make sure we sent the input event to the renderer.
944 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
945 InputMsg_HandleInputEvent::ID
));
946 process_
->sink().ClearMessages();
948 // Send the simulated response from the renderer back.
949 SendInputEventACK(WebInputEvent::MouseWheel
,
950 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
951 EXPECT_TRUE(delegate_
->handle_wheel_event_called());
952 EXPECT_EQ(1, view_
->unhandled_wheel_event_count());
953 EXPECT_EQ(-5, view_
->unhandled_wheel_event().deltaX
);
956 TEST_F(RenderWidgetHostTest
, HandleWheelEvent
) {
957 // Indicate that we're going to handle this wheel event
958 delegate_
->set_handle_wheel_event(true);
960 SimulateWheelEvent(-5, 0, 0, true);
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::MouseWheel
,
969 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
971 // ensure the wheel event handler was invoked
972 EXPECT_TRUE(delegate_
->handle_wheel_event_called());
974 // and that it suppressed the unhandled wheel event handler.
975 EXPECT_EQ(0, view_
->unhandled_wheel_event_count());
978 TEST_F(RenderWidgetHostTest
, UnhandledGestureEvent
) {
979 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap
,
980 blink::WebGestureDeviceTouchscreen
);
982 // Make sure we sent the input event to the renderer.
983 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
984 InputMsg_HandleInputEvent::ID
));
985 process_
->sink().ClearMessages();
987 // Send the simulated response from the renderer back.
988 SendInputEventACK(WebInputEvent::GestureTwoFingerTap
,
989 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
990 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap
, view_
->gesture_event_type());
991 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED
, view_
->ack_result());
994 // Test that the hang monitor timer expires properly if a new timer is started
995 // while one is in progress (see crbug.com/11007).
996 TEST_F(RenderWidgetHostTest
, DontPostponeHangMonitorTimeout
) {
997 // Start with a short timeout.
998 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1000 // Immediately try to add a long 30 second timeout.
1001 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1002 host_
->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
1004 // Wait long enough for first timeout and see if it fired.
1005 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1006 FROM_HERE
, base::MessageLoop::QuitClosure(),
1007 TimeDelta::FromMilliseconds(10));
1008 base::MessageLoop::current()->Run();
1009 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1012 // Test that the hang monitor timer expires properly if it is started, stopped,
1013 // and then started again.
1014 TEST_F(RenderWidgetHostTest
, StopAndStartHangMonitorTimeout
) {
1015 // Start with a short timeout, then stop it.
1016 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1017 host_
->StopHangMonitorTimeout();
1019 // Start it again to ensure it still works.
1020 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1021 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1023 // Wait long enough for first timeout and see if it fired.
1024 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1025 FROM_HERE
, base::MessageLoop::QuitClosure(),
1026 TimeDelta::FromMilliseconds(40));
1027 base::MessageLoop::current()->Run();
1028 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1031 // Test that the hang monitor timer expires properly if it is started, then
1032 // updated to a shorter duration.
1033 TEST_F(RenderWidgetHostTest
, ShorterDelayHangMonitorTimeout
) {
1034 // Start with a timeout.
1035 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
1037 // Start it again with shorter delay.
1038 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1039 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
1041 // Wait long enough for the second timeout and see if it fired.
1042 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1043 FROM_HERE
, base::MessageLoop::QuitClosure(),
1044 TimeDelta::FromMilliseconds(25));
1045 base::MessageLoop::current()->Run();
1046 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1049 // Test that the hang monitor timer is effectively disabled when the widget is
1051 TEST_F(RenderWidgetHostTest
, HangMonitorTimeoutDisabledForInputWhenHidden
) {
1052 host_
->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(1));
1053 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1055 // Hiding the widget should deactivate the timeout.
1058 // The timeout should not fire.
1059 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1060 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1061 FROM_HERE
, base::MessageLoop::QuitClosure(),
1062 TimeDelta::FromMicroseconds(2));
1063 base::MessageLoop::current()->Run();
1064 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1066 // The timeout should never reactivate while hidden.
1067 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1068 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1069 FROM_HERE
, base::MessageLoop::QuitClosure(),
1070 TimeDelta::FromMicroseconds(2));
1071 base::MessageLoop::current()->Run();
1072 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1074 // Showing the widget should restore the timeout, as the events have
1075 // not yet been ack'ed.
1076 host_
->WasShown(ui::LatencyInfo());
1077 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1078 FROM_HERE
, base::MessageLoop::QuitClosure(),
1079 TimeDelta::FromMicroseconds(2));
1080 base::MessageLoop::current()->Run();
1081 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1084 // Test that the hang monitor catches two input events but only one ack.
1085 // This can happen if the second input event causes the renderer to hang.
1086 // This test will catch a regression of crbug.com/111185.
1087 TEST_F(RenderWidgetHostTest
, MultipleInputEvents
) {
1088 // Configure the host to wait 10ms before considering
1089 // the renderer hung.
1090 host_
->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(10));
1092 // Send two events but only one ack.
1093 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1094 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1095 SendInputEventACK(WebInputEvent::RawKeyDown
,
1096 INPUT_EVENT_ACK_STATE_CONSUMED
);
1098 // Wait long enough for first timeout and see if it fired.
1099 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1100 FROM_HERE
, base::MessageLoop::QuitClosure(),
1101 TimeDelta::FromMicroseconds(20));
1102 base::MessageLoop::current()->Run();
1103 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1106 // Test that the rendering timeout for newly loaded content fires
1107 // when enough time passes without receiving a new compositor frame.
1108 TEST_F(RenderWidgetHostTest
, NewContentRenderingTimeout
) {
1109 host_
->set_new_content_rendering_delay_for_testing(
1110 base::TimeDelta::FromMicroseconds(10));
1112 // Test immediate start and stop, ensuring that the timeout doesn't fire.
1113 host_
->StartNewContentRenderingTimeout();
1114 host_
->StopNewContentRenderingTimeout();
1115 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1116 FROM_HERE
, base::MessageLoop::QuitClosure(),
1117 TimeDelta::FromMicroseconds(20));
1118 base::MessageLoop::current()->Run();
1120 EXPECT_FALSE(host_
->new_content_rendering_timeout_fired());
1122 // Test with a long delay to ensure that it does fire this time.
1123 host_
->StartNewContentRenderingTimeout();
1124 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1125 FROM_HERE
, base::MessageLoop::QuitClosure(),
1126 TimeDelta::FromMicroseconds(20));
1127 base::MessageLoop::current()->Run();
1128 EXPECT_TRUE(host_
->new_content_rendering_timeout_fired());
1131 std::string
GetInputMessageTypes(RenderWidgetHostProcess
* process
) {
1133 for (size_t i
= 0; i
< process
->sink().message_count(); ++i
) {
1134 const IPC::Message
*message
= process
->sink().GetMessageAt(i
);
1135 EXPECT_EQ(InputMsg_HandleInputEvent::ID
, message
->type());
1136 InputMsg_HandleInputEvent::Param params
;
1137 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message
, ¶ms
));
1138 const WebInputEvent
* event
= base::get
<0>(params
);
1141 result
+= WebInputEventTraits::GetName(event
->type
);
1143 process
->sink().ClearMessages();
1147 TEST_F(RenderWidgetHostTest
, TouchEmulator
) {
1148 simulated_event_time_delta_seconds_
= 0.1;
1149 // Immediately ack all touches instead of sending them to the renderer.
1150 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1151 host_
->SetTouchEventEmulationEnabled(
1152 true, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1153 process_
->sink().ClearMessages();
1154 view_
->set_bounds(gfx::Rect(0, 0, 400, 200));
1157 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1158 EXPECT_EQ(0U, process_
->sink().message_count());
1160 // Mouse press becomes touch start which in turn becomes tap.
1161 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 10, 0, true);
1162 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1163 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1165 // Mouse drag generates touch move, cancels tap and starts scroll.
1166 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 30, 0, true);
1167 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1169 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1170 GetInputMessageTypes(process_
));
1171 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1172 INPUT_EVENT_ACK_STATE_CONSUMED
);
1173 EXPECT_EQ(0U, process_
->sink().message_count());
1175 // Mouse drag with shift becomes pinch.
1177 WebInputEvent::MouseMove
, 10, 40, WebInputEvent::ShiftKey
, true);
1178 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1179 EXPECT_EQ("GesturePinchBegin",
1180 GetInputMessageTypes(process_
));
1181 EXPECT_EQ(0U, process_
->sink().message_count());
1184 WebInputEvent::MouseMove
, 10, 50, WebInputEvent::ShiftKey
, true);
1185 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1186 EXPECT_EQ("GesturePinchUpdate",
1187 GetInputMessageTypes(process_
));
1188 SendInputEventACK(WebInputEvent::GesturePinchUpdate
,
1189 INPUT_EVENT_ACK_STATE_CONSUMED
);
1190 EXPECT_EQ(0U, process_
->sink().message_count());
1192 // Mouse drag without shift becomes scroll again.
1193 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 60, 0, true);
1194 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1195 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1196 GetInputMessageTypes(process_
));
1197 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1198 INPUT_EVENT_ACK_STATE_CONSUMED
);
1199 EXPECT_EQ(0U, process_
->sink().message_count());
1201 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 70, 0, true);
1202 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1203 EXPECT_EQ("GestureScrollUpdate",
1204 GetInputMessageTypes(process_
));
1205 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1206 INPUT_EVENT_ACK_STATE_CONSUMED
);
1207 EXPECT_EQ(0U, process_
->sink().message_count());
1209 SimulateMouseEvent(WebInputEvent::MouseUp
, 10, 70, 0, true);
1210 EXPECT_EQ(WebInputEvent::TouchEnd
, host_
->acked_touch_event_type());
1211 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_
));
1212 EXPECT_EQ(0U, process_
->sink().message_count());
1214 // Mouse move does nothing.
1215 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 80, 0, false);
1216 EXPECT_EQ(0U, process_
->sink().message_count());
1218 // Another mouse down continues scroll.
1219 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 80, 0, true);
1220 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1221 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1222 EXPECT_EQ(0U, process_
->sink().message_count());
1224 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 100, 0, true);
1225 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1227 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1228 GetInputMessageTypes(process_
));
1229 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1230 INPUT_EVENT_ACK_STATE_CONSUMED
);
1231 EXPECT_EQ(0U, process_
->sink().message_count());
1235 WebInputEvent::MouseMove
, 10, 110, WebInputEvent::ShiftKey
, true);
1236 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1237 EXPECT_EQ("GesturePinchBegin",
1238 GetInputMessageTypes(process_
));
1239 EXPECT_EQ(0U, process_
->sink().message_count());
1242 WebInputEvent::MouseMove
, 10, 120, WebInputEvent::ShiftKey
, true);
1243 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1244 EXPECT_EQ("GesturePinchUpdate",
1245 GetInputMessageTypes(process_
));
1246 SendInputEventACK(WebInputEvent::GesturePinchUpdate
,
1247 INPUT_EVENT_ACK_STATE_CONSUMED
);
1248 EXPECT_EQ(0U, process_
->sink().message_count());
1250 // Turn off emulation during a pinch.
1251 host_
->SetTouchEventEmulationEnabled(
1252 false, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1253 EXPECT_EQ(WebInputEvent::TouchCancel
, host_
->acked_touch_event_type());
1254 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1255 GetInputMessageTypes(process_
));
1256 EXPECT_EQ(0U, process_
->sink().message_count());
1258 // Mouse event should pass untouched.
1260 WebInputEvent::MouseMove
, 10, 10, WebInputEvent::ShiftKey
, true);
1261 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_
));
1262 SendInputEventACK(WebInputEvent::MouseMove
,
1263 INPUT_EVENT_ACK_STATE_CONSUMED
);
1264 EXPECT_EQ(0U, process_
->sink().message_count());
1266 // Turn on emulation.
1267 host_
->SetTouchEventEmulationEnabled(
1268 true, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1269 EXPECT_EQ(0U, process_
->sink().message_count());
1272 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 10, 0, true);
1273 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1274 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1275 EXPECT_EQ(0U, process_
->sink().message_count());
1278 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 30, 0, true);
1279 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1281 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1282 GetInputMessageTypes(process_
));
1283 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1284 INPUT_EVENT_ACK_STATE_CONSUMED
);
1286 // Turn off emulation during a scroll.
1287 host_
->SetTouchEventEmulationEnabled(
1288 false, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1289 EXPECT_EQ(WebInputEvent::TouchCancel
, host_
->acked_touch_event_type());
1291 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_
));
1292 EXPECT_EQ(0U, process_
->sink().message_count());
1295 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1296 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1297 host_->SetupForInputRouterTest(); \
1298 host_->INPUTMSG(); \
1299 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1302 TEST_InputRouterRoutes_NOARGS(Focus
);
1303 TEST_InputRouterRoutes_NOARGS(Blur
);
1304 TEST_InputRouterRoutes_NOARGS(LostCapture
);
1306 #undef TEST_InputRouterRoutes_NOARGS
1308 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1309 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1310 host_->SetupForInputRouterTest(); \
1311 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1312 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1315 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo
);
1316 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo
);
1317 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut
);
1318 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy
);
1319 #if defined(OS_MACOSX)
1320 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard
);
1322 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste
);
1323 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle
);
1324 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete
);
1325 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll
);
1326 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect
);
1328 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1330 TEST_F(RenderWidgetHostTest
, InputRouterRoutesReplace
) {
1331 host_
->SetupForInputRouterTest();
1332 host_
->Send(new InputMsg_Replace(host_
->GetRoutingID(), base::string16()));
1333 EXPECT_TRUE(host_
->mock_input_router()->send_event_called_
);
1336 TEST_F(RenderWidgetHostTest
, InputRouterRoutesReplaceMisspelling
) {
1337 host_
->SetupForInputRouterTest();
1338 host_
->Send(new InputMsg_ReplaceMisspelling(host_
->GetRoutingID(),
1340 EXPECT_TRUE(host_
->mock_input_router()->send_event_called_
);
1343 TEST_F(RenderWidgetHostTest
, IgnoreInputEvent
) {
1344 host_
->SetupForInputRouterTest();
1346 host_
->SetIgnoreInputEvents(true);
1348 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1349 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1351 SimulateMouseEvent(WebInputEvent::MouseMove
);
1352 EXPECT_FALSE(host_
->mock_input_router()->sent_mouse_event_
);
1354 SimulateWheelEvent(0, 100, 0, true);
1355 EXPECT_FALSE(host_
->mock_input_router()->sent_wheel_event_
);
1357 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
1358 blink::WebGestureDeviceTouchpad
);
1359 EXPECT_FALSE(host_
->mock_input_router()->sent_gesture_event_
);
1361 PressTouchPoint(100, 100);
1363 EXPECT_FALSE(host_
->mock_input_router()->send_touch_event_not_cancelled_
);
1366 TEST_F(RenderWidgetHostTest
, KeyboardListenerIgnoresEvent
) {
1367 host_
->SetupForInputRouterTest();
1368 host_
->AddKeyPressEventCallback(
1369 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback
,
1370 base::Unretained(this)));
1371 handle_key_press_event_
= false;
1372 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1374 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1377 TEST_F(RenderWidgetHostTest
, KeyboardListenerSuppressFollowingEvents
) {
1378 host_
->SetupForInputRouterTest();
1380 host_
->AddKeyPressEventCallback(
1381 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback
,
1382 base::Unretained(this)));
1384 // The callback handles the first event
1385 handle_key_press_event_
= true;
1386 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1388 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1390 // Following Char events should be suppressed
1391 handle_key_press_event_
= false;
1392 SimulateKeyboardEvent(WebInputEvent::Char
);
1393 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1394 SimulateKeyboardEvent(WebInputEvent::Char
);
1395 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1397 // Sending RawKeyDown event should stop suppression
1398 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1399 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1401 host_
->mock_input_router()->sent_keyboard_event_
= false;
1402 SimulateKeyboardEvent(WebInputEvent::Char
);
1403 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1406 TEST_F(RenderWidgetHostTest
, MouseEventCallbackCanHandleEvent
) {
1407 host_
->SetupForInputRouterTest();
1409 host_
->AddMouseEventCallback(
1410 base::Bind(&RenderWidgetHostTest::MouseEventCallback
,
1411 base::Unretained(this)));
1413 handle_mouse_event_
= true;
1414 SimulateMouseEvent(WebInputEvent::MouseDown
);
1416 EXPECT_FALSE(host_
->mock_input_router()->sent_mouse_event_
);
1418 handle_mouse_event_
= false;
1419 SimulateMouseEvent(WebInputEvent::MouseDown
);
1421 EXPECT_TRUE(host_
->mock_input_router()->sent_mouse_event_
);
1424 TEST_F(RenderWidgetHostTest
, InputRouterReceivesHandleInputEvent_ACK
) {
1425 host_
->SetupForInputRouterTest();
1427 SendInputEventACK(WebInputEvent::RawKeyDown
,
1428 INPUT_EVENT_ACK_STATE_CONSUMED
);
1430 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1433 TEST_F(RenderWidgetHostTest
, InputRouterReceivesMoveCaret_ACK
) {
1434 host_
->SetupForInputRouterTest();
1436 host_
->OnMessageReceived(InputHostMsg_MoveCaret_ACK(0));
1438 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1441 TEST_F(RenderWidgetHostTest
, InputRouterReceivesSelectRange_ACK
) {
1442 host_
->SetupForInputRouterTest();
1444 host_
->OnMessageReceived(InputHostMsg_SelectRange_ACK(0));
1446 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1449 TEST_F(RenderWidgetHostTest
, InputRouterReceivesHasTouchEventHandlers
) {
1450 host_
->SetupForInputRouterTest();
1452 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1454 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1457 ui::LatencyInfo
GetLatencyInfoFromInputEvent(RenderWidgetHostProcess
* process
) {
1458 const IPC::Message
* message
= process
->sink().GetUniqueMessageMatching(
1459 InputMsg_HandleInputEvent::ID
);
1460 EXPECT_TRUE(message
);
1461 InputMsg_HandleInputEvent::Param params
;
1462 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message
, ¶ms
));
1463 process
->sink().ClearMessages();
1464 return base::get
<1>(params
);
1467 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess
* process
,
1469 WebInputEvent::Type input_type
) {
1470 ui::LatencyInfo latency_info
= GetLatencyInfoFromInputEvent(process
);
1471 EXPECT_TRUE(latency_info
.FindLatency(
1472 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
,
1477 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1478 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1479 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1480 // event's LatencyInfo.
1481 TEST_F(RenderWidgetHostTest
, InputEventRWHLatencyComponent
) {
1482 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1483 process_
->sink().ClearMessages();
1485 // Tests RWHI::ForwardWheelEvent().
1486 SimulateWheelEvent(-5, 0, 0, true);
1487 CheckLatencyInfoComponentInMessage(
1488 process_
, GetLatencyComponentId(), WebInputEvent::MouseWheel
);
1489 SendInputEventACK(WebInputEvent::MouseWheel
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1491 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1492 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1493 CheckLatencyInfoComponentInMessage(
1494 process_
, GetLatencyComponentId(), WebInputEvent::MouseWheel
);
1495 SendInputEventACK(WebInputEvent::MouseWheel
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1497 // Tests RWHI::ForwardMouseEvent().
1498 SimulateMouseEvent(WebInputEvent::MouseMove
);
1499 CheckLatencyInfoComponentInMessage(
1500 process_
, GetLatencyComponentId(), WebInputEvent::MouseMove
);
1501 SendInputEventACK(WebInputEvent::MouseMove
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1503 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1504 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove
,
1506 CheckLatencyInfoComponentInMessage(
1507 process_
, GetLatencyComponentId(), WebInputEvent::MouseMove
);
1508 SendInputEventACK(WebInputEvent::MouseMove
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1510 // Tests RWHI::ForwardGestureEvent().
1511 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
1512 blink::WebGestureDeviceTouchscreen
);
1513 CheckLatencyInfoComponentInMessage(
1514 process_
, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin
);
1516 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1517 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate
,
1518 blink::WebGestureDeviceTouchscreen
,
1520 CheckLatencyInfoComponentInMessage(
1521 process_
, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate
);
1522 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1523 INPUT_EVENT_ACK_STATE_CONSUMED
);
1525 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1526 PressTouchPoint(0, 1);
1527 uint32 touch_event_id
= SendTouchEvent();
1528 InputEventAck
ack(WebInputEvent::TouchStart
, INPUT_EVENT_ACK_STATE_CONSUMED
,
1530 host_
->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack
));
1531 CheckLatencyInfoComponentInMessage(
1532 process_
, GetLatencyComponentId(), WebInputEvent::TouchStart
);
1535 TEST_F(RenderWidgetHostTest
, RendererExitedResetsInputRouter
) {
1536 // RendererExited will delete the view.
1537 host_
->SetView(new TestView(host_
.get()));
1538 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
1540 // Make sure the input router is in a fresh state.
1541 ASSERT_FALSE(host_
->input_router()->HasPendingEvents());
1544 // Regression test for http://crbug.com/401859 and http://crbug.com/522795.
1545 TEST_F(RenderWidgetHostTest
, RendererExitedResetsIsHidden
) {
1546 // RendererExited will delete the view.
1547 host_
->SetView(new TestView(host_
.get()));
1548 host_
->WasShown(ui::LatencyInfo());
1550 ASSERT_FALSE(host_
->is_hidden());
1551 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
1552 ASSERT_TRUE(host_
->is_hidden());
1554 // Make sure the input router is in a fresh state.
1555 ASSERT_FALSE(host_
->input_router()->HasPendingEvents());
1558 TEST_F(RenderWidgetHostTest
, ResizeParams
) {
1559 gfx::Rect
bounds(0, 0, 100, 100);
1560 gfx::Size
physical_backing_size(40, 50);
1561 view_
->set_bounds(bounds
);
1562 view_
->SetMockPhysicalBackingSize(physical_backing_size
);
1564 ViewMsg_Resize_Params resize_params
;
1565 host_
->GetResizeParams(&resize_params
);
1566 EXPECT_EQ(bounds
.size(), resize_params
.new_size
);
1567 EXPECT_EQ(physical_backing_size
, resize_params
.physical_backing_size
);
1570 class RenderWidgetHostInitialSizeTest
: public RenderWidgetHostTest
{
1572 RenderWidgetHostInitialSizeTest()
1573 : RenderWidgetHostTest(), initial_size_(200, 100) {}
1575 void ConfigureView(TestView
* view
) override
{
1576 view
->set_bounds(gfx::Rect(initial_size_
));
1580 gfx::Size initial_size_
;
1583 TEST_F(RenderWidgetHostInitialSizeTest
, InitialSize
) {
1584 // Having an initial size set means that the size information had been sent
1585 // with the reqiest to new up the RenderView and so subsequent WasResized
1586 // calls should not result in new IPC (unless the size has actually changed).
1587 host_
->WasResized();
1588 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
1589 EXPECT_EQ(initial_size_
, host_
->old_resize_params_
->new_size
);
1590 EXPECT_TRUE(host_
->resize_ack_pending_
);
1593 } // namespace content