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/gpu/gpu_surface_tracker.h"
17 #include "content/browser/renderer_host/input/input_router_impl.h"
18 #include "content/browser/renderer_host/render_widget_host_delegate.h"
19 #include "content/browser/renderer_host/render_widget_host_view_base.h"
20 #include "content/common/input/synthetic_web_input_event_builders.h"
21 #include "content/common/input_messages.h"
22 #include "content/common/view_messages.h"
23 #include "content/public/common/content_switches.h"
24 #include "content/public/test/mock_render_process_host.h"
25 #include "content/public/test/test_browser_context.h"
26 #include "content/test/test_render_view_host.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "ui/events/keycodes/keyboard_codes.h"
29 #include "ui/gfx/canvas.h"
30 #include "ui/gfx/screen.h"
32 #if defined(OS_ANDROID)
33 #include "content/browser/renderer_host/render_widget_host_view_android.h"
36 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
37 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
41 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
42 #include "content/browser/renderer_host/ui_events_helper.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 NativeWebKeyboardEventWithLatencyInfo
& key_event
,
88 bool is_shortcut
) override
{
89 sent_keyboard_event_
= true;
91 void SendGestureEvent(
92 const GestureEventWithLatencyInfo
& gesture_event
) override
{
93 sent_gesture_event_
= true;
95 void SendTouchEvent(const TouchEventWithLatencyInfo
& touch_event
) override
{
96 send_touch_event_not_cancelled_
=
97 client_
->FilterInputEvent(touch_event
.event
, touch_event
.latency
) ==
98 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
100 const NativeWebKeyboardEvent
* GetLastKeyboardEvent() const override
{
104 void NotifySiteIsMobileOptimized(bool is_mobile_optimized
) override
{}
105 void RequestNotificationWhenFlushed() override
{}
106 bool HasPendingEvents() const override
{ return false; }
109 bool OnMessageReceived(const IPC::Message
& message
) override
{
110 message_received_
= true;
114 bool send_event_called_
;
115 bool sent_mouse_event_
;
116 bool sent_wheel_event_
;
117 bool sent_keyboard_event_
;
118 bool sent_gesture_event_
;
119 bool send_touch_event_not_cancelled_
;
120 bool message_received_
;
123 InputRouterClient
* client_
;
125 DISALLOW_COPY_AND_ASSIGN(MockInputRouter
);
128 // MockRenderWidgetHost ----------------------------------------------------
130 class MockRenderWidgetHost
: public RenderWidgetHostImpl
{
132 MockRenderWidgetHost(RenderWidgetHostDelegate
* delegate
,
133 RenderProcessHost
* process
,
135 : RenderWidgetHostImpl(
139 GpuSurfaceTracker::Get()->AddSurfaceForRenderer(process
->GetID(),
142 unresponsive_timer_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 void DisableGestureDebounce() {
168 input_router_
.reset(new InputRouterImpl(
169 process_
, this, this, routing_id_
, InputRouterImpl::Config()));
172 WebInputEvent::Type
acked_touch_event_type() const {
173 return acked_touch_event_type_
;
176 void SetupForInputRouterTest() {
177 input_router_
.reset(new MockInputRouter(this));
180 MockInputRouter
* mock_input_router() {
181 return static_cast<MockInputRouter
*>(input_router_
.get());
185 void NotifyRendererUnresponsive() override
{
186 unresponsive_timer_fired_
= true;
189 bool unresponsive_timer_fired_
;
190 WebInputEvent::Type acked_touch_event_type_
;
192 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost
);
197 // RenderWidgetHostProcess -----------------------------------------------------
199 class RenderWidgetHostProcess
: public MockRenderProcessHost
{
201 explicit RenderWidgetHostProcess(BrowserContext
* browser_context
)
202 : MockRenderProcessHost(browser_context
) {
204 ~RenderWidgetHostProcess() override
{}
206 bool HasConnection() const override
{ return true; }
209 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess
);
212 // TestView --------------------------------------------------------------------
214 // This test view allows us to specify the size, and keep track of acked
216 class TestView
: public TestRenderWidgetHostView
{
218 explicit TestView(RenderWidgetHostImpl
* rwh
)
219 : TestRenderWidgetHostView(rwh
),
220 unhandled_wheel_event_count_(0),
221 acked_event_count_(0),
222 gesture_event_type_(-1),
223 use_fake_physical_backing_size_(false),
224 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN
) {
227 // Sets the bounds returned by GetViewBounds.
228 void set_bounds(const gfx::Rect
& bounds
) {
232 const WebTouchEvent
& acked_event() const { return acked_event_
; }
233 int acked_event_count() const { return acked_event_count_
; }
234 void ClearAckedEvent() {
235 acked_event_
.type
= blink::WebInputEvent::Undefined
;
236 acked_event_count_
= 0;
239 const WebMouseWheelEvent
& unhandled_wheel_event() const {
240 return unhandled_wheel_event_
;
242 int unhandled_wheel_event_count() const {
243 return unhandled_wheel_event_count_
;
245 int gesture_event_type() const { return gesture_event_type_
; }
246 InputEventAckState
ack_result() const { return ack_result_
; }
248 void SetMockPhysicalBackingSize(const gfx::Size
& mock_physical_backing_size
) {
249 use_fake_physical_backing_size_
= true;
250 mock_physical_backing_size_
= mock_physical_backing_size
;
252 void ClearMockPhysicalBackingSize() {
253 use_fake_physical_backing_size_
= false;
255 void SetScreenInfo(const blink::WebScreenInfo
& screen_info
) {
256 screen_info_
= screen_info
;
259 // RenderWidgetHostView override.
260 gfx::Rect
GetViewBounds() const override
{ return bounds_
; }
261 void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo
& touch
,
262 InputEventAckState ack_result
) override
{
263 acked_event_
= touch
.event
;
264 ++acked_event_count_
;
266 void WheelEventAck(const WebMouseWheelEvent
& event
,
267 InputEventAckState ack_result
) override
{
268 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
)
270 unhandled_wheel_event_count_
++;
271 unhandled_wheel_event_
= event
;
273 void GestureEventAck(const WebGestureEvent
& event
,
274 InputEventAckState ack_result
) override
{
275 gesture_event_type_
= event
.type
;
276 ack_result_
= ack_result
;
278 gfx::Size
GetPhysicalBackingSize() const override
{
279 if (use_fake_physical_backing_size_
)
280 return mock_physical_backing_size_
;
281 return TestRenderWidgetHostView::GetPhysicalBackingSize();
283 void GetScreenInfo(blink::WebScreenInfo
* screen_info
) override
{
284 *screen_info
= screen_info_
;
286 #if defined(USE_AURA)
287 ~TestView() override
{
288 // Simulate the mouse exit event dispatched when an aura window is
289 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
290 // into WebInputEvent::MouseMove.)
291 WebMouseEvent event
=
292 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove
);
293 event
.timeStampSeconds
=
294 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
295 rwh_
->input_router()->SendMouseEvent(
296 MouseEventWithLatencyInfo(event
, ui::LatencyInfo()));
301 WebMouseWheelEvent unhandled_wheel_event_
;
302 int unhandled_wheel_event_count_
;
303 WebTouchEvent acked_event_
;
304 int acked_event_count_
;
305 int gesture_event_type_
;
307 bool use_fake_physical_backing_size_
;
308 gfx::Size mock_physical_backing_size_
;
309 InputEventAckState ack_result_
;
310 blink::WebScreenInfo screen_info_
;
312 DISALLOW_COPY_AND_ASSIGN(TestView
);
315 // MockRenderWidgetHostDelegate --------------------------------------------
317 class MockRenderWidgetHostDelegate
: public RenderWidgetHostDelegate
{
319 MockRenderWidgetHostDelegate()
320 : prehandle_keyboard_event_(false),
321 prehandle_keyboard_event_called_(false),
322 prehandle_keyboard_event_type_(WebInputEvent::Undefined
),
323 unhandled_keyboard_event_called_(false),
324 unhandled_keyboard_event_type_(WebInputEvent::Undefined
),
325 handle_wheel_event_(false),
326 handle_wheel_event_called_(false) {
328 ~MockRenderWidgetHostDelegate() override
{}
330 // Tests that make sure we ignore keyboard event acknowledgments to events we
331 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
332 bool unhandled_keyboard_event_called() const {
333 return unhandled_keyboard_event_called_
;
336 WebInputEvent::Type
unhandled_keyboard_event_type() const {
337 return unhandled_keyboard_event_type_
;
340 bool prehandle_keyboard_event_called() const {
341 return prehandle_keyboard_event_called_
;
344 WebInputEvent::Type
prehandle_keyboard_event_type() const {
345 return prehandle_keyboard_event_type_
;
348 void set_prehandle_keyboard_event(bool handle
) {
349 prehandle_keyboard_event_
= handle
;
352 void set_handle_wheel_event(bool handle
) {
353 handle_wheel_event_
= handle
;
356 bool handle_wheel_event_called() {
357 return handle_wheel_event_called_
;
361 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent
& event
,
362 bool* is_keyboard_shortcut
) override
{
363 prehandle_keyboard_event_type_
= event
.type
;
364 prehandle_keyboard_event_called_
= true;
365 return prehandle_keyboard_event_
;
368 void HandleKeyboardEvent(const NativeWebKeyboardEvent
& event
) override
{
369 unhandled_keyboard_event_type_
= event
.type
;
370 unhandled_keyboard_event_called_
= true;
373 bool HandleWheelEvent(const blink::WebMouseWheelEvent
& event
) override
{
374 handle_wheel_event_called_
= true;
375 return handle_wheel_event_
;
378 void Cut() override
{}
379 void Copy() override
{}
380 void Paste() override
{}
381 void SelectAll() override
{}
384 bool prehandle_keyboard_event_
;
385 bool prehandle_keyboard_event_called_
;
386 WebInputEvent::Type prehandle_keyboard_event_type_
;
388 bool unhandled_keyboard_event_called_
;
389 WebInputEvent::Type unhandled_keyboard_event_type_
;
391 bool handle_wheel_event_
;
392 bool handle_wheel_event_called_
;
395 // RenderWidgetHostTest --------------------------------------------------------
397 class RenderWidgetHostTest
: public testing::Test
{
399 RenderWidgetHostTest()
401 handle_key_press_event_(false),
402 handle_mouse_event_(false),
403 simulated_event_time_delta_seconds_(0) {
404 last_simulated_event_time_seconds_
=
405 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
407 ~RenderWidgetHostTest() override
{}
409 bool KeyPressEventCallback(const NativeWebKeyboardEvent
& /* event */) {
410 return handle_key_press_event_
;
412 bool MouseEventCallback(const blink::WebMouseEvent
& /* event */) {
413 return handle_mouse_event_
;
418 void SetUp() override
{
419 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
420 command_line
->AppendSwitch(switches::kValidateInputEventStream
);
422 browser_context_
.reset(new TestBrowserContext());
423 delegate_
.reset(new MockRenderWidgetHostDelegate());
424 process_
= new RenderWidgetHostProcess(browser_context_
.get());
425 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
426 if (IsDelegatedRendererEnabled()) {
427 ImageTransportFactory::InitializeForUnitTests(
428 scoped_ptr
<ImageTransportFactory
>(
429 new NoTransportImageTransportFactory
));
432 #if defined(USE_AURA)
433 screen_
.reset(aura::TestScreen::Create(gfx::Size()));
434 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
.get());
436 host_
.reset(new MockRenderWidgetHost(delegate_
.get(), process_
,
437 process_
->GetNextRoutingID()));
438 view_
.reset(new TestView(host_
.get()));
439 ConfigureView(view_
.get());
440 host_
->SetView(view_
.get());
441 SetInitialRenderSizeParams();
443 host_
->DisableGestureDebounce();
446 void TearDown() override
{
451 browser_context_
.reset();
453 #if defined(USE_AURA)
454 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, nullptr);
457 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
458 if (IsDelegatedRendererEnabled())
459 ImageTransportFactory::Terminate();
462 // Process all pending tasks to avoid leaks.
463 base::MessageLoop::current()->RunUntilIdle();
466 void SetInitialRenderSizeParams() {
467 ViewMsg_Resize_Params render_size_params
;
468 host_
->GetResizeParams(&render_size_params
);
469 host_
->SetInitialRenderSizeParams(render_size_params
);
472 virtual void ConfigureView(TestView
* view
) {
475 int64
GetLatencyComponentId() {
476 return host_
->GetLatencyComponentId();
479 void SendInputEventACK(WebInputEvent::Type type
,
480 InputEventAckState ack_result
) {
481 DCHECK(!WebInputEvent::isTouchEventType(type
));
482 InputEventAck
ack(type
, ack_result
);
483 host_
->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack
));
486 double GetNextSimulatedEventTimeSeconds() {
487 last_simulated_event_time_seconds_
+= simulated_event_time_delta_seconds_
;
488 return last_simulated_event_time_seconds_
;
491 void SimulateKeyboardEvent(WebInputEvent::Type type
) {
492 SimulateKeyboardEvent(type
, 0);
495 void SimulateKeyboardEvent(WebInputEvent::Type type
, int modifiers
) {
496 WebKeyboardEvent event
= SyntheticWebKeyboardEventBuilder::Build(type
);
497 event
.modifiers
= modifiers
;
498 NativeWebKeyboardEvent native_event
;
499 memcpy(&native_event
, &event
, sizeof(event
));
500 host_
->ForwardKeyboardEvent(native_event
);
503 void SimulateMouseEvent(WebInputEvent::Type type
) {
504 host_
->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type
));
507 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type
,
508 const ui::LatencyInfo
& ui_latency
) {
509 host_
->ForwardMouseEventWithLatencyInfo(
510 SyntheticWebMouseEventBuilder::Build(type
),
514 void SimulateWheelEvent(float dX
, float dY
, int modifiers
, bool precise
) {
515 host_
->ForwardWheelEvent(
516 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
));
519 void SimulateWheelEventWithLatencyInfo(float dX
,
523 const ui::LatencyInfo
& ui_latency
) {
524 host_
->ForwardWheelEventWithLatencyInfo(
525 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
),
529 void SimulateMouseMove(int x
, int y
, int modifiers
) {
530 SimulateMouseEvent(WebInputEvent::MouseMove
, x
, y
, modifiers
, false);
533 void SimulateMouseEvent(
534 WebInputEvent::Type type
, int x
, int y
, int modifiers
, bool pressed
) {
535 WebMouseEvent event
=
536 SyntheticWebMouseEventBuilder::Build(type
, x
, y
, modifiers
);
538 event
.button
= WebMouseEvent::ButtonLeft
;
539 event
.timeStampSeconds
= GetNextSimulatedEventTimeSeconds();
540 host_
->ForwardMouseEvent(event
);
543 // Inject simple synthetic WebGestureEvent instances.
544 void SimulateGestureEvent(WebInputEvent::Type type
,
545 WebGestureDevice sourceDevice
) {
546 host_
->ForwardGestureEvent(
547 SyntheticWebGestureEventBuilder::Build(type
, sourceDevice
));
550 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type
,
551 WebGestureDevice sourceDevice
,
552 const ui::LatencyInfo
& ui_latency
) {
553 host_
->ForwardGestureEventWithLatencyInfo(
554 SyntheticWebGestureEventBuilder::Build(type
, sourceDevice
),
558 // Set the timestamp for the touch-event.
559 void SetTouchTimestamp(base::TimeDelta timestamp
) {
560 touch_event_
.SetTimestamp(timestamp
);
563 // Sends a touch event (irrespective of whether the page has a touch-event
565 uint32
SendTouchEvent() {
566 uint32 touch_event_id
= touch_event_
.uniqueTouchEventId
;
567 host_
->ForwardTouchEventWithLatencyInfo(touch_event_
, ui::LatencyInfo());
569 touch_event_
.ResetPoints();
570 return touch_event_id
;
573 int PressTouchPoint(int x
, int y
) {
574 return touch_event_
.PressPoint(x
, y
);
577 void MoveTouchPoint(int index
, int x
, int y
) {
578 touch_event_
.MovePoint(index
, x
, y
);
581 void ReleaseTouchPoint(int index
) {
582 touch_event_
.ReleasePoint(index
);
585 const WebInputEvent
* GetInputEventFromMessage(const IPC::Message
& message
) {
586 base::PickleIterator
iter(message
);
589 if (!iter
.ReadData(&data
, &data_length
))
591 return reinterpret_cast<const WebInputEvent
*>(data
);
594 base::MessageLoopForUI message_loop_
;
596 scoped_ptr
<TestBrowserContext
> browser_context_
;
597 RenderWidgetHostProcess
* process_
; // Deleted automatically by the widget.
598 scoped_ptr
<MockRenderWidgetHostDelegate
> delegate_
;
599 scoped_ptr
<MockRenderWidgetHost
> host_
;
600 scoped_ptr
<TestView
> view_
;
601 scoped_ptr
<gfx::Screen
> screen_
;
602 bool handle_key_press_event_
;
603 bool handle_mouse_event_
;
604 double last_simulated_event_time_seconds_
;
605 double simulated_event_time_delta_seconds_
;
608 SyntheticWebTouchEvent touch_event_
;
610 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest
);
613 #if GTEST_HAS_PARAM_TEST
614 // RenderWidgetHostWithSourceTest ----------------------------------------------
616 // This is for tests that are to be run for all source devices.
617 class RenderWidgetHostWithSourceTest
618 : public RenderWidgetHostTest
,
619 public testing::WithParamInterface
<WebGestureDevice
> {};
620 #endif // GTEST_HAS_PARAM_TEST
624 // -----------------------------------------------------------------------------
626 TEST_F(RenderWidgetHostTest
, Resize
) {
627 // The initial bounds is the empty rect, so setting it to the same thing
628 // shouldn't send the resize message.
629 view_
->set_bounds(gfx::Rect());
631 EXPECT_FALSE(host_
->resize_ack_pending_
);
632 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
634 // No resize ack if the physical backing gets set, but the view bounds are
636 view_
->SetMockPhysicalBackingSize(gfx::Size(200, 200));
638 EXPECT_FALSE(host_
->resize_ack_pending_
);
640 // Setting the view bounds to nonzero should send out the notification.
641 // but should not expect ack for empty physical backing size.
642 gfx::Rect
original_size(0, 0, 100, 100);
643 process_
->sink().ClearMessages();
644 view_
->set_bounds(original_size
);
645 view_
->SetMockPhysicalBackingSize(gfx::Size());
647 EXPECT_FALSE(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
));
651 // Setting the bounds and physical backing size to nonzero should send out
652 // the notification and expect an ack.
653 process_
->sink().ClearMessages();
654 view_
->ClearMockPhysicalBackingSize();
656 EXPECT_TRUE(host_
->resize_ack_pending_
);
657 EXPECT_EQ(original_size
.size(), host_
->old_resize_params_
->new_size
);
658 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
659 ViewHostMsg_UpdateRect_Params params
;
660 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
661 params
.view_size
= original_size
.size();
662 host_
->OnUpdateRect(params
);
663 EXPECT_FALSE(host_
->resize_ack_pending_
);
665 // Send out a update that's not a resize ack after setting resize ack pending
666 // flag. This should not clean the resize ack pending flag.
667 process_
->sink().ClearMessages();
668 gfx::Rect
second_size(0, 0, 110, 110);
669 EXPECT_FALSE(host_
->resize_ack_pending_
);
670 view_
->set_bounds(second_size
);
672 EXPECT_TRUE(host_
->resize_ack_pending_
);
674 params
.view_size
= gfx::Size(100, 100);
675 host_
->OnUpdateRect(params
);
676 EXPECT_TRUE(host_
->resize_ack_pending_
);
677 EXPECT_EQ(second_size
.size(), host_
->old_resize_params_
->new_size
);
679 // Sending out a new notification should NOT send out a new IPC message since
680 // a resize ACK is pending.
681 gfx::Rect
third_size(0, 0, 120, 120);
682 process_
->sink().ClearMessages();
683 view_
->set_bounds(third_size
);
685 EXPECT_TRUE(host_
->resize_ack_pending_
);
686 EXPECT_EQ(second_size
.size(), host_
->old_resize_params_
->new_size
);
687 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
689 // Send a update that's a resize ack, but for the original_size we sent. Since
690 // this isn't the second_size, the message handler should immediately send
691 // a new resize message for the new size to the renderer.
692 process_
->sink().ClearMessages();
693 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
694 params
.view_size
= original_size
.size();
695 host_
->OnUpdateRect(params
);
696 EXPECT_TRUE(host_
->resize_ack_pending_
);
697 EXPECT_EQ(third_size
.size(), host_
->old_resize_params_
->new_size
);
698 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
700 // Send the resize ack for the latest size.
701 process_
->sink().ClearMessages();
702 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
703 params
.view_size
= third_size
.size();
704 host_
->OnUpdateRect(params
);
705 EXPECT_FALSE(host_
->resize_ack_pending_
);
706 EXPECT_EQ(third_size
.size(), host_
->old_resize_params_
->new_size
);
707 EXPECT_FALSE(process_
->sink().GetFirstMessageMatching(ViewMsg_Resize::ID
));
709 // Now clearing the bounds should send out a notification but we shouldn't
710 // expect a resize ack (since the renderer won't ack empty sizes). The message
711 // should contain the new size (0x0) and not the previous one that we skipped
712 process_
->sink().ClearMessages();
713 view_
->set_bounds(gfx::Rect());
715 EXPECT_FALSE(host_
->resize_ack_pending_
);
716 EXPECT_EQ(gfx::Size(), host_
->old_resize_params_
->new_size
);
717 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
719 // Send a rect that has no area but has either width or height set.
720 process_
->sink().ClearMessages();
721 view_
->set_bounds(gfx::Rect(0, 0, 0, 30));
723 EXPECT_FALSE(host_
->resize_ack_pending_
);
724 EXPECT_EQ(gfx::Size(0, 30), host_
->old_resize_params_
->new_size
);
725 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
727 // Set the same size again. It should not be sent again.
728 process_
->sink().ClearMessages();
730 EXPECT_FALSE(host_
->resize_ack_pending_
);
731 EXPECT_EQ(gfx::Size(0, 30), host_
->old_resize_params_
->new_size
);
732 EXPECT_FALSE(process_
->sink().GetFirstMessageMatching(ViewMsg_Resize::ID
));
734 // A different size should be sent again, however.
735 view_
->set_bounds(gfx::Rect(0, 0, 0, 31));
737 EXPECT_FALSE(host_
->resize_ack_pending_
);
738 EXPECT_EQ(gfx::Size(0, 31), host_
->old_resize_params_
->new_size
);
739 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
742 // Test that a resize event is sent if WasResized() is called after a
743 // WebScreenInfo change.
744 TEST_F(RenderWidgetHostTest
, ResizeScreenInfo
) {
745 blink::WebScreenInfo screen_info
;
746 screen_info
.deviceScaleFactor
= 1.f
;
747 screen_info
.rect
= blink::WebRect(0, 0, 800, 600);
748 screen_info
.availableRect
= blink::WebRect(0, 0, 800, 600);
749 screen_info
.orientationAngle
= 0;
750 screen_info
.orientationType
= blink::WebScreenOrientationPortraitPrimary
;
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
.orientationAngle
= 180;
759 screen_info
.orientationType
= blink::WebScreenOrientationLandscapePrimary
;
761 view_
->SetScreenInfo(screen_info
);
763 EXPECT_FALSE(host_
->resize_ack_pending_
);
764 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
765 process_
->sink().ClearMessages();
767 screen_info
.deviceScaleFactor
= 2.f
;
769 view_
->SetScreenInfo(screen_info
);
771 EXPECT_FALSE(host_
->resize_ack_pending_
);
772 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
773 process_
->sink().ClearMessages();
776 view_
->SetScreenInfo(screen_info
);
778 EXPECT_FALSE(host_
->resize_ack_pending_
);
779 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
782 // Test for crbug.com/25097. If a renderer crashes between a resize and the
783 // corresponding update message, we must be sure to clear the resize ack logic.
784 TEST_F(RenderWidgetHostTest
, ResizeThenCrash
) {
785 // Clear the first Resize message that carried screen info.
786 process_
->sink().ClearMessages();
788 // Setting the bounds to a "real" rect should send out the notification.
789 gfx::Rect
original_size(0, 0, 100, 100);
790 view_
->set_bounds(original_size
);
792 EXPECT_TRUE(host_
->resize_ack_pending_
);
793 EXPECT_EQ(original_size
.size(), host_
->old_resize_params_
->new_size
);
794 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
796 // Simulate a renderer crash before the update message. Ensure all the
797 // resize ack logic is cleared. Must clear the view first so it doesn't get
799 host_
->SetView(NULL
);
800 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
801 EXPECT_FALSE(host_
->resize_ack_pending_
);
802 EXPECT_EQ(gfx::Size(), host_
->old_resize_params_
->new_size
);
804 // Reset the view so we can exit the test cleanly.
805 host_
->SetView(view_
.get());
808 // Unable to include render_widget_host_view_mac.h and compile.
809 #if !defined(OS_MACOSX)
810 // Tests setting background transparency.
811 TEST_F(RenderWidgetHostTest
, Background
) {
812 scoped_ptr
<RenderWidgetHostViewBase
> view
;
813 #if defined(USE_AURA)
814 view
.reset(new RenderWidgetHostViewAura(host_
.get(), false));
815 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
816 view
->InitAsChild(NULL
);
817 #elif defined(OS_ANDROID)
818 view
.reset(new RenderWidgetHostViewAndroid(host_
.get(), NULL
));
820 host_
->SetView(view
.get());
822 EXPECT_TRUE(view
->GetBackgroundOpaque());
823 view
->SetBackgroundColor(SK_ColorTRANSPARENT
);
824 EXPECT_FALSE(view
->GetBackgroundOpaque());
826 const IPC::Message
* set_background
=
827 process_
->sink().GetUniqueMessageMatching(
828 ViewMsg_SetBackgroundOpaque::ID
);
829 ASSERT_TRUE(set_background
);
830 base::Tuple
<bool> sent_background
;
831 ViewMsg_SetBackgroundOpaque::Read(set_background
, &sent_background
);
832 EXPECT_FALSE(base::get
<0>(sent_background
));
834 #if defined(USE_AURA)
835 // See the comment above |InitAsChild(NULL)|.
836 host_
->SetView(NULL
);
837 static_cast<RenderWidgetHostViewBase
*>(view
.release())->Destroy();
842 // Test that we don't paint when we're hidden, but we still send the ACK. Most
843 // of the rest of the painting is tested in the GetBackingStore* ones.
844 TEST_F(RenderWidgetHostTest
, HiddenPaint
) {
845 BrowserThreadImpl
ui_thread(BrowserThread::UI
, base::MessageLoop::current());
846 // Hide the widget, it should have sent out a message to the renderer.
847 EXPECT_FALSE(host_
->is_hidden_
);
849 EXPECT_TRUE(host_
->is_hidden_
);
850 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID
));
852 // Send it an update as from the renderer.
853 process_
->sink().ClearMessages();
854 ViewHostMsg_UpdateRect_Params params
;
855 params
.view_size
= gfx::Size(100, 100);
856 host_
->OnUpdateRect(params
);
859 process_
->sink().ClearMessages();
860 host_
->WasShown(ui::LatencyInfo());
861 EXPECT_FALSE(host_
->is_hidden_
);
863 // It should have sent out a restored message with a request to paint.
864 const IPC::Message
* restored
= process_
->sink().GetUniqueMessageMatching(
865 ViewMsg_WasShown::ID
);
866 ASSERT_TRUE(restored
);
867 base::Tuple
<bool, ui::LatencyInfo
> needs_repaint
;
868 ViewMsg_WasShown::Read(restored
, &needs_repaint
);
869 EXPECT_TRUE(base::get
<0>(needs_repaint
));
872 TEST_F(RenderWidgetHostTest
, IgnoreKeyEventsHandledByRenderer
) {
873 // Simulate a keyboard event.
874 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
876 // Make sure we sent the input event to the renderer.
877 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
878 InputMsg_HandleInputEvent::ID
));
879 process_
->sink().ClearMessages();
881 // Send the simulated response from the renderer back.
882 SendInputEventACK(WebInputEvent::RawKeyDown
,
883 INPUT_EVENT_ACK_STATE_CONSUMED
);
884 EXPECT_FALSE(delegate_
->unhandled_keyboard_event_called());
887 TEST_F(RenderWidgetHostTest
, PreHandleRawKeyDownEvent
) {
888 // Simluate the situation that the browser handled the key down event during
889 // pre-handle phrase.
890 delegate_
->set_prehandle_keyboard_event(true);
891 process_
->sink().ClearMessages();
893 // Simulate a keyboard event.
894 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
896 EXPECT_TRUE(delegate_
->prehandle_keyboard_event_called());
897 EXPECT_EQ(WebInputEvent::RawKeyDown
,
898 delegate_
->prehandle_keyboard_event_type());
900 // Make sure the RawKeyDown event is not sent to the renderer.
901 EXPECT_EQ(0U, process_
->sink().message_count());
903 // The browser won't pre-handle a Char event.
904 delegate_
->set_prehandle_keyboard_event(false);
906 // Forward the Char event.
907 SimulateKeyboardEvent(WebInputEvent::Char
);
909 // Make sure the Char event is suppressed.
910 EXPECT_EQ(0U, process_
->sink().message_count());
912 // Forward the KeyUp event.
913 SimulateKeyboardEvent(WebInputEvent::KeyUp
);
915 // Make sure only KeyUp was sent to the renderer.
916 EXPECT_EQ(1U, process_
->sink().message_count());
917 EXPECT_EQ(InputMsg_HandleInputEvent::ID
,
918 process_
->sink().GetMessageAt(0)->type());
919 process_
->sink().ClearMessages();
921 // Send the simulated response from the renderer back.
922 SendInputEventACK(WebInputEvent::KeyUp
,
923 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
925 EXPECT_TRUE(delegate_
->unhandled_keyboard_event_called());
926 EXPECT_EQ(WebInputEvent::KeyUp
, delegate_
->unhandled_keyboard_event_type());
929 TEST_F(RenderWidgetHostTest
, UnhandledWheelEvent
) {
930 SimulateWheelEvent(-5, 0, 0, true);
932 // Make sure we sent the input event to the renderer.
933 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
934 InputMsg_HandleInputEvent::ID
));
935 process_
->sink().ClearMessages();
937 // Send the simulated response from the renderer back.
938 SendInputEventACK(WebInputEvent::MouseWheel
,
939 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
940 EXPECT_TRUE(delegate_
->handle_wheel_event_called());
941 EXPECT_EQ(1, view_
->unhandled_wheel_event_count());
942 EXPECT_EQ(-5, view_
->unhandled_wheel_event().deltaX
);
945 TEST_F(RenderWidgetHostTest
, HandleWheelEvent
) {
946 // Indicate that we're going to handle this wheel event
947 delegate_
->set_handle_wheel_event(true);
949 SimulateWheelEvent(-5, 0, 0, true);
951 // Make sure we sent the input event to the renderer.
952 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
953 InputMsg_HandleInputEvent::ID
));
954 process_
->sink().ClearMessages();
956 // Send the simulated response from the renderer back.
957 SendInputEventACK(WebInputEvent::MouseWheel
,
958 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
960 // ensure the wheel event handler was invoked
961 EXPECT_TRUE(delegate_
->handle_wheel_event_called());
963 // and that it suppressed the unhandled wheel event handler.
964 EXPECT_EQ(0, view_
->unhandled_wheel_event_count());
967 TEST_F(RenderWidgetHostTest
, UnhandledGestureEvent
) {
968 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap
,
969 blink::WebGestureDeviceTouchscreen
);
971 // Make sure we sent the input event to the renderer.
972 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
973 InputMsg_HandleInputEvent::ID
));
974 process_
->sink().ClearMessages();
976 // Send the simulated response from the renderer back.
977 SendInputEventACK(WebInputEvent::GestureTwoFingerTap
,
978 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
979 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap
, view_
->gesture_event_type());
980 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED
, view_
->ack_result());
983 // Test that the hang monitor timer expires properly if a new timer is started
984 // while one is in progress (see crbug.com/11007).
985 TEST_F(RenderWidgetHostTest
, DontPostponeHangMonitorTimeout
) {
986 // Start with a short timeout.
987 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
989 // Immediately try to add a long 30 second timeout.
990 EXPECT_FALSE(host_
->unresponsive_timer_fired());
991 host_
->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
993 // Wait long enough for first timeout and see if it fired.
994 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
995 FROM_HERE
, base::MessageLoop::QuitClosure(),
996 TimeDelta::FromMilliseconds(10));
997 base::MessageLoop::current()->Run();
998 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1001 // Test that the hang monitor timer expires properly if it is started, stopped,
1002 // and then started again.
1003 TEST_F(RenderWidgetHostTest
, StopAndStartHangMonitorTimeout
) {
1004 // Start with a short timeout, then stop it.
1005 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1006 host_
->StopHangMonitorTimeout();
1008 // Start it again to ensure it still works.
1009 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1010 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1012 // Wait long enough for first timeout and see if it fired.
1013 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1014 FROM_HERE
, base::MessageLoop::QuitClosure(),
1015 TimeDelta::FromMilliseconds(40));
1016 base::MessageLoop::current()->Run();
1017 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1020 // Test that the hang monitor timer expires properly if it is started, then
1021 // updated to a shorter duration.
1022 TEST_F(RenderWidgetHostTest
, ShorterDelayHangMonitorTimeout
) {
1023 // Start with a timeout.
1024 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
1026 // Start it again with shorter delay.
1027 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1028 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
1030 // Wait long enough for the second timeout and see if it fired.
1031 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1032 FROM_HERE
, base::MessageLoop::QuitClosure(),
1033 TimeDelta::FromMilliseconds(25));
1034 base::MessageLoop::current()->Run();
1035 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1038 // Test that the hang monitor timer is effectively disabled when the widget is
1040 TEST_F(RenderWidgetHostTest
, HangMonitorTimeoutDisabledForInputWhenHidden
) {
1041 host_
->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(1));
1042 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1044 // Hiding the widget should deactivate the timeout.
1047 // The timeout should not fire.
1048 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1049 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1050 FROM_HERE
, base::MessageLoop::QuitClosure(),
1051 TimeDelta::FromMicroseconds(2));
1052 base::MessageLoop::current()->Run();
1053 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1055 // The timeout should never reactivate while hidden.
1056 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1057 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1058 FROM_HERE
, base::MessageLoop::QuitClosure(),
1059 TimeDelta::FromMicroseconds(2));
1060 base::MessageLoop::current()->Run();
1061 EXPECT_FALSE(host_
->unresponsive_timer_fired());
1063 // Showing the widget should restore the timeout, as the events have
1064 // not yet been ack'ed.
1065 host_
->WasShown(ui::LatencyInfo());
1066 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1067 FROM_HERE
, base::MessageLoop::QuitClosure(),
1068 TimeDelta::FromMicroseconds(2));
1069 base::MessageLoop::current()->Run();
1070 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1073 // Test that the hang monitor catches two input events but only one ack.
1074 // This can happen if the second input event causes the renderer to hang.
1075 // This test will catch a regression of crbug.com/111185.
1076 TEST_F(RenderWidgetHostTest
, MultipleInputEvents
) {
1077 // Configure the host to wait 10ms before considering
1078 // the renderer hung.
1079 host_
->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(10));
1081 // Send two events but only one ack.
1082 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1083 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1084 SendInputEventACK(WebInputEvent::RawKeyDown
,
1085 INPUT_EVENT_ACK_STATE_CONSUMED
);
1087 // Wait long enough for first timeout and see if it fired.
1088 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1089 FROM_HERE
, base::MessageLoop::QuitClosure(),
1090 TimeDelta::FromMicroseconds(20));
1091 base::MessageLoop::current()->Run();
1092 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1095 std::string
GetInputMessageTypes(RenderWidgetHostProcess
* process
) {
1097 for (size_t i
= 0; i
< process
->sink().message_count(); ++i
) {
1098 const IPC::Message
*message
= process
->sink().GetMessageAt(i
);
1099 EXPECT_EQ(InputMsg_HandleInputEvent::ID
, message
->type());
1100 InputMsg_HandleInputEvent::Param params
;
1101 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message
, ¶ms
));
1102 const WebInputEvent
* event
= base::get
<0>(params
);
1105 result
+= WebInputEventTraits::GetName(event
->type
);
1107 process
->sink().ClearMessages();
1111 TEST_F(RenderWidgetHostTest
, TouchEmulator
) {
1112 simulated_event_time_delta_seconds_
= 0.1;
1113 // Immediately ack all touches instead of sending them to the renderer.
1114 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1115 host_
->SetTouchEventEmulationEnabled(
1116 true, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1117 process_
->sink().ClearMessages();
1118 view_
->set_bounds(gfx::Rect(0, 0, 400, 200));
1121 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1122 EXPECT_EQ(0U, process_
->sink().message_count());
1124 // Mouse press becomes touch start which in turn becomes tap.
1125 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 10, 0, true);
1126 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1127 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1129 // Mouse drag generates touch move, cancels tap and starts scroll.
1130 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 30, 0, true);
1131 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1133 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1134 GetInputMessageTypes(process_
));
1135 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1136 INPUT_EVENT_ACK_STATE_CONSUMED
);
1137 EXPECT_EQ(0U, process_
->sink().message_count());
1139 // Mouse drag with shift becomes pinch.
1141 WebInputEvent::MouseMove
, 10, 40, WebInputEvent::ShiftKey
, true);
1142 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1143 EXPECT_EQ("GesturePinchBegin",
1144 GetInputMessageTypes(process_
));
1145 EXPECT_EQ(0U, process_
->sink().message_count());
1148 WebInputEvent::MouseMove
, 10, 50, WebInputEvent::ShiftKey
, true);
1149 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1150 EXPECT_EQ("GesturePinchUpdate",
1151 GetInputMessageTypes(process_
));
1152 SendInputEventACK(WebInputEvent::GesturePinchUpdate
,
1153 INPUT_EVENT_ACK_STATE_CONSUMED
);
1154 EXPECT_EQ(0U, process_
->sink().message_count());
1156 // Mouse drag without shift becomes scroll again.
1157 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 60, 0, true);
1158 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1159 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1160 GetInputMessageTypes(process_
));
1161 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1162 INPUT_EVENT_ACK_STATE_CONSUMED
);
1163 EXPECT_EQ(0U, process_
->sink().message_count());
1165 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 70, 0, true);
1166 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1167 EXPECT_EQ("GestureScrollUpdate",
1168 GetInputMessageTypes(process_
));
1169 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1170 INPUT_EVENT_ACK_STATE_CONSUMED
);
1171 EXPECT_EQ(0U, process_
->sink().message_count());
1173 SimulateMouseEvent(WebInputEvent::MouseUp
, 10, 70, 0, true);
1174 EXPECT_EQ(WebInputEvent::TouchEnd
, host_
->acked_touch_event_type());
1175 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_
));
1176 EXPECT_EQ(0U, process_
->sink().message_count());
1178 // Mouse move does nothing.
1179 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 80, 0, false);
1180 EXPECT_EQ(0U, process_
->sink().message_count());
1182 // Another mouse down continues scroll.
1183 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 80, 0, true);
1184 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1185 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1186 EXPECT_EQ(0U, process_
->sink().message_count());
1188 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 100, 0, true);
1189 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1191 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1192 GetInputMessageTypes(process_
));
1193 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1194 INPUT_EVENT_ACK_STATE_CONSUMED
);
1195 EXPECT_EQ(0U, process_
->sink().message_count());
1199 WebInputEvent::MouseMove
, 10, 110, WebInputEvent::ShiftKey
, true);
1200 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1201 EXPECT_EQ("GesturePinchBegin",
1202 GetInputMessageTypes(process_
));
1203 EXPECT_EQ(0U, process_
->sink().message_count());
1206 WebInputEvent::MouseMove
, 10, 120, WebInputEvent::ShiftKey
, true);
1207 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1208 EXPECT_EQ("GesturePinchUpdate",
1209 GetInputMessageTypes(process_
));
1210 SendInputEventACK(WebInputEvent::GesturePinchUpdate
,
1211 INPUT_EVENT_ACK_STATE_CONSUMED
);
1212 EXPECT_EQ(0U, process_
->sink().message_count());
1214 // Turn off emulation during a pinch.
1215 host_
->SetTouchEventEmulationEnabled(
1216 false, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1217 EXPECT_EQ(WebInputEvent::TouchCancel
, host_
->acked_touch_event_type());
1218 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1219 GetInputMessageTypes(process_
));
1220 EXPECT_EQ(0U, process_
->sink().message_count());
1222 // Mouse event should pass untouched.
1224 WebInputEvent::MouseMove
, 10, 10, WebInputEvent::ShiftKey
, true);
1225 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_
));
1226 SendInputEventACK(WebInputEvent::MouseMove
,
1227 INPUT_EVENT_ACK_STATE_CONSUMED
);
1228 EXPECT_EQ(0U, process_
->sink().message_count());
1230 // Turn on emulation.
1231 host_
->SetTouchEventEmulationEnabled(
1232 true, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1233 EXPECT_EQ(0U, process_
->sink().message_count());
1236 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 10, 0, true);
1237 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1238 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1239 EXPECT_EQ(0U, process_
->sink().message_count());
1242 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 30, 0, true);
1243 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1245 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1246 GetInputMessageTypes(process_
));
1247 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1248 INPUT_EVENT_ACK_STATE_CONSUMED
);
1250 // Turn off emulation during a scroll.
1251 host_
->SetTouchEventEmulationEnabled(
1252 false, ui::GestureProviderConfigType::GENERIC_MOBILE
);
1253 EXPECT_EQ(WebInputEvent::TouchCancel
, host_
->acked_touch_event_type());
1255 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_
));
1256 EXPECT_EQ(0U, process_
->sink().message_count());
1259 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1260 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1261 host_->SetupForInputRouterTest(); \
1262 host_->INPUTMSG(); \
1263 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1266 TEST_InputRouterRoutes_NOARGS(Focus
);
1267 TEST_InputRouterRoutes_NOARGS(Blur
);
1268 TEST_InputRouterRoutes_NOARGS(LostCapture
);
1270 #undef TEST_InputRouterRoutes_NOARGS
1272 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1273 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1274 host_->SetupForInputRouterTest(); \
1275 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1276 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1279 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo
);
1280 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo
);
1281 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut
);
1282 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy
);
1283 #if defined(OS_MACOSX)
1284 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard
);
1286 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste
);
1287 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle
);
1288 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete
);
1289 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll
);
1290 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect
);
1292 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1294 TEST_F(RenderWidgetHostTest
, InputRouterRoutesReplace
) {
1295 host_
->SetupForInputRouterTest();
1296 host_
->Send(new InputMsg_Replace(host_
->GetRoutingID(), base::string16()));
1297 EXPECT_TRUE(host_
->mock_input_router()->send_event_called_
);
1300 TEST_F(RenderWidgetHostTest
, InputRouterRoutesReplaceMisspelling
) {
1301 host_
->SetupForInputRouterTest();
1302 host_
->Send(new InputMsg_ReplaceMisspelling(host_
->GetRoutingID(),
1304 EXPECT_TRUE(host_
->mock_input_router()->send_event_called_
);
1307 TEST_F(RenderWidgetHostTest
, IgnoreInputEvent
) {
1308 host_
->SetupForInputRouterTest();
1310 host_
->SetIgnoreInputEvents(true);
1312 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1313 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1315 SimulateMouseEvent(WebInputEvent::MouseMove
);
1316 EXPECT_FALSE(host_
->mock_input_router()->sent_mouse_event_
);
1318 SimulateWheelEvent(0, 100, 0, true);
1319 EXPECT_FALSE(host_
->mock_input_router()->sent_wheel_event_
);
1321 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
1322 blink::WebGestureDeviceTouchpad
);
1323 EXPECT_FALSE(host_
->mock_input_router()->sent_gesture_event_
);
1325 PressTouchPoint(100, 100);
1327 EXPECT_FALSE(host_
->mock_input_router()->send_touch_event_not_cancelled_
);
1330 TEST_F(RenderWidgetHostTest
, KeyboardListenerIgnoresEvent
) {
1331 host_
->SetupForInputRouterTest();
1332 host_
->AddKeyPressEventCallback(
1333 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback
,
1334 base::Unretained(this)));
1335 handle_key_press_event_
= false;
1336 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1338 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1341 TEST_F(RenderWidgetHostTest
, KeyboardListenerSuppressFollowingEvents
) {
1342 host_
->SetupForInputRouterTest();
1344 host_
->AddKeyPressEventCallback(
1345 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback
,
1346 base::Unretained(this)));
1348 // The callback handles the first event
1349 handle_key_press_event_
= true;
1350 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1352 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1354 // Following Char events should be suppressed
1355 handle_key_press_event_
= false;
1356 SimulateKeyboardEvent(WebInputEvent::Char
);
1357 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1358 SimulateKeyboardEvent(WebInputEvent::Char
);
1359 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1361 // Sending RawKeyDown event should stop suppression
1362 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1363 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1365 host_
->mock_input_router()->sent_keyboard_event_
= false;
1366 SimulateKeyboardEvent(WebInputEvent::Char
);
1367 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1370 TEST_F(RenderWidgetHostTest
, MouseEventCallbackCanHandleEvent
) {
1371 host_
->SetupForInputRouterTest();
1373 host_
->AddMouseEventCallback(
1374 base::Bind(&RenderWidgetHostTest::MouseEventCallback
,
1375 base::Unretained(this)));
1377 handle_mouse_event_
= true;
1378 SimulateMouseEvent(WebInputEvent::MouseDown
);
1380 EXPECT_FALSE(host_
->mock_input_router()->sent_mouse_event_
);
1382 handle_mouse_event_
= false;
1383 SimulateMouseEvent(WebInputEvent::MouseDown
);
1385 EXPECT_TRUE(host_
->mock_input_router()->sent_mouse_event_
);
1388 TEST_F(RenderWidgetHostTest
, InputRouterReceivesHandleInputEvent_ACK
) {
1389 host_
->SetupForInputRouterTest();
1391 SendInputEventACK(WebInputEvent::RawKeyDown
,
1392 INPUT_EVENT_ACK_STATE_CONSUMED
);
1394 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1397 TEST_F(RenderWidgetHostTest
, InputRouterReceivesMoveCaret_ACK
) {
1398 host_
->SetupForInputRouterTest();
1400 host_
->OnMessageReceived(InputHostMsg_MoveCaret_ACK(0));
1402 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1405 TEST_F(RenderWidgetHostTest
, InputRouterReceivesSelectRange_ACK
) {
1406 host_
->SetupForInputRouterTest();
1408 host_
->OnMessageReceived(InputHostMsg_SelectRange_ACK(0));
1410 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1413 TEST_F(RenderWidgetHostTest
, InputRouterReceivesHasTouchEventHandlers
) {
1414 host_
->SetupForInputRouterTest();
1416 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1418 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1421 ui::LatencyInfo
GetLatencyInfoFromInputEvent(RenderWidgetHostProcess
* process
) {
1422 const IPC::Message
* message
= process
->sink().GetUniqueMessageMatching(
1423 InputMsg_HandleInputEvent::ID
);
1424 EXPECT_TRUE(message
);
1425 InputMsg_HandleInputEvent::Param params
;
1426 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message
, ¶ms
));
1427 process
->sink().ClearMessages();
1428 return base::get
<1>(params
);
1431 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess
* process
,
1433 WebInputEvent::Type input_type
) {
1434 ui::LatencyInfo latency_info
= GetLatencyInfoFromInputEvent(process
);
1435 EXPECT_TRUE(latency_info
.FindLatency(
1436 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
,
1441 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1442 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1443 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1444 // event's LatencyInfo.
1445 TEST_F(RenderWidgetHostTest
, InputEventRWHLatencyComponent
) {
1446 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1447 process_
->sink().ClearMessages();
1449 // Tests RWHI::ForwardWheelEvent().
1450 SimulateWheelEvent(-5, 0, 0, true);
1451 CheckLatencyInfoComponentInMessage(
1452 process_
, GetLatencyComponentId(), WebInputEvent::MouseWheel
);
1453 SendInputEventACK(WebInputEvent::MouseWheel
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1455 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1456 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1457 CheckLatencyInfoComponentInMessage(
1458 process_
, GetLatencyComponentId(), WebInputEvent::MouseWheel
);
1459 SendInputEventACK(WebInputEvent::MouseWheel
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1461 // Tests RWHI::ForwardMouseEvent().
1462 SimulateMouseEvent(WebInputEvent::MouseMove
);
1463 CheckLatencyInfoComponentInMessage(
1464 process_
, GetLatencyComponentId(), WebInputEvent::MouseMove
);
1465 SendInputEventACK(WebInputEvent::MouseMove
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1467 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1468 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove
,
1470 CheckLatencyInfoComponentInMessage(
1471 process_
, GetLatencyComponentId(), WebInputEvent::MouseMove
);
1472 SendInputEventACK(WebInputEvent::MouseMove
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1474 // Tests RWHI::ForwardGestureEvent().
1475 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
1476 blink::WebGestureDeviceTouchscreen
);
1477 CheckLatencyInfoComponentInMessage(
1478 process_
, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin
);
1480 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1481 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate
,
1482 blink::WebGestureDeviceTouchscreen
,
1484 CheckLatencyInfoComponentInMessage(
1485 process_
, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate
);
1486 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1487 INPUT_EVENT_ACK_STATE_CONSUMED
);
1489 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1490 PressTouchPoint(0, 1);
1491 uint32 touch_event_id
= SendTouchEvent();
1492 InputEventAck
ack(WebInputEvent::TouchStart
, INPUT_EVENT_ACK_STATE_CONSUMED
,
1494 host_
->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack
));
1495 CheckLatencyInfoComponentInMessage(
1496 process_
, GetLatencyComponentId(), WebInputEvent::TouchStart
);
1499 TEST_F(RenderWidgetHostTest
, RendererExitedResetsInputRouter
) {
1500 // RendererExited will delete the view.
1501 host_
->SetView(new TestView(host_
.get()));
1502 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
1504 // Make sure the input router is in a fresh state.
1505 ASSERT_FALSE(host_
->input_router()->HasPendingEvents());
1508 // Regression test for http://crbug.com/401859 and http://crbug.com/522795.
1509 TEST_F(RenderWidgetHostTest
, RendererExitedResetsIsHidden
) {
1510 // RendererExited will delete the view.
1511 host_
->SetView(new TestView(host_
.get()));
1512 host_
->WasShown(ui::LatencyInfo());
1514 ASSERT_FALSE(host_
->is_hidden());
1515 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
1516 ASSERT_TRUE(host_
->is_hidden());
1518 // Make sure the input router is in a fresh state.
1519 ASSERT_FALSE(host_
->input_router()->HasPendingEvents());
1522 TEST_F(RenderWidgetHostTest
, ResizeParams
) {
1523 gfx::Rect
bounds(0, 0, 100, 100);
1524 gfx::Size
physical_backing_size(40, 50);
1525 view_
->set_bounds(bounds
);
1526 view_
->SetMockPhysicalBackingSize(physical_backing_size
);
1528 ViewMsg_Resize_Params resize_params
;
1529 host_
->GetResizeParams(&resize_params
);
1530 EXPECT_EQ(bounds
.size(), resize_params
.new_size
);
1531 EXPECT_EQ(physical_backing_size
, resize_params
.physical_backing_size
);
1534 class RenderWidgetHostInitialSizeTest
: public RenderWidgetHostTest
{
1536 RenderWidgetHostInitialSizeTest()
1537 : RenderWidgetHostTest(), initial_size_(200, 100) {}
1539 void ConfigureView(TestView
* view
) override
{
1540 view
->set_bounds(gfx::Rect(initial_size_
));
1544 gfx::Size initial_size_
;
1547 TEST_F(RenderWidgetHostInitialSizeTest
, InitialSize
) {
1548 // Having an initial size set means that the size information had been sent
1549 // with the reqiest to new up the RenderView and so subsequent WasResized
1550 // calls should not result in new IPC (unless the size has actually changed).
1551 host_
->WasResized();
1552 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
1553 EXPECT_EQ(initial_size_
, host_
->old_resize_params_
->new_size
);
1554 EXPECT_TRUE(host_
->resize_ack_pending_
);
1557 } // namespace content