1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
7 #include "base/command_line.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/shared_memory.h"
10 #include "base/timer/timer.h"
11 #include "content/browser/browser_thread_impl.h"
12 #include "content/browser/gpu/compositor_util.h"
13 #include "content/browser/renderer_host/input/input_router_impl.h"
14 #include "content/browser/renderer_host/render_widget_host_delegate.h"
15 #include "content/browser/renderer_host/render_widget_host_view_base.h"
16 #include "content/common/input/synthetic_web_input_event_builders.h"
17 #include "content/common/input_messages.h"
18 #include "content/common/view_messages.h"
19 #include "content/public/common/content_switches.h"
20 #include "content/public/test/mock_render_process_host.h"
21 #include "content/public/test/test_browser_context.h"
22 #include "content/test/test_render_view_host.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/events/keycodes/keyboard_codes.h"
25 #include "ui/gfx/canvas.h"
26 #include "ui/gfx/screen.h"
28 #if defined(OS_ANDROID)
29 #include "content/browser/renderer_host/render_widget_host_view_android.h"
32 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
33 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
37 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
38 #include "content/browser/renderer_host/ui_events_helper.h"
39 #include "ui/aura/env.h"
40 #include "ui/aura/test/test_screen.h"
41 #include "ui/events/event.h"
44 using base::TimeDelta
;
45 using blink::WebGestureDevice
;
46 using blink::WebGestureEvent
;
47 using blink::WebInputEvent
;
48 using blink::WebKeyboardEvent
;
49 using blink::WebMouseEvent
;
50 using blink::WebMouseWheelEvent
;
51 using blink::WebTouchEvent
;
52 using blink::WebTouchPoint
;
56 // MockInputRouter -------------------------------------------------------------
58 class MockInputRouter
: public InputRouter
{
60 explicit MockInputRouter(InputRouterClient
* client
)
61 : send_event_called_(false),
62 sent_mouse_event_(false),
63 sent_wheel_event_(false),
64 sent_keyboard_event_(false),
65 sent_gesture_event_(false),
66 send_touch_event_not_cancelled_(false),
67 message_received_(false),
70 virtual ~MockInputRouter() {}
73 virtual void Flush() OVERRIDE
{
76 virtual bool SendInput(scoped_ptr
<IPC::Message
> message
) OVERRIDE
{
77 send_event_called_
= true;
80 virtual void SendMouseEvent(
81 const MouseEventWithLatencyInfo
& mouse_event
) OVERRIDE
{
82 sent_mouse_event_
= true;
84 virtual void SendWheelEvent(
85 const MouseWheelEventWithLatencyInfo
& wheel_event
) OVERRIDE
{
86 sent_wheel_event_
= true;
88 virtual void SendKeyboardEvent(
89 const NativeWebKeyboardEvent
& key_event
,
90 const ui::LatencyInfo
& latency_info
,
91 bool is_shortcut
) OVERRIDE
{
92 sent_keyboard_event_
= true;
94 virtual void SendGestureEvent(
95 const GestureEventWithLatencyInfo
& gesture_event
) OVERRIDE
{
96 sent_gesture_event_
= true;
98 virtual void SendTouchEvent(
99 const TouchEventWithLatencyInfo
& touch_event
) OVERRIDE
{
100 send_touch_event_not_cancelled_
=
101 client_
->FilterInputEvent(touch_event
.event
, touch_event
.latency
) ==
102 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
104 virtual const NativeWebKeyboardEvent
* GetLastKeyboardEvent() const OVERRIDE
{
108 virtual bool ShouldForwardTouchEvent() const OVERRIDE
{ return true; }
109 virtual void OnViewUpdated(int view_flags
) OVERRIDE
{}
110 virtual bool HasPendingEvents() const OVERRIDE
{ return false; }
113 virtual bool OnMessageReceived(const IPC::Message
& message
) OVERRIDE
{
114 message_received_
= true;
119 bool send_event_called_
;
120 bool sent_mouse_event_
;
121 bool sent_wheel_event_
;
122 bool sent_keyboard_event_
;
123 bool sent_gesture_event_
;
124 bool send_touch_event_not_cancelled_
;
125 bool message_received_
;
128 InputRouterClient
* client_
;
130 DISALLOW_COPY_AND_ASSIGN(MockInputRouter
);
133 // MockRenderWidgetHost ----------------------------------------------------
135 class MockRenderWidgetHost
: public RenderWidgetHostImpl
{
137 MockRenderWidgetHost(
138 RenderWidgetHostDelegate
* delegate
,
139 RenderProcessHost
* process
,
141 : RenderWidgetHostImpl(delegate
, process
, routing_id
, false),
142 unresponsive_timer_fired_(false) {
143 acked_touch_event_type_
= blink::WebInputEvent::Undefined
;
146 // Allow poking at a few private members.
147 using RenderWidgetHostImpl::OnUpdateRect
;
148 using RenderWidgetHostImpl::RendererExited
;
149 using RenderWidgetHostImpl::last_requested_size_
;
150 using RenderWidgetHostImpl::is_hidden_
;
151 using RenderWidgetHostImpl::resize_ack_pending_
;
152 using RenderWidgetHostImpl::input_router_
;
154 virtual void OnTouchEventAck(
155 const TouchEventWithLatencyInfo
& event
,
156 InputEventAckState ack_result
) OVERRIDE
{
158 acked_touch_event_type_
= event
.event
.type
;
159 RenderWidgetHostImpl::OnTouchEventAck(event
, ack_result
);
162 bool unresponsive_timer_fired() const {
163 return unresponsive_timer_fired_
;
166 void set_hung_renderer_delay_ms(int delay_ms
) {
167 hung_renderer_delay_ms_
= delay_ms
;
170 void DisableGestureDebounce() {
171 input_router_
.reset(new InputRouterImpl(
172 process_
, this, this, routing_id_
, InputRouterImpl::Config()));
175 WebInputEvent::Type
acked_touch_event_type() const {
176 return acked_touch_event_type_
;
179 void SetupForInputRouterTest() {
180 input_router_
.reset(new MockInputRouter(this));
183 MockInputRouter
* mock_input_router() {
184 return static_cast<MockInputRouter
*>(input_router_
.get());
188 virtual void NotifyRendererUnresponsive() OVERRIDE
{
189 unresponsive_timer_fired_
= true;
192 bool unresponsive_timer_fired_
;
193 WebInputEvent::Type acked_touch_event_type_
;
195 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost
);
200 // RenderWidgetHostProcess -----------------------------------------------------
202 class RenderWidgetHostProcess
: public MockRenderProcessHost
{
204 explicit RenderWidgetHostProcess(BrowserContext
* browser_context
)
205 : MockRenderProcessHost(browser_context
),
206 update_msg_reply_flags_(0) {
208 virtual ~RenderWidgetHostProcess() {
211 void set_update_msg_reply_flags(int flags
) {
212 update_msg_reply_flags_
= flags
;
215 // Fills the given update parameters with resonable default values.
216 void InitUpdateRectParams(ViewHostMsg_UpdateRect_Params
* params
);
218 virtual bool HasConnection() const OVERRIDE
{ return true; }
221 // Indicates the flags that should be sent with a repaint request. This
222 // only has an effect when update_msg_should_reply_ is true.
223 int update_msg_reply_flags_
;
225 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess
);
228 void RenderWidgetHostProcess::InitUpdateRectParams(
229 ViewHostMsg_UpdateRect_Params
* params
) {
230 const int w
= 100, h
= 100;
232 params
->view_size
= gfx::Size(w
, h
);
233 params
->flags
= update_msg_reply_flags_
;
236 // TestView --------------------------------------------------------------------
238 // This test view allows us to specify the size, and keep track of acked
240 class TestView
: public TestRenderWidgetHostView
{
242 explicit TestView(RenderWidgetHostImpl
* rwh
)
243 : TestRenderWidgetHostView(rwh
),
244 unhandled_wheel_event_count_(0),
245 acked_event_count_(0),
246 gesture_event_type_(-1),
247 use_fake_physical_backing_size_(false),
248 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN
) {
251 // Sets the bounds returned by GetViewBounds.
252 void set_bounds(const gfx::Rect
& bounds
) {
256 const WebTouchEvent
& acked_event() const { return acked_event_
; }
257 int acked_event_count() const { return acked_event_count_
; }
258 void ClearAckedEvent() {
259 acked_event_
.type
= blink::WebInputEvent::Undefined
;
260 acked_event_count_
= 0;
263 const WebMouseWheelEvent
& unhandled_wheel_event() const {
264 return unhandled_wheel_event_
;
266 int unhandled_wheel_event_count() const {
267 return unhandled_wheel_event_count_
;
269 int gesture_event_type() const { return gesture_event_type_
; }
270 InputEventAckState
ack_result() const { return ack_result_
; }
272 void SetMockPhysicalBackingSize(const gfx::Size
& mock_physical_backing_size
) {
273 use_fake_physical_backing_size_
= true;
274 mock_physical_backing_size_
= mock_physical_backing_size
;
276 void ClearMockPhysicalBackingSize() {
277 use_fake_physical_backing_size_
= false;
280 // RenderWidgetHostView override.
281 virtual gfx::Rect
GetViewBounds() const OVERRIDE
{
284 virtual void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo
& touch
,
285 InputEventAckState ack_result
) OVERRIDE
{
286 acked_event_
= touch
.event
;
287 ++acked_event_count_
;
289 virtual void WheelEventAck(const WebMouseWheelEvent
& event
,
290 InputEventAckState ack_result
) OVERRIDE
{
291 if (ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
)
293 unhandled_wheel_event_count_
++;
294 unhandled_wheel_event_
= event
;
296 virtual void GestureEventAck(const WebGestureEvent
& event
,
297 InputEventAckState ack_result
) OVERRIDE
{
298 gesture_event_type_
= event
.type
;
299 ack_result_
= ack_result
;
301 virtual gfx::Size
GetPhysicalBackingSize() const OVERRIDE
{
302 if (use_fake_physical_backing_size_
)
303 return mock_physical_backing_size_
;
304 return TestRenderWidgetHostView::GetPhysicalBackingSize();
306 #if defined(USE_AURA)
307 virtual ~TestView() {
308 // Simulate the mouse exit event dispatched when an aura window is
309 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
310 // into WebInputEvent::MouseMove.)
311 rwh_
->input_router()->SendMouseEvent(
312 MouseEventWithLatencyInfo(
313 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove
),
319 WebMouseWheelEvent unhandled_wheel_event_
;
320 int unhandled_wheel_event_count_
;
321 WebTouchEvent acked_event_
;
322 int acked_event_count_
;
323 int gesture_event_type_
;
325 bool use_fake_physical_backing_size_
;
326 gfx::Size mock_physical_backing_size_
;
327 InputEventAckState ack_result_
;
329 DISALLOW_COPY_AND_ASSIGN(TestView
);
332 // MockRenderWidgetHostDelegate --------------------------------------------
334 class MockRenderWidgetHostDelegate
: public RenderWidgetHostDelegate
{
336 MockRenderWidgetHostDelegate()
337 : prehandle_keyboard_event_(false),
338 prehandle_keyboard_event_called_(false),
339 prehandle_keyboard_event_type_(WebInputEvent::Undefined
),
340 unhandled_keyboard_event_called_(false),
341 unhandled_keyboard_event_type_(WebInputEvent::Undefined
),
342 handle_wheel_event_(false),
343 handle_wheel_event_called_(false) {
345 virtual ~MockRenderWidgetHostDelegate() {}
347 // Tests that make sure we ignore keyboard event acknowledgments to events we
348 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
349 bool unhandled_keyboard_event_called() const {
350 return unhandled_keyboard_event_called_
;
353 WebInputEvent::Type
unhandled_keyboard_event_type() const {
354 return unhandled_keyboard_event_type_
;
357 bool prehandle_keyboard_event_called() const {
358 return prehandle_keyboard_event_called_
;
361 WebInputEvent::Type
prehandle_keyboard_event_type() const {
362 return prehandle_keyboard_event_type_
;
365 void set_prehandle_keyboard_event(bool handle
) {
366 prehandle_keyboard_event_
= handle
;
369 void set_handle_wheel_event(bool handle
) {
370 handle_wheel_event_
= handle
;
373 bool handle_wheel_event_called() {
374 return handle_wheel_event_called_
;
378 virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent
& event
,
379 bool* is_keyboard_shortcut
) OVERRIDE
{
380 prehandle_keyboard_event_type_
= event
.type
;
381 prehandle_keyboard_event_called_
= true;
382 return prehandle_keyboard_event_
;
385 virtual void HandleKeyboardEvent(
386 const NativeWebKeyboardEvent
& event
) OVERRIDE
{
387 unhandled_keyboard_event_type_
= event
.type
;
388 unhandled_keyboard_event_called_
= true;
391 virtual bool HandleWheelEvent(
392 const blink::WebMouseWheelEvent
& event
) OVERRIDE
{
393 handle_wheel_event_called_
= true;
394 return handle_wheel_event_
;
398 bool prehandle_keyboard_event_
;
399 bool prehandle_keyboard_event_called_
;
400 WebInputEvent::Type prehandle_keyboard_event_type_
;
402 bool unhandled_keyboard_event_called_
;
403 WebInputEvent::Type unhandled_keyboard_event_type_
;
405 bool handle_wheel_event_
;
406 bool handle_wheel_event_called_
;
409 // RenderWidgetHostTest --------------------------------------------------------
411 class RenderWidgetHostTest
: public testing::Test
{
413 RenderWidgetHostTest()
415 handle_key_press_event_(false),
416 handle_mouse_event_(false),
417 simulated_event_time_delta_seconds_(0) {
418 last_simulated_event_time_seconds_
=
419 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
421 virtual ~RenderWidgetHostTest() {
424 bool KeyPressEventCallback(const NativeWebKeyboardEvent
& /* event */) {
425 return handle_key_press_event_
;
427 bool MouseEventCallback(const blink::WebMouseEvent
& /* event */) {
428 return handle_mouse_event_
;
433 virtual void SetUp() {
434 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
435 command_line
->AppendSwitch(switches::kValidateInputEventStream
);
437 browser_context_
.reset(new TestBrowserContext());
438 delegate_
.reset(new MockRenderWidgetHostDelegate());
439 process_
= new RenderWidgetHostProcess(browser_context_
.get());
440 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
441 if (IsDelegatedRendererEnabled()) {
442 ImageTransportFactory::InitializeForUnitTests(
443 scoped_ptr
<ImageTransportFactory
>(
444 new NoTransportImageTransportFactory
));
447 #if defined(USE_AURA)
448 aura::Env::CreateInstance(true);
449 screen_
.reset(aura::TestScreen::Create(gfx::Size()));
450 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
.get());
453 new MockRenderWidgetHost(delegate_
.get(), process_
, MSG_ROUTING_NONE
));
454 view_
.reset(new TestView(host_
.get()));
455 host_
->SetView(view_
.get());
457 host_
->DisableGestureDebounce();
459 virtual void TearDown() {
464 browser_context_
.reset();
466 #if defined(USE_AURA)
467 aura::Env::DeleteInstance();
470 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
471 if (IsDelegatedRendererEnabled())
472 ImageTransportFactory::Terminate();
475 // Process all pending tasks to avoid leaks.
476 base::MessageLoop::current()->RunUntilIdle();
479 int64
GetLatencyComponentId() {
480 return host_
->GetLatencyComponentId();
483 void SendInputEventACK(WebInputEvent::Type type
,
484 InputEventAckState ack_result
) {
485 InputHostMsg_HandleInputEvent_ACK_Params ack
;
487 ack
.state
= ack_result
;
488 host_
->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack
));
491 double GetNextSimulatedEventTimeSeconds() {
492 last_simulated_event_time_seconds_
+= simulated_event_time_delta_seconds_
;
493 return last_simulated_event_time_seconds_
;
496 void SimulateKeyboardEvent(WebInputEvent::Type type
) {
497 SimulateKeyboardEvent(type
, 0);
500 void SimulateKeyboardEvent(WebInputEvent::Type type
, int modifiers
) {
501 WebKeyboardEvent event
= SyntheticWebKeyboardEventBuilder::Build(type
);
502 event
.modifiers
= modifiers
;
503 NativeWebKeyboardEvent native_event
;
504 memcpy(&native_event
, &event
, sizeof(event
));
505 host_
->ForwardKeyboardEvent(native_event
);
508 void SimulateMouseEvent(WebInputEvent::Type type
) {
509 host_
->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type
));
512 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type
,
513 const ui::LatencyInfo
& ui_latency
) {
514 host_
->ForwardMouseEventWithLatencyInfo(
515 SyntheticWebMouseEventBuilder::Build(type
),
519 void SimulateWheelEvent(float dX
, float dY
, int modifiers
, bool precise
) {
520 host_
->ForwardWheelEvent(
521 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
));
524 void SimulateWheelEventWithLatencyInfo(float dX
,
528 const ui::LatencyInfo
& ui_latency
) {
529 host_
->ForwardWheelEventWithLatencyInfo(
530 SyntheticWebMouseWheelEventBuilder::Build(dX
, dY
, modifiers
, precise
),
534 void SimulateMouseMove(int x
, int y
, int modifiers
) {
535 SimulateMouseEvent(WebInputEvent::MouseMove
, x
, y
, modifiers
, false);
538 void SimulateMouseEvent(
539 WebInputEvent::Type type
, int x
, int y
, int modifiers
, bool pressed
) {
540 WebMouseEvent event
=
541 SyntheticWebMouseEventBuilder::Build(type
, x
, y
, modifiers
);
543 event
.button
= WebMouseEvent::ButtonLeft
;
544 event
.timeStampSeconds
= GetNextSimulatedEventTimeSeconds();
545 host_
->ForwardMouseEvent(event
);
548 // Inject simple synthetic WebGestureEvent instances.
549 void SimulateGestureEvent(WebInputEvent::Type type
,
550 WebGestureDevice sourceDevice
) {
551 host_
->ForwardGestureEvent(
552 SyntheticWebGestureEventBuilder::Build(type
, sourceDevice
));
555 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type
,
556 WebGestureDevice sourceDevice
,
557 const ui::LatencyInfo
& ui_latency
) {
558 host_
->ForwardGestureEventWithLatencyInfo(
559 SyntheticWebGestureEventBuilder::Build(type
, sourceDevice
),
563 // Set the timestamp for the touch-event.
564 void SetTouchTimestamp(base::TimeDelta timestamp
) {
565 touch_event_
.SetTimestamp(timestamp
);
568 // Sends a touch event (irrespective of whether the page has a touch-event
570 void SendTouchEvent() {
571 host_
->ForwardTouchEventWithLatencyInfo(touch_event_
, ui::LatencyInfo());
573 touch_event_
.ResetPoints();
576 int PressTouchPoint(int x
, int y
) {
577 return touch_event_
.PressPoint(x
, y
);
580 void MoveTouchPoint(int index
, int x
, int y
) {
581 touch_event_
.MovePoint(index
, x
, y
);
584 void ReleaseTouchPoint(int index
) {
585 touch_event_
.ReleasePoint(index
);
588 const WebInputEvent
* GetInputEventFromMessage(const IPC::Message
& message
) {
589 PickleIterator
iter(message
);
592 if (!message
.ReadData(&iter
, &data
, &data_length
))
594 return reinterpret_cast<const WebInputEvent
*>(data
);
597 base::MessageLoopForUI message_loop_
;
599 scoped_ptr
<TestBrowserContext
> browser_context_
;
600 RenderWidgetHostProcess
* process_
; // Deleted automatically by the widget.
601 scoped_ptr
<MockRenderWidgetHostDelegate
> delegate_
;
602 scoped_ptr
<MockRenderWidgetHost
> host_
;
603 scoped_ptr
<TestView
> view_
;
604 scoped_ptr
<gfx::Screen
> screen_
;
605 bool handle_key_press_event_
;
606 bool handle_mouse_event_
;
607 double last_simulated_event_time_seconds_
;
608 double simulated_event_time_delta_seconds_
;
611 SyntheticWebTouchEvent touch_event_
;
613 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest
);
616 #if GTEST_HAS_PARAM_TEST
617 // RenderWidgetHostWithSourceTest ----------------------------------------------
619 // This is for tests that are to be run for all source devices.
620 class RenderWidgetHostWithSourceTest
621 : public RenderWidgetHostTest
,
622 public testing::WithParamInterface
<WebGestureDevice
> {};
623 #endif // GTEST_HAS_PARAM_TEST
627 // -----------------------------------------------------------------------------
629 TEST_F(RenderWidgetHostTest
, Resize
) {
630 // The initial bounds is the empty rect, and the screen info hasn't been sent
631 // yet, so setting it to the same thing shouldn't send the resize message.
632 view_
->set_bounds(gfx::Rect());
634 EXPECT_FALSE(host_
->resize_ack_pending_
);
635 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
637 // Setting the bounds to a "real" rect should send out the notification.
638 // but should not expect ack for empty physical backing size.
639 gfx::Rect
original_size(0, 0, 100, 100);
640 process_
->sink().ClearMessages();
641 view_
->set_bounds(original_size
);
642 view_
->SetMockPhysicalBackingSize(gfx::Size());
644 EXPECT_FALSE(host_
->resize_ack_pending_
);
645 EXPECT_EQ(original_size
.size(), host_
->last_requested_size_
);
646 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
648 // Setting the bounds to a "real" rect should send out the notification.
649 // but should not expect ack for only physical backing size change.
650 process_
->sink().ClearMessages();
651 view_
->ClearMockPhysicalBackingSize();
653 EXPECT_FALSE(host_
->resize_ack_pending_
);
654 EXPECT_EQ(original_size
.size(), host_
->last_requested_size_
);
655 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
657 // Send out a update that's not a resize ack after setting resize ack pending
658 // flag. This should not clean the resize ack pending flag.
659 process_
->sink().ClearMessages();
660 gfx::Rect
second_size(0, 0, 110, 110);
661 EXPECT_FALSE(host_
->resize_ack_pending_
);
662 view_
->set_bounds(second_size
);
664 EXPECT_TRUE(host_
->resize_ack_pending_
);
665 ViewHostMsg_UpdateRect_Params params
;
666 process_
->InitUpdateRectParams(¶ms
);
667 host_
->OnUpdateRect(params
);
668 EXPECT_TRUE(host_
->resize_ack_pending_
);
669 EXPECT_EQ(second_size
.size(), host_
->last_requested_size_
);
671 // Sending out a new notification should NOT send out a new IPC message since
672 // a resize ACK is pending.
673 gfx::Rect
third_size(0, 0, 120, 120);
674 process_
->sink().ClearMessages();
675 view_
->set_bounds(third_size
);
677 EXPECT_TRUE(host_
->resize_ack_pending_
);
678 EXPECT_EQ(second_size
.size(), host_
->last_requested_size_
);
679 EXPECT_FALSE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
681 // Send a update that's a resize ack, but for the original_size we sent. Since
682 // this isn't the second_size, the message handler should immediately send
683 // a new resize message for the new size to the renderer.
684 process_
->sink().ClearMessages();
685 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK
;
686 params
.view_size
= original_size
.size();
687 host_
->OnUpdateRect(params
);
688 EXPECT_TRUE(host_
->resize_ack_pending_
);
689 EXPECT_EQ(third_size
.size(), host_
->last_requested_size_
);
690 ASSERT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
692 // Send the resize ack for the latest size.
693 process_
->sink().ClearMessages();
694 params
.view_size
= third_size
.size();
695 host_
->OnUpdateRect(params
);
696 EXPECT_FALSE(host_
->resize_ack_pending_
);
697 EXPECT_EQ(third_size
.size(), host_
->last_requested_size_
);
698 ASSERT_FALSE(process_
->sink().GetFirstMessageMatching(ViewMsg_Resize::ID
));
700 // Now clearing the bounds should send out a notification but we shouldn't
701 // expect a resize ack (since the renderer won't ack empty sizes). The message
702 // should contain the new size (0x0) and not the previous one that we skipped
703 process_
->sink().ClearMessages();
704 view_
->set_bounds(gfx::Rect());
706 EXPECT_FALSE(host_
->resize_ack_pending_
);
707 EXPECT_EQ(gfx::Size(), host_
->last_requested_size_
);
708 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
710 // Send a rect that has no area but has either width or height set.
711 process_
->sink().ClearMessages();
712 view_
->set_bounds(gfx::Rect(0, 0, 0, 30));
714 EXPECT_FALSE(host_
->resize_ack_pending_
);
715 EXPECT_EQ(gfx::Size(0, 30), host_
->last_requested_size_
);
716 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
718 // Set the same size again. It should not be sent again.
719 process_
->sink().ClearMessages();
721 EXPECT_FALSE(host_
->resize_ack_pending_
);
722 EXPECT_EQ(gfx::Size(0, 30), host_
->last_requested_size_
);
723 EXPECT_FALSE(process_
->sink().GetFirstMessageMatching(ViewMsg_Resize::ID
));
725 // A different size should be sent again, however.
726 view_
->set_bounds(gfx::Rect(0, 0, 0, 31));
728 EXPECT_FALSE(host_
->resize_ack_pending_
);
729 EXPECT_EQ(gfx::Size(0, 31), host_
->last_requested_size_
);
730 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
733 // Test for crbug.com/25097. If a renderer crashes between a resize and the
734 // corresponding update message, we must be sure to clear the resize ack logic.
735 TEST_F(RenderWidgetHostTest
, ResizeThenCrash
) {
736 // Clear the first Resize message that carried screen info.
737 process_
->sink().ClearMessages();
739 // Setting the bounds to a "real" rect should send out the notification.
740 gfx::Rect
original_size(0, 0, 100, 100);
741 view_
->set_bounds(original_size
);
743 EXPECT_TRUE(host_
->resize_ack_pending_
);
744 EXPECT_EQ(original_size
.size(), host_
->last_requested_size_
);
745 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID
));
747 // Simulate a renderer crash before the update message. Ensure all the
748 // resize ack logic is cleared. Must clear the view first so it doesn't get
750 host_
->SetView(NULL
);
751 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
752 EXPECT_FALSE(host_
->resize_ack_pending_
);
753 EXPECT_EQ(gfx::Size(), host_
->last_requested_size_
);
755 // Reset the view so we can exit the test cleanly.
756 host_
->SetView(view_
.get());
759 // Unable to include render_widget_host_view_mac.h and compile.
760 #if !defined(OS_MACOSX)
761 // Tests setting background transparency.
762 TEST_F(RenderWidgetHostTest
, Background
) {
763 scoped_ptr
<RenderWidgetHostViewBase
> view
;
764 #if defined(USE_AURA)
765 view
.reset(new RenderWidgetHostViewAura(host_
.get()));
766 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
767 view
->InitAsChild(NULL
);
768 #elif defined(OS_ANDROID)
769 view
.reset(new RenderWidgetHostViewAndroid(host_
.get(), NULL
));
771 host_
->SetView(view
.get());
773 EXPECT_TRUE(view
->GetBackgroundOpaque());
774 view
->SetBackgroundOpaque(false);
775 EXPECT_FALSE(view
->GetBackgroundOpaque());
777 const IPC::Message
* set_background
=
778 process_
->sink().GetUniqueMessageMatching(
779 ViewMsg_SetBackgroundOpaque::ID
);
780 ASSERT_TRUE(set_background
);
781 Tuple1
<bool> sent_background
;
782 ViewMsg_SetBackgroundOpaque::Read(set_background
, &sent_background
);
783 EXPECT_FALSE(sent_background
.a
);
785 #if defined(USE_AURA)
786 // See the comment above |InitAsChild(NULL)|.
787 host_
->SetView(NULL
);
788 static_cast<RenderWidgetHostViewBase
*>(view
.release())->Destroy();
793 // Test that we don't paint when we're hidden, but we still send the ACK. Most
794 // of the rest of the painting is tested in the GetBackingStore* ones.
795 TEST_F(RenderWidgetHostTest
, HiddenPaint
) {
796 BrowserThreadImpl
ui_thread(BrowserThread::UI
, base::MessageLoop::current());
797 // Hide the widget, it should have sent out a message to the renderer.
798 EXPECT_FALSE(host_
->is_hidden_
);
800 EXPECT_TRUE(host_
->is_hidden_
);
801 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID
));
803 // Send it an update as from the renderer.
804 process_
->sink().ClearMessages();
805 ViewHostMsg_UpdateRect_Params params
;
806 process_
->InitUpdateRectParams(¶ms
);
807 host_
->OnUpdateRect(params
);
810 process_
->sink().ClearMessages();
811 host_
->WasShown(ui::LatencyInfo());
812 EXPECT_FALSE(host_
->is_hidden_
);
814 // It should have sent out a restored message with a request to paint.
815 const IPC::Message
* restored
= process_
->sink().GetUniqueMessageMatching(
816 ViewMsg_WasShown::ID
);
817 ASSERT_TRUE(restored
);
818 Tuple2
<bool, ui::LatencyInfo
> needs_repaint
;
819 ViewMsg_WasShown::Read(restored
, &needs_repaint
);
820 EXPECT_TRUE(needs_repaint
.a
);
823 TEST_F(RenderWidgetHostTest
, IgnoreKeyEventsHandledByRenderer
) {
824 // Simulate a keyboard event.
825 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
827 // Make sure we sent the input event to the renderer.
828 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
829 InputMsg_HandleInputEvent::ID
));
830 process_
->sink().ClearMessages();
832 // Send the simulated response from the renderer back.
833 SendInputEventACK(WebInputEvent::RawKeyDown
,
834 INPUT_EVENT_ACK_STATE_CONSUMED
);
835 EXPECT_FALSE(delegate_
->unhandled_keyboard_event_called());
838 TEST_F(RenderWidgetHostTest
, PreHandleRawKeyDownEvent
) {
839 // Simluate the situation that the browser handled the key down event during
840 // pre-handle phrase.
841 delegate_
->set_prehandle_keyboard_event(true);
842 process_
->sink().ClearMessages();
844 // Simulate a keyboard event.
845 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
847 EXPECT_TRUE(delegate_
->prehandle_keyboard_event_called());
848 EXPECT_EQ(WebInputEvent::RawKeyDown
,
849 delegate_
->prehandle_keyboard_event_type());
851 // Make sure the RawKeyDown event is not sent to the renderer.
852 EXPECT_EQ(0U, process_
->sink().message_count());
854 // The browser won't pre-handle a Char event.
855 delegate_
->set_prehandle_keyboard_event(false);
857 // Forward the Char event.
858 SimulateKeyboardEvent(WebInputEvent::Char
);
860 // Make sure the Char event is suppressed.
861 EXPECT_EQ(0U, process_
->sink().message_count());
863 // Forward the KeyUp event.
864 SimulateKeyboardEvent(WebInputEvent::KeyUp
);
866 // Make sure only KeyUp was sent to the renderer.
867 EXPECT_EQ(1U, process_
->sink().message_count());
868 EXPECT_EQ(InputMsg_HandleInputEvent::ID
,
869 process_
->sink().GetMessageAt(0)->type());
870 process_
->sink().ClearMessages();
872 // Send the simulated response from the renderer back.
873 SendInputEventACK(WebInputEvent::KeyUp
,
874 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
876 EXPECT_TRUE(delegate_
->unhandled_keyboard_event_called());
877 EXPECT_EQ(WebInputEvent::KeyUp
, delegate_
->unhandled_keyboard_event_type());
880 TEST_F(RenderWidgetHostTest
, UnhandledWheelEvent
) {
881 SimulateWheelEvent(-5, 0, 0, true);
883 // Make sure we sent the input event to the renderer.
884 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
885 InputMsg_HandleInputEvent::ID
));
886 process_
->sink().ClearMessages();
888 // Send the simulated response from the renderer back.
889 SendInputEventACK(WebInputEvent::MouseWheel
,
890 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
891 EXPECT_TRUE(delegate_
->handle_wheel_event_called());
892 EXPECT_EQ(1, view_
->unhandled_wheel_event_count());
893 EXPECT_EQ(-5, view_
->unhandled_wheel_event().deltaX
);
896 TEST_F(RenderWidgetHostTest
, HandleWheelEvent
) {
897 // Indicate that we're going to handle this wheel event
898 delegate_
->set_handle_wheel_event(true);
900 SimulateWheelEvent(-5, 0, 0, true);
902 // Make sure we sent the input event to the renderer.
903 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
904 InputMsg_HandleInputEvent::ID
));
905 process_
->sink().ClearMessages();
907 // Send the simulated response from the renderer back.
908 SendInputEventACK(WebInputEvent::MouseWheel
,
909 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
911 // ensure the wheel event handler was invoked
912 EXPECT_TRUE(delegate_
->handle_wheel_event_called());
914 // and that it suppressed the unhandled wheel event handler.
915 EXPECT_EQ(0, view_
->unhandled_wheel_event_count());
918 TEST_F(RenderWidgetHostTest
, UnhandledGestureEvent
) {
919 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap
,
920 blink::WebGestureDeviceTouchscreen
);
922 // Make sure we sent the input event to the renderer.
923 EXPECT_TRUE(process_
->sink().GetUniqueMessageMatching(
924 InputMsg_HandleInputEvent::ID
));
925 process_
->sink().ClearMessages();
927 // Send the simulated response from the renderer back.
928 SendInputEventACK(WebInputEvent::GestureTwoFingerTap
,
929 INPUT_EVENT_ACK_STATE_NOT_CONSUMED
);
930 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap
, view_
->gesture_event_type());
931 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED
, view_
->ack_result());
934 // Test that the hang monitor timer expires properly if a new timer is started
935 // while one is in progress (see crbug.com/11007).
936 TEST_F(RenderWidgetHostTest
, DontPostponeHangMonitorTimeout
) {
937 // Start with a short timeout.
938 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
940 // Immediately try to add a long 30 second timeout.
941 EXPECT_FALSE(host_
->unresponsive_timer_fired());
942 host_
->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
944 // Wait long enough for first timeout and see if it fired.
945 base::MessageLoop::current()->PostDelayedTask(
947 base::MessageLoop::QuitClosure(),
948 TimeDelta::FromMilliseconds(10));
949 base::MessageLoop::current()->Run();
950 EXPECT_TRUE(host_
->unresponsive_timer_fired());
953 // Test that the hang monitor timer expires properly if it is started, stopped,
954 // and then started again.
955 TEST_F(RenderWidgetHostTest
, StopAndStartHangMonitorTimeout
) {
956 // Start with a short timeout, then stop it.
957 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
958 host_
->StopHangMonitorTimeout();
960 // Start it again to ensure it still works.
961 EXPECT_FALSE(host_
->unresponsive_timer_fired());
962 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
964 // Wait long enough for first timeout and see if it fired.
965 base::MessageLoop::current()->PostDelayedTask(
967 base::MessageLoop::QuitClosure(),
968 TimeDelta::FromMilliseconds(40));
969 base::MessageLoop::current()->Run();
970 EXPECT_TRUE(host_
->unresponsive_timer_fired());
973 // Test that the hang monitor timer expires properly if it is started, then
974 // updated to a shorter duration.
975 TEST_F(RenderWidgetHostTest
, ShorterDelayHangMonitorTimeout
) {
976 // Start with a timeout.
977 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
979 // Start it again with shorter delay.
980 EXPECT_FALSE(host_
->unresponsive_timer_fired());
981 host_
->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
983 // Wait long enough for the second timeout and see if it fired.
984 base::MessageLoop::current()->PostDelayedTask(
986 base::MessageLoop::QuitClosure(),
987 TimeDelta::FromMilliseconds(25));
988 base::MessageLoop::current()->Run();
989 EXPECT_TRUE(host_
->unresponsive_timer_fired());
992 // Test that the hang monitor catches two input events but only one ack.
993 // This can happen if the second input event causes the renderer to hang.
994 // This test will catch a regression of crbug.com/111185.
995 TEST_F(RenderWidgetHostTest
, MultipleInputEvents
) {
996 // Configure the host to wait 10ms before considering
997 // the renderer hung.
998 host_
->set_hung_renderer_delay_ms(10);
1000 // Send two events but only one ack.
1001 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1002 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1003 SendInputEventACK(WebInputEvent::RawKeyDown
,
1004 INPUT_EVENT_ACK_STATE_CONSUMED
);
1006 // Wait long enough for first timeout and see if it fired.
1007 base::MessageLoop::current()->PostDelayedTask(
1009 base::MessageLoop::QuitClosure(),
1010 TimeDelta::FromMilliseconds(40));
1011 base::MessageLoop::current()->Run();
1012 EXPECT_TRUE(host_
->unresponsive_timer_fired());
1015 std::string
GetInputMessageTypes(RenderWidgetHostProcess
* process
) {
1017 for (size_t i
= 0; i
< process
->sink().message_count(); ++i
) {
1018 const IPC::Message
*message
= process
->sink().GetMessageAt(i
);
1019 EXPECT_EQ(InputMsg_HandleInputEvent::ID
, message
->type());
1020 InputMsg_HandleInputEvent::Param params
;
1021 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message
, ¶ms
));
1022 const WebInputEvent
* event
= params
.a
;
1025 result
+= WebInputEventTraits::GetName(event
->type
);
1027 process
->sink().ClearMessages();
1031 TEST_F(RenderWidgetHostTest
, TouchEmulator
) {
1032 simulated_event_time_delta_seconds_
= 0.1;
1033 // Immediately ack all touches instead of sending them to the renderer.
1034 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1035 host_
->SetTouchEventEmulationEnabled(true);
1036 process_
->sink().ClearMessages();
1037 view_
->set_bounds(gfx::Rect(0, 0, 400, 200));
1040 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 10, 0, false);
1041 EXPECT_EQ(0U, process_
->sink().message_count());
1043 // Mouse press becomes touch start which in turn becomes tap.
1044 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 10, 0, true);
1045 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1046 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1048 // Mouse drag generates touch move, cancels tap and starts scroll.
1049 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 30, 0, true);
1050 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1052 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1053 GetInputMessageTypes(process_
));
1054 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1055 INPUT_EVENT_ACK_STATE_CONSUMED
);
1056 EXPECT_EQ(0U, process_
->sink().message_count());
1058 // Mouse drag with shift becomes pinch.
1060 WebInputEvent::MouseMove
, 10, 40, WebInputEvent::ShiftKey
, true);
1061 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1062 EXPECT_EQ("GesturePinchBegin",
1063 GetInputMessageTypes(process_
));
1064 EXPECT_EQ(0U, process_
->sink().message_count());
1067 WebInputEvent::MouseMove
, 10, 50, WebInputEvent::ShiftKey
, true);
1068 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1069 EXPECT_EQ("GesturePinchUpdate",
1070 GetInputMessageTypes(process_
));
1071 SendInputEventACK(WebInputEvent::GesturePinchUpdate
,
1072 INPUT_EVENT_ACK_STATE_CONSUMED
);
1073 EXPECT_EQ(0U, process_
->sink().message_count());
1075 // Mouse drag without shift becomes scroll again.
1076 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 60, 0, true);
1077 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1078 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1079 GetInputMessageTypes(process_
));
1080 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1081 INPUT_EVENT_ACK_STATE_CONSUMED
);
1082 EXPECT_EQ(0U, process_
->sink().message_count());
1084 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 70, 0, true);
1085 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1086 EXPECT_EQ("GestureScrollUpdate",
1087 GetInputMessageTypes(process_
));
1088 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1089 INPUT_EVENT_ACK_STATE_CONSUMED
);
1090 EXPECT_EQ(0U, process_
->sink().message_count());
1092 SimulateMouseEvent(WebInputEvent::MouseUp
, 10, 70, 0, true);
1093 EXPECT_EQ(WebInputEvent::TouchEnd
, host_
->acked_touch_event_type());
1094 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_
));
1095 EXPECT_EQ(0U, process_
->sink().message_count());
1097 // Mouse move does nothing.
1098 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 80, 0, false);
1099 EXPECT_EQ(0U, process_
->sink().message_count());
1101 // Another mouse down continues scroll.
1102 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 80, 0, true);
1103 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1104 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1105 EXPECT_EQ(0U, process_
->sink().message_count());
1107 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 100, 0, true);
1108 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1110 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1111 GetInputMessageTypes(process_
));
1112 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1113 INPUT_EVENT_ACK_STATE_CONSUMED
);
1114 EXPECT_EQ(0U, process_
->sink().message_count());
1118 WebInputEvent::MouseMove
, 10, 110, WebInputEvent::ShiftKey
, true);
1119 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1120 EXPECT_EQ("GesturePinchBegin",
1121 GetInputMessageTypes(process_
));
1122 EXPECT_EQ(0U, process_
->sink().message_count());
1125 WebInputEvent::MouseMove
, 10, 120, WebInputEvent::ShiftKey
, true);
1126 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1127 EXPECT_EQ("GesturePinchUpdate",
1128 GetInputMessageTypes(process_
));
1129 SendInputEventACK(WebInputEvent::GesturePinchUpdate
,
1130 INPUT_EVENT_ACK_STATE_CONSUMED
);
1131 EXPECT_EQ(0U, process_
->sink().message_count());
1133 // Turn off emulation during a pinch.
1134 host_
->SetTouchEventEmulationEnabled(false);
1135 EXPECT_EQ(WebInputEvent::TouchCancel
, host_
->acked_touch_event_type());
1136 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1137 GetInputMessageTypes(process_
));
1138 EXPECT_EQ(0U, process_
->sink().message_count());
1140 // Mouse event should pass untouched.
1142 WebInputEvent::MouseMove
, 10, 10, WebInputEvent::ShiftKey
, true);
1143 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_
));
1144 SendInputEventACK(WebInputEvent::MouseMove
,
1145 INPUT_EVENT_ACK_STATE_CONSUMED
);
1146 EXPECT_EQ(0U, process_
->sink().message_count());
1148 // Turn on emulation.
1149 host_
->SetTouchEventEmulationEnabled(true);
1150 EXPECT_EQ(0U, process_
->sink().message_count());
1153 SimulateMouseEvent(WebInputEvent::MouseDown
, 10, 10, 0, true);
1154 EXPECT_EQ(WebInputEvent::TouchStart
, host_
->acked_touch_event_type());
1155 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_
));
1156 EXPECT_EQ(0U, process_
->sink().message_count());
1159 SimulateMouseEvent(WebInputEvent::MouseMove
, 10, 30, 0, true);
1160 EXPECT_EQ(WebInputEvent::TouchMove
, host_
->acked_touch_event_type());
1162 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1163 GetInputMessageTypes(process_
));
1164 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1165 INPUT_EVENT_ACK_STATE_CONSUMED
);
1167 // Turn off emulation during a scroll.
1168 host_
->SetTouchEventEmulationEnabled(false);
1169 EXPECT_EQ(WebInputEvent::TouchCancel
, host_
->acked_touch_event_type());
1171 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_
));
1172 EXPECT_EQ(0U, process_
->sink().message_count());
1175 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1176 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1177 host_->SetupForInputRouterTest(); \
1178 host_->INPUTMSG(); \
1179 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1182 TEST_InputRouterRoutes_NOARGS(Focus
);
1183 TEST_InputRouterRoutes_NOARGS(Blur
);
1184 TEST_InputRouterRoutes_NOARGS(LostCapture
);
1186 #undef TEST_InputRouterRoutes_NOARGS
1188 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1189 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1190 host_->SetupForInputRouterTest(); \
1191 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1192 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1195 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo
);
1196 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo
);
1197 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut
);
1198 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy
);
1199 #if defined(OS_MACOSX)
1200 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard
);
1202 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste
);
1203 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle
);
1204 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete
);
1205 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll
);
1206 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect
);
1208 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1210 TEST_F(RenderWidgetHostTest
, InputRouterRoutesReplace
) {
1211 host_
->SetupForInputRouterTest();
1212 host_
->Send(new InputMsg_Replace(host_
->GetRoutingID(), base::string16()));
1213 EXPECT_TRUE(host_
->mock_input_router()->send_event_called_
);
1216 TEST_F(RenderWidgetHostTest
, InputRouterRoutesReplaceMisspelling
) {
1217 host_
->SetupForInputRouterTest();
1218 host_
->Send(new InputMsg_ReplaceMisspelling(host_
->GetRoutingID(),
1220 EXPECT_TRUE(host_
->mock_input_router()->send_event_called_
);
1223 TEST_F(RenderWidgetHostTest
, IgnoreInputEvent
) {
1224 host_
->SetupForInputRouterTest();
1226 host_
->SetIgnoreInputEvents(true);
1228 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1229 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1231 SimulateMouseEvent(WebInputEvent::MouseMove
);
1232 EXPECT_FALSE(host_
->mock_input_router()->sent_mouse_event_
);
1234 SimulateWheelEvent(0, 100, 0, true);
1235 EXPECT_FALSE(host_
->mock_input_router()->sent_wheel_event_
);
1237 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
1238 blink::WebGestureDeviceTouchpad
);
1239 EXPECT_FALSE(host_
->mock_input_router()->sent_gesture_event_
);
1241 PressTouchPoint(100, 100);
1243 EXPECT_FALSE(host_
->mock_input_router()->send_touch_event_not_cancelled_
);
1246 TEST_F(RenderWidgetHostTest
, KeyboardListenerIgnoresEvent
) {
1247 host_
->SetupForInputRouterTest();
1248 host_
->AddKeyPressEventCallback(
1249 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback
,
1250 base::Unretained(this)));
1251 handle_key_press_event_
= false;
1252 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1254 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1257 TEST_F(RenderWidgetHostTest
, KeyboardListenerSuppressFollowingEvents
) {
1258 host_
->SetupForInputRouterTest();
1260 host_
->AddKeyPressEventCallback(
1261 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback
,
1262 base::Unretained(this)));
1264 // The callback handles the first event
1265 handle_key_press_event_
= true;
1266 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1268 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1270 // Following Char events should be suppressed
1271 handle_key_press_event_
= false;
1272 SimulateKeyboardEvent(WebInputEvent::Char
);
1273 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1274 SimulateKeyboardEvent(WebInputEvent::Char
);
1275 EXPECT_FALSE(host_
->mock_input_router()->sent_keyboard_event_
);
1277 // Sending RawKeyDown event should stop suppression
1278 SimulateKeyboardEvent(WebInputEvent::RawKeyDown
);
1279 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1281 host_
->mock_input_router()->sent_keyboard_event_
= false;
1282 SimulateKeyboardEvent(WebInputEvent::Char
);
1283 EXPECT_TRUE(host_
->mock_input_router()->sent_keyboard_event_
);
1286 TEST_F(RenderWidgetHostTest
, MouseEventCallbackCanHandleEvent
) {
1287 host_
->SetupForInputRouterTest();
1289 host_
->AddMouseEventCallback(
1290 base::Bind(&RenderWidgetHostTest::MouseEventCallback
,
1291 base::Unretained(this)));
1293 handle_mouse_event_
= true;
1294 SimulateMouseEvent(WebInputEvent::MouseDown
);
1296 EXPECT_FALSE(host_
->mock_input_router()->sent_mouse_event_
);
1298 handle_mouse_event_
= false;
1299 SimulateMouseEvent(WebInputEvent::MouseDown
);
1301 EXPECT_TRUE(host_
->mock_input_router()->sent_mouse_event_
);
1304 TEST_F(RenderWidgetHostTest
, InputRouterReceivesHandleInputEvent_ACK
) {
1305 host_
->SetupForInputRouterTest();
1307 SendInputEventACK(WebInputEvent::RawKeyDown
,
1308 INPUT_EVENT_ACK_STATE_CONSUMED
);
1310 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1313 TEST_F(RenderWidgetHostTest
, InputRouterReceivesMoveCaret_ACK
) {
1314 host_
->SetupForInputRouterTest();
1316 host_
->OnMessageReceived(ViewHostMsg_MoveCaret_ACK(0));
1318 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1321 TEST_F(RenderWidgetHostTest
, InputRouterReceivesSelectRange_ACK
) {
1322 host_
->SetupForInputRouterTest();
1324 host_
->OnMessageReceived(ViewHostMsg_SelectRange_ACK(0));
1326 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1329 TEST_F(RenderWidgetHostTest
, InputRouterReceivesHasTouchEventHandlers
) {
1330 host_
->SetupForInputRouterTest();
1332 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1334 EXPECT_TRUE(host_
->mock_input_router()->message_received_
);
1338 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess
* process
,
1340 WebInputEvent::Type input_type
) {
1341 const IPC::Message
* message
= process
->sink().GetUniqueMessageMatching(
1342 InputMsg_HandleInputEvent::ID
);
1343 ASSERT_TRUE(message
);
1344 InputMsg_HandleInputEvent::Param params
;
1345 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message
, ¶ms
));
1346 ui::LatencyInfo latency_info
= params
.b
;
1347 EXPECT_TRUE(latency_info
.FindLatency(
1348 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
,
1351 process
->sink().ClearMessages();
1354 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1355 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1356 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1357 // event's LatencyInfo.
1358 TEST_F(RenderWidgetHostTest
, InputEventRWHLatencyComponent
) {
1359 host_
->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1360 process_
->sink().ClearMessages();
1362 // Tests RWHI::ForwardWheelEvent().
1363 SimulateWheelEvent(-5, 0, 0, true);
1364 CheckLatencyInfoComponentInMessage(
1365 process_
, GetLatencyComponentId(), WebInputEvent::MouseWheel
);
1366 SendInputEventACK(WebInputEvent::MouseWheel
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1368 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1369 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1370 CheckLatencyInfoComponentInMessage(
1371 process_
, GetLatencyComponentId(), WebInputEvent::MouseWheel
);
1372 SendInputEventACK(WebInputEvent::MouseWheel
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1374 // Tests RWHI::ForwardMouseEvent().
1375 SimulateMouseEvent(WebInputEvent::MouseMove
);
1376 CheckLatencyInfoComponentInMessage(
1377 process_
, GetLatencyComponentId(), WebInputEvent::MouseMove
);
1378 SendInputEventACK(WebInputEvent::MouseMove
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1380 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1381 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove
,
1383 CheckLatencyInfoComponentInMessage(
1384 process_
, GetLatencyComponentId(), WebInputEvent::MouseMove
);
1385 SendInputEventACK(WebInputEvent::MouseMove
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1387 // Tests RWHI::ForwardGestureEvent().
1388 SimulateGestureEvent(WebInputEvent::GestureScrollBegin
,
1389 blink::WebGestureDeviceTouchscreen
);
1390 CheckLatencyInfoComponentInMessage(
1391 process_
, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin
);
1393 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1394 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate
,
1395 blink::WebGestureDeviceTouchscreen
,
1397 CheckLatencyInfoComponentInMessage(
1398 process_
, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate
);
1399 SendInputEventACK(WebInputEvent::GestureScrollUpdate
,
1400 INPUT_EVENT_ACK_STATE_CONSUMED
);
1402 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1403 PressTouchPoint(0, 1);
1405 CheckLatencyInfoComponentInMessage(
1406 process_
, GetLatencyComponentId(), WebInputEvent::TouchStart
);
1407 SendInputEventACK(WebInputEvent::TouchStart
, INPUT_EVENT_ACK_STATE_CONSUMED
);
1410 TEST_F(RenderWidgetHostTest
, RendererExitedResetsInputRouter
) {
1411 // RendererExited will delete the view.
1412 host_
->SetView(new TestView(host_
.get()));
1413 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
1415 // Make sure the input router is in a fresh state.
1416 ASSERT_FALSE(host_
->input_router()->HasPendingEvents());
1419 // Regression test for http://crbug.com/401859.
1420 TEST_F(RenderWidgetHostTest
, RendererExitedResetsIsHidden
) {
1421 // RendererExited will delete the view.
1422 host_
->SetView(new TestView(host_
.get()));
1425 ASSERT_TRUE(host_
->is_hidden());
1426 host_
->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED
, -1);
1427 ASSERT_FALSE(host_
->is_hidden());
1429 // Make sure the input router is in a fresh state.
1430 ASSERT_FALSE(host_
->input_router()->HasPendingEvents());
1433 } // namespace content