Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_unittest.cc
blob6503eeabd0cfee7e47da7749a3e2e8401f414ac3
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"
6 #include "base/bind.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"
30 #endif
32 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
33 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
34 #endif
36 #if defined(USE_AURA)
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"
42 #endif
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;
54 namespace content {
56 // MockInputRouter -------------------------------------------------------------
58 class MockInputRouter : public InputRouter {
59 public:
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),
68 client_(client) {
70 virtual ~MockInputRouter() {}
72 // InputRouter
73 virtual void Flush() OVERRIDE {
74 flush_called_ = true;
76 virtual bool SendInput(scoped_ptr<IPC::Message> message) OVERRIDE {
77 send_event_called_ = true;
78 return 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 {
105 NOTREACHED();
106 return NULL;
108 virtual bool ShouldForwardTouchEvent() const OVERRIDE { return true; }
109 virtual void OnViewUpdated(int view_flags) OVERRIDE {}
110 virtual bool HasPendingEvents() const OVERRIDE { return false; }
112 // IPC::Listener
113 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
114 message_received_ = true;
115 return false;
118 bool flush_called_;
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_;
127 private:
128 InputRouterClient* client_;
130 DISALLOW_COPY_AND_ASSIGN(MockInputRouter);
133 // MockRenderWidgetHost ----------------------------------------------------
135 class MockRenderWidgetHost : public RenderWidgetHostImpl {
136 public:
137 MockRenderWidgetHost(
138 RenderWidgetHostDelegate* delegate,
139 RenderProcessHost* process,
140 int routing_id)
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 {
157 // Sniff touch acks.
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());
187 protected:
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);
198 namespace {
200 // RenderWidgetHostProcess -----------------------------------------------------
202 class RenderWidgetHostProcess : public MockRenderProcessHost {
203 public:
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; }
220 protected:
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
239 // touch-events.
240 class TestView : public TestRenderWidgetHostView {
241 public:
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) {
253 bounds_ = 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 {
282 return bounds_;
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)
292 return;
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),
314 ui::LatencyInfo()));
316 #endif
318 protected:
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_;
324 gfx::Rect bounds_;
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 {
335 public:
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_;
377 protected:
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_;
397 private:
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 {
412 public:
413 RenderWidgetHostTest()
414 : process_(NULL),
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_;
431 protected:
432 // testing::Test
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));
446 #endif
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());
451 #endif
452 host_.reset(
453 new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
454 view_.reset(new TestView(host_.get()));
455 host_->SetView(view_.get());
456 host_->Init();
457 host_->DisableGestureDebounce();
459 virtual void TearDown() {
460 view_.reset();
461 host_.reset();
462 delegate_.reset();
463 process_ = NULL;
464 browser_context_.reset();
466 #if defined(USE_AURA)
467 aura::Env::DeleteInstance();
468 screen_.reset();
469 #endif
470 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
471 if (IsDelegatedRendererEnabled())
472 ImageTransportFactory::Terminate();
473 #endif
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;
486 ack.type = type;
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),
516 ui_latency);
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,
525 float dY,
526 int modifiers,
527 bool precise,
528 const ui::LatencyInfo& ui_latency) {
529 host_->ForwardWheelEventWithLatencyInfo(
530 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
531 ui_latency);
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);
542 if (pressed)
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),
560 ui_latency);
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
569 // handler or not).
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);
590 const char* data;
591 int data_length;
592 if (!message.ReadData(&iter, &data, &data_length))
593 return NULL;
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_;
610 private:
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
625 } // namespace
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());
633 host_->WasResized();
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());
643 host_->WasResized();
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();
652 host_->WasResized();
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);
663 host_->WasResized();
664 EXPECT_TRUE(host_->resize_ack_pending_);
665 ViewHostMsg_UpdateRect_Params params;
666 process_->InitUpdateRectParams(&params);
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);
676 host_->WasResized();
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());
705 host_->WasResized();
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));
713 host_->WasResized();
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();
720 host_->WasResized();
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));
727 host_->WasResized();
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);
742 host_->WasResized();
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
749 // deleted.
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));
770 #endif
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();
789 #endif
791 #endif
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_);
799 host_->WasHidden();
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(&params);
807 host_->OnUpdateRect(params);
809 // Now unhide.
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(
946 FROM_HERE,
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(
966 FROM_HERE,
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(
985 FROM_HERE,
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(
1008 FROM_HERE,
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) {
1016 std::string result;
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, &params));
1022 const WebInputEvent* event = params.a;
1023 if (i != 0)
1024 result += " ";
1025 result += WebInputEventTraits::GetName(event->type);
1027 process->sink().ClearMessages();
1028 return result;
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));
1038 view_->Show();
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());
1051 EXPECT_EQ(
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.
1059 SimulateMouseEvent(
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());
1066 SimulateMouseEvent(
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());
1109 EXPECT_EQ(
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());
1116 // Another pinch.
1117 SimulateMouseEvent(
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());
1124 SimulateMouseEvent(
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.
1141 SimulateMouseEvent(
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());
1152 // Another touch.
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());
1158 // Scroll.
1159 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1160 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1161 EXPECT_EQ(
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);
1201 #endif
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(),
1219 base::string16()));
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);
1242 SendTouchEvent();
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,
1339 int64 component_id,
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, &params));
1346 ui::LatencyInfo latency_info = params.b;
1347 EXPECT_TRUE(latency_info.FindLatency(
1348 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
1349 component_id,
1350 NULL));
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,
1382 ui::LatencyInfo());
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,
1396 ui::LatencyInfo());
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);
1404 SendTouchEvent();
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()));
1423 host_->WasHidden();
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