Simplify ChildProcessLauncher
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_unittest.cc
blob46acbd1dbae6d48581ac9393358222dd4d686b81
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 ~MockInputRouter() override {}
72 // InputRouter
73 bool SendInput(scoped_ptr<IPC::Message> message) override {
74 send_event_called_ = true;
75 return true;
77 void SendMouseEvent(const MouseEventWithLatencyInfo& mouse_event) override {
78 sent_mouse_event_ = true;
80 void SendWheelEvent(
81 const MouseWheelEventWithLatencyInfo& wheel_event) override {
82 sent_wheel_event_ = true;
84 void SendKeyboardEvent(const NativeWebKeyboardEvent& key_event,
85 const ui::LatencyInfo& latency_info,
86 bool is_shortcut) override {
87 sent_keyboard_event_ = true;
89 void SendGestureEvent(
90 const GestureEventWithLatencyInfo& gesture_event) override {
91 sent_gesture_event_ = true;
93 void SendTouchEvent(const TouchEventWithLatencyInfo& touch_event) override {
94 send_touch_event_not_cancelled_ =
95 client_->FilterInputEvent(touch_event.event, touch_event.latency) ==
96 INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
98 const NativeWebKeyboardEvent* GetLastKeyboardEvent() const override {
99 NOTREACHED();
100 return NULL;
102 void OnViewUpdated(int view_flags) override {}
103 void RequestNotificationWhenFlushed() override {}
104 bool HasPendingEvents() const override { return false; }
106 // IPC::Listener
107 bool OnMessageReceived(const IPC::Message& message) override {
108 message_received_ = true;
109 return false;
112 bool send_event_called_;
113 bool sent_mouse_event_;
114 bool sent_wheel_event_;
115 bool sent_keyboard_event_;
116 bool sent_gesture_event_;
117 bool send_touch_event_not_cancelled_;
118 bool message_received_;
120 private:
121 InputRouterClient* client_;
123 DISALLOW_COPY_AND_ASSIGN(MockInputRouter);
126 // MockRenderWidgetHost ----------------------------------------------------
128 class MockRenderWidgetHost : public RenderWidgetHostImpl {
129 public:
130 MockRenderWidgetHost(
131 RenderWidgetHostDelegate* delegate,
132 RenderProcessHost* process,
133 int routing_id)
134 : RenderWidgetHostImpl(delegate, process, routing_id, false),
135 unresponsive_timer_fired_(false) {
136 acked_touch_event_type_ = blink::WebInputEvent::Undefined;
139 // Allow poking at a few private members.
140 using RenderWidgetHostImpl::GetResizeParams;
141 using RenderWidgetHostImpl::OnUpdateRect;
142 using RenderWidgetHostImpl::RendererExited;
143 using RenderWidgetHostImpl::SetInitialRenderSizeParams;
144 using RenderWidgetHostImpl::old_resize_params_;
145 using RenderWidgetHostImpl::is_hidden_;
146 using RenderWidgetHostImpl::resize_ack_pending_;
147 using RenderWidgetHostImpl::input_router_;
149 void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
150 InputEventAckState ack_result) override {
151 // Sniff touch acks.
152 acked_touch_event_type_ = event.event.type;
153 RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
156 bool unresponsive_timer_fired() const {
157 return unresponsive_timer_fired_;
160 void DisableGestureDebounce() {
161 input_router_.reset(new InputRouterImpl(
162 process_, this, this, routing_id_, InputRouterImpl::Config()));
165 WebInputEvent::Type acked_touch_event_type() const {
166 return acked_touch_event_type_;
169 void SetupForInputRouterTest() {
170 input_router_.reset(new MockInputRouter(this));
173 MockInputRouter* mock_input_router() {
174 return static_cast<MockInputRouter*>(input_router_.get());
177 protected:
178 void NotifyRendererUnresponsive() override {
179 unresponsive_timer_fired_ = true;
182 bool unresponsive_timer_fired_;
183 WebInputEvent::Type acked_touch_event_type_;
185 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
188 namespace {
190 // RenderWidgetHostProcess -----------------------------------------------------
192 class RenderWidgetHostProcess : public MockRenderProcessHost {
193 public:
194 explicit RenderWidgetHostProcess(BrowserContext* browser_context)
195 : MockRenderProcessHost(browser_context) {
197 ~RenderWidgetHostProcess() override {}
199 bool HasConnection() const override { return true; }
201 protected:
202 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess);
205 // TestView --------------------------------------------------------------------
207 // This test view allows us to specify the size, and keep track of acked
208 // touch-events.
209 class TestView : public TestRenderWidgetHostView {
210 public:
211 explicit TestView(RenderWidgetHostImpl* rwh)
212 : TestRenderWidgetHostView(rwh),
213 unhandled_wheel_event_count_(0),
214 acked_event_count_(0),
215 gesture_event_type_(-1),
216 use_fake_physical_backing_size_(false),
217 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
220 // Sets the bounds returned by GetViewBounds.
221 void set_bounds(const gfx::Rect& bounds) {
222 bounds_ = bounds;
225 const WebTouchEvent& acked_event() const { return acked_event_; }
226 int acked_event_count() const { return acked_event_count_; }
227 void ClearAckedEvent() {
228 acked_event_.type = blink::WebInputEvent::Undefined;
229 acked_event_count_ = 0;
232 const WebMouseWheelEvent& unhandled_wheel_event() const {
233 return unhandled_wheel_event_;
235 int unhandled_wheel_event_count() const {
236 return unhandled_wheel_event_count_;
238 int gesture_event_type() const { return gesture_event_type_; }
239 InputEventAckState ack_result() const { return ack_result_; }
241 void SetMockPhysicalBackingSize(const gfx::Size& mock_physical_backing_size) {
242 use_fake_physical_backing_size_ = true;
243 mock_physical_backing_size_ = mock_physical_backing_size;
245 void ClearMockPhysicalBackingSize() {
246 use_fake_physical_backing_size_ = false;
249 // RenderWidgetHostView override.
250 gfx::Rect GetViewBounds() const override { return bounds_; }
251 void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
252 InputEventAckState ack_result) override {
253 acked_event_ = touch.event;
254 ++acked_event_count_;
256 void WheelEventAck(const WebMouseWheelEvent& event,
257 InputEventAckState ack_result) override {
258 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
259 return;
260 unhandled_wheel_event_count_++;
261 unhandled_wheel_event_ = event;
263 void GestureEventAck(const WebGestureEvent& event,
264 InputEventAckState ack_result) override {
265 gesture_event_type_ = event.type;
266 ack_result_ = ack_result;
268 gfx::Size GetPhysicalBackingSize() const override {
269 if (use_fake_physical_backing_size_)
270 return mock_physical_backing_size_;
271 return TestRenderWidgetHostView::GetPhysicalBackingSize();
273 #if defined(USE_AURA)
274 ~TestView() override {
275 // Simulate the mouse exit event dispatched when an aura window is
276 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
277 // into WebInputEvent::MouseMove.)
278 rwh_->input_router()->SendMouseEvent(
279 MouseEventWithLatencyInfo(
280 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove),
281 ui::LatencyInfo()));
283 #endif
285 protected:
286 WebMouseWheelEvent unhandled_wheel_event_;
287 int unhandled_wheel_event_count_;
288 WebTouchEvent acked_event_;
289 int acked_event_count_;
290 int gesture_event_type_;
291 gfx::Rect bounds_;
292 bool use_fake_physical_backing_size_;
293 gfx::Size mock_physical_backing_size_;
294 InputEventAckState ack_result_;
296 DISALLOW_COPY_AND_ASSIGN(TestView);
299 // MockRenderWidgetHostDelegate --------------------------------------------
301 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
302 public:
303 MockRenderWidgetHostDelegate()
304 : prehandle_keyboard_event_(false),
305 prehandle_keyboard_event_called_(false),
306 prehandle_keyboard_event_type_(WebInputEvent::Undefined),
307 unhandled_keyboard_event_called_(false),
308 unhandled_keyboard_event_type_(WebInputEvent::Undefined),
309 handle_wheel_event_(false),
310 handle_wheel_event_called_(false) {
312 ~MockRenderWidgetHostDelegate() override {}
314 // Tests that make sure we ignore keyboard event acknowledgments to events we
315 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
316 bool unhandled_keyboard_event_called() const {
317 return unhandled_keyboard_event_called_;
320 WebInputEvent::Type unhandled_keyboard_event_type() const {
321 return unhandled_keyboard_event_type_;
324 bool prehandle_keyboard_event_called() const {
325 return prehandle_keyboard_event_called_;
328 WebInputEvent::Type prehandle_keyboard_event_type() const {
329 return prehandle_keyboard_event_type_;
332 void set_prehandle_keyboard_event(bool handle) {
333 prehandle_keyboard_event_ = handle;
336 void set_handle_wheel_event(bool handle) {
337 handle_wheel_event_ = handle;
340 bool handle_wheel_event_called() {
341 return handle_wheel_event_called_;
344 protected:
345 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
346 bool* is_keyboard_shortcut) override {
347 prehandle_keyboard_event_type_ = event.type;
348 prehandle_keyboard_event_called_ = true;
349 return prehandle_keyboard_event_;
352 void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override {
353 unhandled_keyboard_event_type_ = event.type;
354 unhandled_keyboard_event_called_ = true;
357 bool HandleWheelEvent(const blink::WebMouseWheelEvent& event) override {
358 handle_wheel_event_called_ = true;
359 return handle_wheel_event_;
362 private:
363 bool prehandle_keyboard_event_;
364 bool prehandle_keyboard_event_called_;
365 WebInputEvent::Type prehandle_keyboard_event_type_;
367 bool unhandled_keyboard_event_called_;
368 WebInputEvent::Type unhandled_keyboard_event_type_;
370 bool handle_wheel_event_;
371 bool handle_wheel_event_called_;
374 // RenderWidgetHostTest --------------------------------------------------------
376 class RenderWidgetHostTest : public testing::Test {
377 public:
378 RenderWidgetHostTest()
379 : process_(NULL),
380 handle_key_press_event_(false),
381 handle_mouse_event_(false),
382 simulated_event_time_delta_seconds_(0) {
383 last_simulated_event_time_seconds_ =
384 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
386 ~RenderWidgetHostTest() override {}
388 bool KeyPressEventCallback(const NativeWebKeyboardEvent& /* event */) {
389 return handle_key_press_event_;
391 bool MouseEventCallback(const blink::WebMouseEvent& /* event */) {
392 return handle_mouse_event_;
395 protected:
396 // testing::Test
397 void SetUp() override {
398 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
399 command_line->AppendSwitch(switches::kValidateInputEventStream);
401 browser_context_.reset(new TestBrowserContext());
402 delegate_.reset(new MockRenderWidgetHostDelegate());
403 process_ = new RenderWidgetHostProcess(browser_context_.get());
404 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
405 if (IsDelegatedRendererEnabled()) {
406 ImageTransportFactory::InitializeForUnitTests(
407 scoped_ptr<ImageTransportFactory>(
408 new NoTransportImageTransportFactory));
410 #endif
411 #if defined(USE_AURA)
412 aura::Env::CreateInstance(true);
413 screen_.reset(aura::TestScreen::Create(gfx::Size()));
414 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
415 #endif
416 host_.reset(
417 new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
418 view_.reset(new TestView(host_.get()));
419 ConfigureView(view_.get());
420 host_->SetView(view_.get());
421 SetInitialRenderSizeParams();
422 host_->Init();
423 host_->DisableGestureDebounce();
426 void TearDown() override {
427 view_.reset();
428 host_.reset();
429 delegate_.reset();
430 process_ = NULL;
431 browser_context_.reset();
433 #if defined(USE_AURA)
434 aura::Env::DeleteInstance();
435 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, nullptr);
436 screen_.reset();
437 #endif
438 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
439 if (IsDelegatedRendererEnabled())
440 ImageTransportFactory::Terminate();
441 #endif
443 // Process all pending tasks to avoid leaks.
444 base::MessageLoop::current()->RunUntilIdle();
447 void SetInitialRenderSizeParams() {
448 ViewMsg_Resize_Params render_size_params;
449 host_->GetResizeParams(&render_size_params);
450 host_->SetInitialRenderSizeParams(render_size_params);
453 virtual void ConfigureView(TestView* view) {
456 int64 GetLatencyComponentId() {
457 return host_->GetLatencyComponentId();
460 void SendInputEventACK(WebInputEvent::Type type,
461 InputEventAckState ack_result) {
462 InputHostMsg_HandleInputEvent_ACK_Params ack;
463 ack.type = type;
464 ack.state = ack_result;
465 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
468 double GetNextSimulatedEventTimeSeconds() {
469 last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_;
470 return last_simulated_event_time_seconds_;
473 void SimulateKeyboardEvent(WebInputEvent::Type type) {
474 SimulateKeyboardEvent(type, 0);
477 void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) {
478 WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
479 event.modifiers = modifiers;
480 NativeWebKeyboardEvent native_event;
481 memcpy(&native_event, &event, sizeof(event));
482 host_->ForwardKeyboardEvent(native_event);
485 void SimulateMouseEvent(WebInputEvent::Type type) {
486 host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type));
489 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type,
490 const ui::LatencyInfo& ui_latency) {
491 host_->ForwardMouseEventWithLatencyInfo(
492 SyntheticWebMouseEventBuilder::Build(type),
493 ui_latency);
496 void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
497 host_->ForwardWheelEvent(
498 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
501 void SimulateWheelEventWithLatencyInfo(float dX,
502 float dY,
503 int modifiers,
504 bool precise,
505 const ui::LatencyInfo& ui_latency) {
506 host_->ForwardWheelEventWithLatencyInfo(
507 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
508 ui_latency);
511 void SimulateMouseMove(int x, int y, int modifiers) {
512 SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false);
515 void SimulateMouseEvent(
516 WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) {
517 WebMouseEvent event =
518 SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers);
519 if (pressed)
520 event.button = WebMouseEvent::ButtonLeft;
521 event.timeStampSeconds = GetNextSimulatedEventTimeSeconds();
522 host_->ForwardMouseEvent(event);
525 // Inject simple synthetic WebGestureEvent instances.
526 void SimulateGestureEvent(WebInputEvent::Type type,
527 WebGestureDevice sourceDevice) {
528 host_->ForwardGestureEvent(
529 SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
532 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type,
533 WebGestureDevice sourceDevice,
534 const ui::LatencyInfo& ui_latency) {
535 host_->ForwardGestureEventWithLatencyInfo(
536 SyntheticWebGestureEventBuilder::Build(type, sourceDevice),
537 ui_latency);
540 // Set the timestamp for the touch-event.
541 void SetTouchTimestamp(base::TimeDelta timestamp) {
542 touch_event_.SetTimestamp(timestamp);
545 // Sends a touch event (irrespective of whether the page has a touch-event
546 // handler or not).
547 void SendTouchEvent() {
548 host_->ForwardTouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo());
550 touch_event_.ResetPoints();
553 int PressTouchPoint(int x, int y) {
554 return touch_event_.PressPoint(x, y);
557 void MoveTouchPoint(int index, int x, int y) {
558 touch_event_.MovePoint(index, x, y);
561 void ReleaseTouchPoint(int index) {
562 touch_event_.ReleasePoint(index);
565 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
566 PickleIterator iter(message);
567 const char* data;
568 int data_length;
569 if (!iter.ReadData(&data, &data_length))
570 return NULL;
571 return reinterpret_cast<const WebInputEvent*>(data);
574 base::MessageLoopForUI message_loop_;
576 scoped_ptr<TestBrowserContext> browser_context_;
577 RenderWidgetHostProcess* process_; // Deleted automatically by the widget.
578 scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
579 scoped_ptr<MockRenderWidgetHost> host_;
580 scoped_ptr<TestView> view_;
581 scoped_ptr<gfx::Screen> screen_;
582 bool handle_key_press_event_;
583 bool handle_mouse_event_;
584 double last_simulated_event_time_seconds_;
585 double simulated_event_time_delta_seconds_;
587 private:
588 SyntheticWebTouchEvent touch_event_;
590 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest);
593 #if GTEST_HAS_PARAM_TEST
594 // RenderWidgetHostWithSourceTest ----------------------------------------------
596 // This is for tests that are to be run for all source devices.
597 class RenderWidgetHostWithSourceTest
598 : public RenderWidgetHostTest,
599 public testing::WithParamInterface<WebGestureDevice> {};
600 #endif // GTEST_HAS_PARAM_TEST
602 } // namespace
604 // -----------------------------------------------------------------------------
606 TEST_F(RenderWidgetHostTest, Resize) {
607 // The initial bounds is the empty rect, and the screen info hasn't been sent
608 // yet, so setting it to the same thing shouldn't send the resize message.
609 view_->set_bounds(gfx::Rect());
610 host_->WasResized();
611 EXPECT_FALSE(host_->resize_ack_pending_);
612 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
614 // No resize ack if the physical backing gets set, but the view bounds are
615 // zero.
616 view_->SetMockPhysicalBackingSize(gfx::Size(200, 200));
617 host_->WasResized();
618 EXPECT_FALSE(host_->resize_ack_pending_);
620 // Setting the view bounds to nonzero should send out the notification.
621 // but should not expect ack for empty physical backing size.
622 gfx::Rect original_size(0, 0, 100, 100);
623 process_->sink().ClearMessages();
624 view_->set_bounds(original_size);
625 view_->SetMockPhysicalBackingSize(gfx::Size());
626 host_->WasResized();
627 EXPECT_FALSE(host_->resize_ack_pending_);
628 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
629 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
631 // Setting the bounds and physical backing size to nonzero should send out
632 // the notification and expect an ack.
633 process_->sink().ClearMessages();
634 view_->ClearMockPhysicalBackingSize();
635 host_->WasResized();
636 EXPECT_TRUE(host_->resize_ack_pending_);
637 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
638 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
639 ViewHostMsg_UpdateRect_Params params;
640 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
641 params.view_size = original_size.size();
642 host_->OnUpdateRect(params);
643 EXPECT_FALSE(host_->resize_ack_pending_);
645 // Send out a update that's not a resize ack after setting resize ack pending
646 // flag. This should not clean the resize ack pending flag.
647 process_->sink().ClearMessages();
648 gfx::Rect second_size(0, 0, 110, 110);
649 EXPECT_FALSE(host_->resize_ack_pending_);
650 view_->set_bounds(second_size);
651 host_->WasResized();
652 EXPECT_TRUE(host_->resize_ack_pending_);
653 params.flags = 0;
654 params.view_size = gfx::Size(100, 100);
655 host_->OnUpdateRect(params);
656 EXPECT_TRUE(host_->resize_ack_pending_);
657 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
659 // Sending out a new notification should NOT send out a new IPC message since
660 // a resize ACK is pending.
661 gfx::Rect third_size(0, 0, 120, 120);
662 process_->sink().ClearMessages();
663 view_->set_bounds(third_size);
664 host_->WasResized();
665 EXPECT_TRUE(host_->resize_ack_pending_);
666 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
667 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
669 // Send a update that's a resize ack, but for the original_size we sent. Since
670 // this isn't the second_size, the message handler should immediately send
671 // a new resize message for the new size to the renderer.
672 process_->sink().ClearMessages();
673 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
674 params.view_size = original_size.size();
675 host_->OnUpdateRect(params);
676 EXPECT_TRUE(host_->resize_ack_pending_);
677 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
678 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
680 // Send the resize ack for the latest size.
681 process_->sink().ClearMessages();
682 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
683 params.view_size = third_size.size();
684 host_->OnUpdateRect(params);
685 EXPECT_FALSE(host_->resize_ack_pending_);
686 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
687 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
689 // Now clearing the bounds should send out a notification but we shouldn't
690 // expect a resize ack (since the renderer won't ack empty sizes). The message
691 // should contain the new size (0x0) and not the previous one that we skipped
692 process_->sink().ClearMessages();
693 view_->set_bounds(gfx::Rect());
694 host_->WasResized();
695 EXPECT_FALSE(host_->resize_ack_pending_);
696 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
697 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
699 // Send a rect that has no area but has either width or height set.
700 process_->sink().ClearMessages();
701 view_->set_bounds(gfx::Rect(0, 0, 0, 30));
702 host_->WasResized();
703 EXPECT_FALSE(host_->resize_ack_pending_);
704 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
705 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
707 // Set the same size again. It should not be sent again.
708 process_->sink().ClearMessages();
709 host_->WasResized();
710 EXPECT_FALSE(host_->resize_ack_pending_);
711 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
712 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
714 // A different size should be sent again, however.
715 view_->set_bounds(gfx::Rect(0, 0, 0, 31));
716 host_->WasResized();
717 EXPECT_FALSE(host_->resize_ack_pending_);
718 EXPECT_EQ(gfx::Size(0, 31), host_->old_resize_params_->new_size);
719 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
722 // Test for crbug.com/25097. If a renderer crashes between a resize and the
723 // corresponding update message, we must be sure to clear the resize ack logic.
724 TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
725 // Clear the first Resize message that carried screen info.
726 process_->sink().ClearMessages();
728 // Setting the bounds to a "real" rect should send out the notification.
729 gfx::Rect original_size(0, 0, 100, 100);
730 view_->set_bounds(original_size);
731 host_->WasResized();
732 EXPECT_TRUE(host_->resize_ack_pending_);
733 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
734 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
736 // Simulate a renderer crash before the update message. Ensure all the
737 // resize ack logic is cleared. Must clear the view first so it doesn't get
738 // deleted.
739 host_->SetView(NULL);
740 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
741 EXPECT_FALSE(host_->resize_ack_pending_);
742 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
744 // Reset the view so we can exit the test cleanly.
745 host_->SetView(view_.get());
748 // Unable to include render_widget_host_view_mac.h and compile.
749 #if !defined(OS_MACOSX)
750 // Tests setting background transparency.
751 TEST_F(RenderWidgetHostTest, Background) {
752 scoped_ptr<RenderWidgetHostViewBase> view;
753 #if defined(USE_AURA)
754 view.reset(new RenderWidgetHostViewAura(host_.get(), false));
755 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
756 view->InitAsChild(NULL);
757 #elif defined(OS_ANDROID)
758 view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
759 #endif
760 host_->SetView(view.get());
762 EXPECT_TRUE(view->GetBackgroundOpaque());
763 view->SetBackgroundColor(SK_ColorTRANSPARENT);
764 EXPECT_FALSE(view->GetBackgroundOpaque());
766 const IPC::Message* set_background =
767 process_->sink().GetUniqueMessageMatching(
768 ViewMsg_SetBackgroundOpaque::ID);
769 ASSERT_TRUE(set_background);
770 Tuple<bool> sent_background;
771 ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
772 EXPECT_FALSE(get<0>(sent_background));
774 #if defined(USE_AURA)
775 // See the comment above |InitAsChild(NULL)|.
776 host_->SetView(NULL);
777 static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
778 #endif
780 #endif
782 // Test that we don't paint when we're hidden, but we still send the ACK. Most
783 // of the rest of the painting is tested in the GetBackingStore* ones.
784 TEST_F(RenderWidgetHostTest, HiddenPaint) {
785 BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
786 // Hide the widget, it should have sent out a message to the renderer.
787 EXPECT_FALSE(host_->is_hidden_);
788 host_->WasHidden();
789 EXPECT_TRUE(host_->is_hidden_);
790 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID));
792 // Send it an update as from the renderer.
793 process_->sink().ClearMessages();
794 ViewHostMsg_UpdateRect_Params params;
795 params.view_size = gfx::Size(100, 100);
796 host_->OnUpdateRect(params);
798 // Now unhide.
799 process_->sink().ClearMessages();
800 host_->WasShown(ui::LatencyInfo());
801 EXPECT_FALSE(host_->is_hidden_);
803 // It should have sent out a restored message with a request to paint.
804 const IPC::Message* restored = process_->sink().GetUniqueMessageMatching(
805 ViewMsg_WasShown::ID);
806 ASSERT_TRUE(restored);
807 Tuple<bool, ui::LatencyInfo> needs_repaint;
808 ViewMsg_WasShown::Read(restored, &needs_repaint);
809 EXPECT_TRUE(get<0>(needs_repaint));
812 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
813 // Simulate a keyboard event.
814 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
816 // Make sure we sent the input event to the renderer.
817 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
818 InputMsg_HandleInputEvent::ID));
819 process_->sink().ClearMessages();
821 // Send the simulated response from the renderer back.
822 SendInputEventACK(WebInputEvent::RawKeyDown,
823 INPUT_EVENT_ACK_STATE_CONSUMED);
824 EXPECT_FALSE(delegate_->unhandled_keyboard_event_called());
827 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
828 // Simluate the situation that the browser handled the key down event during
829 // pre-handle phrase.
830 delegate_->set_prehandle_keyboard_event(true);
831 process_->sink().ClearMessages();
833 // Simulate a keyboard event.
834 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
836 EXPECT_TRUE(delegate_->prehandle_keyboard_event_called());
837 EXPECT_EQ(WebInputEvent::RawKeyDown,
838 delegate_->prehandle_keyboard_event_type());
840 // Make sure the RawKeyDown event is not sent to the renderer.
841 EXPECT_EQ(0U, process_->sink().message_count());
843 // The browser won't pre-handle a Char event.
844 delegate_->set_prehandle_keyboard_event(false);
846 // Forward the Char event.
847 SimulateKeyboardEvent(WebInputEvent::Char);
849 // Make sure the Char event is suppressed.
850 EXPECT_EQ(0U, process_->sink().message_count());
852 // Forward the KeyUp event.
853 SimulateKeyboardEvent(WebInputEvent::KeyUp);
855 // Make sure only KeyUp was sent to the renderer.
856 EXPECT_EQ(1U, process_->sink().message_count());
857 EXPECT_EQ(InputMsg_HandleInputEvent::ID,
858 process_->sink().GetMessageAt(0)->type());
859 process_->sink().ClearMessages();
861 // Send the simulated response from the renderer back.
862 SendInputEventACK(WebInputEvent::KeyUp,
863 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
865 EXPECT_TRUE(delegate_->unhandled_keyboard_event_called());
866 EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type());
869 TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
870 SimulateWheelEvent(-5, 0, 0, true);
872 // Make sure we sent the input event to the renderer.
873 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
874 InputMsg_HandleInputEvent::ID));
875 process_->sink().ClearMessages();
877 // Send the simulated response from the renderer back.
878 SendInputEventACK(WebInputEvent::MouseWheel,
879 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
880 EXPECT_TRUE(delegate_->handle_wheel_event_called());
881 EXPECT_EQ(1, view_->unhandled_wheel_event_count());
882 EXPECT_EQ(-5, view_->unhandled_wheel_event().deltaX);
885 TEST_F(RenderWidgetHostTest, HandleWheelEvent) {
886 // Indicate that we're going to handle this wheel event
887 delegate_->set_handle_wheel_event(true);
889 SimulateWheelEvent(-5, 0, 0, true);
891 // Make sure we sent the input event to the renderer.
892 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
893 InputMsg_HandleInputEvent::ID));
894 process_->sink().ClearMessages();
896 // Send the simulated response from the renderer back.
897 SendInputEventACK(WebInputEvent::MouseWheel,
898 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
900 // ensure the wheel event handler was invoked
901 EXPECT_TRUE(delegate_->handle_wheel_event_called());
903 // and that it suppressed the unhandled wheel event handler.
904 EXPECT_EQ(0, view_->unhandled_wheel_event_count());
907 TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
908 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap,
909 blink::WebGestureDeviceTouchscreen);
911 // Make sure we sent the input event to the renderer.
912 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
913 InputMsg_HandleInputEvent::ID));
914 process_->sink().ClearMessages();
916 // Send the simulated response from the renderer back.
917 SendInputEventACK(WebInputEvent::GestureTwoFingerTap,
918 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
919 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap, view_->gesture_event_type());
920 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, view_->ack_result());
923 // Test that the hang monitor timer expires properly if a new timer is started
924 // while one is in progress (see crbug.com/11007).
925 TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) {
926 // Start with a short timeout.
927 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
929 // Immediately try to add a long 30 second timeout.
930 EXPECT_FALSE(host_->unresponsive_timer_fired());
931 host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
933 // Wait long enough for first timeout and see if it fired.
934 base::MessageLoop::current()->PostDelayedTask(
935 FROM_HERE,
936 base::MessageLoop::QuitClosure(),
937 TimeDelta::FromMilliseconds(10));
938 base::MessageLoop::current()->Run();
939 EXPECT_TRUE(host_->unresponsive_timer_fired());
942 // Test that the hang monitor timer expires properly if it is started, stopped,
943 // and then started again.
944 TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
945 // Start with a short timeout, then stop it.
946 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
947 host_->StopHangMonitorTimeout();
949 // Start it again to ensure it still works.
950 EXPECT_FALSE(host_->unresponsive_timer_fired());
951 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
953 // Wait long enough for first timeout and see if it fired.
954 base::MessageLoop::current()->PostDelayedTask(
955 FROM_HERE,
956 base::MessageLoop::QuitClosure(),
957 TimeDelta::FromMilliseconds(40));
958 base::MessageLoop::current()->Run();
959 EXPECT_TRUE(host_->unresponsive_timer_fired());
962 // Test that the hang monitor timer expires properly if it is started, then
963 // updated to a shorter duration.
964 TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) {
965 // Start with a timeout.
966 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
968 // Start it again with shorter delay.
969 EXPECT_FALSE(host_->unresponsive_timer_fired());
970 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
972 // Wait long enough for the second timeout and see if it fired.
973 base::MessageLoop::current()->PostDelayedTask(
974 FROM_HERE,
975 base::MessageLoop::QuitClosure(),
976 TimeDelta::FromMilliseconds(25));
977 base::MessageLoop::current()->Run();
978 EXPECT_TRUE(host_->unresponsive_timer_fired());
981 // Test that the hang monitor timer is effectively disabled when the widget is
982 // hidden.
983 TEST_F(RenderWidgetHostTest, HangMonitorTimeoutDisabledForInputWhenHidden) {
984 host_->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(1));
985 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
987 // Hiding the widget should deactivate the timeout.
988 host_->WasHidden();
990 // The timeout should not fire.
991 EXPECT_FALSE(host_->unresponsive_timer_fired());
992 base::MessageLoop::current()->PostDelayedTask(
993 FROM_HERE,
994 base::MessageLoop::QuitClosure(),
995 TimeDelta::FromMicroseconds(2));
996 base::MessageLoop::current()->Run();
997 EXPECT_FALSE(host_->unresponsive_timer_fired());
999 // The timeout should never reactivate while hidden.
1000 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1001 base::MessageLoop::current()->PostDelayedTask(
1002 FROM_HERE,
1003 base::MessageLoop::QuitClosure(),
1004 TimeDelta::FromMicroseconds(2));
1005 base::MessageLoop::current()->Run();
1006 EXPECT_FALSE(host_->unresponsive_timer_fired());
1008 // Showing the widget should restore the timeout, as the events have
1009 // not yet been ack'ed.
1010 host_->WasShown(ui::LatencyInfo());
1011 base::MessageLoop::current()->PostDelayedTask(
1012 FROM_HERE,
1013 base::MessageLoop::QuitClosure(),
1014 TimeDelta::FromMicroseconds(2));
1015 base::MessageLoop::current()->Run();
1016 EXPECT_TRUE(host_->unresponsive_timer_fired());
1019 // Test that the hang monitor catches two input events but only one ack.
1020 // This can happen if the second input event causes the renderer to hang.
1021 // This test will catch a regression of crbug.com/111185.
1022 TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
1023 // Configure the host to wait 10ms before considering
1024 // the renderer hung.
1025 host_->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(10));
1027 // Send two events but only one ack.
1028 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1029 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1030 SendInputEventACK(WebInputEvent::RawKeyDown,
1031 INPUT_EVENT_ACK_STATE_CONSUMED);
1033 // Wait long enough for first timeout and see if it fired.
1034 base::MessageLoop::current()->PostDelayedTask(
1035 FROM_HERE,
1036 base::MessageLoop::QuitClosure(),
1037 TimeDelta::FromMicroseconds(20));
1038 base::MessageLoop::current()->Run();
1039 EXPECT_TRUE(host_->unresponsive_timer_fired());
1042 std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
1043 std::string result;
1044 for (size_t i = 0; i < process->sink().message_count(); ++i) {
1045 const IPC::Message *message = process->sink().GetMessageAt(i);
1046 EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
1047 InputMsg_HandleInputEvent::Param params;
1048 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1049 const WebInputEvent* event = get<0>(params);
1050 if (i != 0)
1051 result += " ";
1052 result += WebInputEventTraits::GetName(event->type);
1054 process->sink().ClearMessages();
1055 return result;
1058 TEST_F(RenderWidgetHostTest, TouchEmulator) {
1059 simulated_event_time_delta_seconds_ = 0.1;
1060 // Immediately ack all touches instead of sending them to the renderer.
1061 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1062 host_->SetTouchEventEmulationEnabled(
1063 true, ui::GestureProviderConfigType::GENERIC_MOBILE);
1064 process_->sink().ClearMessages();
1065 view_->set_bounds(gfx::Rect(0, 0, 400, 200));
1066 view_->Show();
1068 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1069 EXPECT_EQ(0U, process_->sink().message_count());
1071 // Mouse press becomes touch start which in turn becomes tap.
1072 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1073 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1074 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1076 // Mouse drag generates touch move, cancels tap and starts scroll.
1077 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1078 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1079 EXPECT_EQ(
1080 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1081 GetInputMessageTypes(process_));
1082 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1083 INPUT_EVENT_ACK_STATE_CONSUMED);
1084 EXPECT_EQ(0U, process_->sink().message_count());
1086 // Mouse drag with shift becomes pinch.
1087 SimulateMouseEvent(
1088 WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true);
1089 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1090 EXPECT_EQ("GesturePinchBegin",
1091 GetInputMessageTypes(process_));
1092 EXPECT_EQ(0U, process_->sink().message_count());
1094 SimulateMouseEvent(
1095 WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true);
1096 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1097 EXPECT_EQ("GesturePinchUpdate",
1098 GetInputMessageTypes(process_));
1099 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1100 INPUT_EVENT_ACK_STATE_CONSUMED);
1101 EXPECT_EQ(0U, process_->sink().message_count());
1103 // Mouse drag without shift becomes scroll again.
1104 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true);
1105 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1106 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1107 GetInputMessageTypes(process_));
1108 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1109 INPUT_EVENT_ACK_STATE_CONSUMED);
1110 EXPECT_EQ(0U, process_->sink().message_count());
1112 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true);
1113 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1114 EXPECT_EQ("GestureScrollUpdate",
1115 GetInputMessageTypes(process_));
1116 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1117 INPUT_EVENT_ACK_STATE_CONSUMED);
1118 EXPECT_EQ(0U, process_->sink().message_count());
1120 SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true);
1121 EXPECT_EQ(WebInputEvent::TouchEnd, host_->acked_touch_event_type());
1122 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1123 EXPECT_EQ(0U, process_->sink().message_count());
1125 // Mouse move does nothing.
1126 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false);
1127 EXPECT_EQ(0U, process_->sink().message_count());
1129 // Another mouse down continues scroll.
1130 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true);
1131 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1132 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1133 EXPECT_EQ(0U, process_->sink().message_count());
1135 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true);
1136 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1137 EXPECT_EQ(
1138 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1139 GetInputMessageTypes(process_));
1140 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1141 INPUT_EVENT_ACK_STATE_CONSUMED);
1142 EXPECT_EQ(0U, process_->sink().message_count());
1144 // Another pinch.
1145 SimulateMouseEvent(
1146 WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true);
1147 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1148 EXPECT_EQ("GesturePinchBegin",
1149 GetInputMessageTypes(process_));
1150 EXPECT_EQ(0U, process_->sink().message_count());
1152 SimulateMouseEvent(
1153 WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true);
1154 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1155 EXPECT_EQ("GesturePinchUpdate",
1156 GetInputMessageTypes(process_));
1157 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1158 INPUT_EVENT_ACK_STATE_CONSUMED);
1159 EXPECT_EQ(0U, process_->sink().message_count());
1161 // Turn off emulation during a pinch.
1162 host_->SetTouchEventEmulationEnabled(
1163 false, ui::GestureProviderConfigType::GENERIC_MOBILE);
1164 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1165 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1166 GetInputMessageTypes(process_));
1167 EXPECT_EQ(0U, process_->sink().message_count());
1169 // Mouse event should pass untouched.
1170 SimulateMouseEvent(
1171 WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true);
1172 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_));
1173 SendInputEventACK(WebInputEvent::MouseMove,
1174 INPUT_EVENT_ACK_STATE_CONSUMED);
1175 EXPECT_EQ(0U, process_->sink().message_count());
1177 // Turn on emulation.
1178 host_->SetTouchEventEmulationEnabled(
1179 true, ui::GestureProviderConfigType::GENERIC_MOBILE);
1180 EXPECT_EQ(0U, process_->sink().message_count());
1182 // Another touch.
1183 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1184 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1185 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1186 EXPECT_EQ(0U, process_->sink().message_count());
1188 // Scroll.
1189 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1190 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1191 EXPECT_EQ(
1192 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1193 GetInputMessageTypes(process_));
1194 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1195 INPUT_EVENT_ACK_STATE_CONSUMED);
1197 // Turn off emulation during a scroll.
1198 host_->SetTouchEventEmulationEnabled(
1199 false, ui::GestureProviderConfigType::GENERIC_MOBILE);
1200 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1202 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1203 EXPECT_EQ(0U, process_->sink().message_count());
1206 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1207 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1208 host_->SetupForInputRouterTest(); \
1209 host_->INPUTMSG(); \
1210 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1213 TEST_InputRouterRoutes_NOARGS(Focus);
1214 TEST_InputRouterRoutes_NOARGS(Blur);
1215 TEST_InputRouterRoutes_NOARGS(LostCapture);
1217 #undef TEST_InputRouterRoutes_NOARGS
1219 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1220 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1221 host_->SetupForInputRouterTest(); \
1222 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1223 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1226 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo);
1227 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo);
1228 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut);
1229 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy);
1230 #if defined(OS_MACOSX)
1231 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard);
1232 #endif
1233 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste);
1234 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle);
1235 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete);
1236 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll);
1237 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect);
1239 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1241 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplace) {
1242 host_->SetupForInputRouterTest();
1243 host_->Send(new InputMsg_Replace(host_->GetRoutingID(), base::string16()));
1244 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1247 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplaceMisspelling) {
1248 host_->SetupForInputRouterTest();
1249 host_->Send(new InputMsg_ReplaceMisspelling(host_->GetRoutingID(),
1250 base::string16()));
1251 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1254 TEST_F(RenderWidgetHostTest, IgnoreInputEvent) {
1255 host_->SetupForInputRouterTest();
1257 host_->SetIgnoreInputEvents(true);
1259 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1260 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1262 SimulateMouseEvent(WebInputEvent::MouseMove);
1263 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1265 SimulateWheelEvent(0, 100, 0, true);
1266 EXPECT_FALSE(host_->mock_input_router()->sent_wheel_event_);
1268 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1269 blink::WebGestureDeviceTouchpad);
1270 EXPECT_FALSE(host_->mock_input_router()->sent_gesture_event_);
1272 PressTouchPoint(100, 100);
1273 SendTouchEvent();
1274 EXPECT_FALSE(host_->mock_input_router()->send_touch_event_not_cancelled_);
1277 TEST_F(RenderWidgetHostTest, KeyboardListenerIgnoresEvent) {
1278 host_->SetupForInputRouterTest();
1279 host_->AddKeyPressEventCallback(
1280 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1281 base::Unretained(this)));
1282 handle_key_press_event_ = false;
1283 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1285 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1288 TEST_F(RenderWidgetHostTest, KeyboardListenerSuppressFollowingEvents) {
1289 host_->SetupForInputRouterTest();
1291 host_->AddKeyPressEventCallback(
1292 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1293 base::Unretained(this)));
1295 // The callback handles the first event
1296 handle_key_press_event_ = true;
1297 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1299 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1301 // Following Char events should be suppressed
1302 handle_key_press_event_ = false;
1303 SimulateKeyboardEvent(WebInputEvent::Char);
1304 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1305 SimulateKeyboardEvent(WebInputEvent::Char);
1306 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1308 // Sending RawKeyDown event should stop suppression
1309 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1310 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1312 host_->mock_input_router()->sent_keyboard_event_ = false;
1313 SimulateKeyboardEvent(WebInputEvent::Char);
1314 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1317 TEST_F(RenderWidgetHostTest, MouseEventCallbackCanHandleEvent) {
1318 host_->SetupForInputRouterTest();
1320 host_->AddMouseEventCallback(
1321 base::Bind(&RenderWidgetHostTest::MouseEventCallback,
1322 base::Unretained(this)));
1324 handle_mouse_event_ = true;
1325 SimulateMouseEvent(WebInputEvent::MouseDown);
1327 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1329 handle_mouse_event_ = false;
1330 SimulateMouseEvent(WebInputEvent::MouseDown);
1332 EXPECT_TRUE(host_->mock_input_router()->sent_mouse_event_);
1335 TEST_F(RenderWidgetHostTest, InputRouterReceivesHandleInputEvent_ACK) {
1336 host_->SetupForInputRouterTest();
1338 SendInputEventACK(WebInputEvent::RawKeyDown,
1339 INPUT_EVENT_ACK_STATE_CONSUMED);
1341 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1344 TEST_F(RenderWidgetHostTest, InputRouterReceivesMoveCaret_ACK) {
1345 host_->SetupForInputRouterTest();
1347 host_->OnMessageReceived(InputHostMsg_MoveCaret_ACK(0));
1349 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1352 TEST_F(RenderWidgetHostTest, InputRouterReceivesSelectRange_ACK) {
1353 host_->SetupForInputRouterTest();
1355 host_->OnMessageReceived(InputHostMsg_SelectRange_ACK(0));
1357 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1360 TEST_F(RenderWidgetHostTest, InputRouterReceivesHasTouchEventHandlers) {
1361 host_->SetupForInputRouterTest();
1363 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1365 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1368 ui::LatencyInfo GetLatencyInfoFromInputEvent(RenderWidgetHostProcess* process) {
1369 const IPC::Message* message = process->sink().GetUniqueMessageMatching(
1370 InputMsg_HandleInputEvent::ID);
1371 EXPECT_TRUE(message);
1372 InputMsg_HandleInputEvent::Param params;
1373 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1374 process->sink().ClearMessages();
1375 return get<1>(params);
1378 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process,
1379 int64 component_id,
1380 WebInputEvent::Type input_type) {
1381 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process);
1382 EXPECT_TRUE(latency_info.FindLatency(
1383 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
1384 component_id,
1385 NULL));
1388 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1389 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1390 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1391 // event's LatencyInfo.
1392 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
1393 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1394 process_->sink().ClearMessages();
1396 // Tests RWHI::ForwardWheelEvent().
1397 SimulateWheelEvent(-5, 0, 0, true);
1398 CheckLatencyInfoComponentInMessage(
1399 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1400 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1402 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1403 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1404 CheckLatencyInfoComponentInMessage(
1405 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1406 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1408 // Tests RWHI::ForwardMouseEvent().
1409 SimulateMouseEvent(WebInputEvent::MouseMove);
1410 CheckLatencyInfoComponentInMessage(
1411 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1412 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1414 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1415 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove,
1416 ui::LatencyInfo());
1417 CheckLatencyInfoComponentInMessage(
1418 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1419 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1421 // Tests RWHI::ForwardGestureEvent().
1422 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1423 blink::WebGestureDeviceTouchscreen);
1424 CheckLatencyInfoComponentInMessage(
1425 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin);
1427 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1428 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate,
1429 blink::WebGestureDeviceTouchscreen,
1430 ui::LatencyInfo());
1431 CheckLatencyInfoComponentInMessage(
1432 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate);
1433 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1434 INPUT_EVENT_ACK_STATE_CONSUMED);
1436 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1437 PressTouchPoint(0, 1);
1438 SendTouchEvent();
1439 CheckLatencyInfoComponentInMessage(
1440 process_, GetLatencyComponentId(), WebInputEvent::TouchStart);
1441 SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
1444 TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) {
1445 // RendererExited will delete the view.
1446 host_->SetView(new TestView(host_.get()));
1447 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1449 // Make sure the input router is in a fresh state.
1450 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1453 // Regression test for http://crbug.com/401859.
1454 TEST_F(RenderWidgetHostTest, RendererExitedResetsIsHidden) {
1455 // RendererExited will delete the view.
1456 host_->SetView(new TestView(host_.get()));
1457 host_->WasHidden();
1459 ASSERT_TRUE(host_->is_hidden());
1460 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1461 ASSERT_FALSE(host_->is_hidden());
1463 // Make sure the input router is in a fresh state.
1464 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1467 TEST_F(RenderWidgetHostTest, ResizeParams) {
1468 gfx::Rect bounds(0, 0, 100, 100);
1469 gfx::Size physical_backing_size(40, 50);
1470 view_->set_bounds(bounds);
1471 view_->SetMockPhysicalBackingSize(physical_backing_size);
1473 ViewMsg_Resize_Params resize_params;
1474 host_->GetResizeParams(&resize_params);
1475 EXPECT_EQ(bounds.size(), resize_params.new_size);
1476 EXPECT_EQ(physical_backing_size, resize_params.physical_backing_size);
1479 class RenderWidgetHostInitialSizeTest : public RenderWidgetHostTest {
1480 public:
1481 RenderWidgetHostInitialSizeTest()
1482 : RenderWidgetHostTest(), initial_size_(200, 100) {}
1484 void ConfigureView(TestView* view) override {
1485 view->set_bounds(gfx::Rect(initial_size_));
1488 protected:
1489 gfx::Size initial_size_;
1492 TEST_F(RenderWidgetHostInitialSizeTest, InitialSize) {
1493 // Having an initial size set means that the size information had been sent
1494 // with the reqiest to new up the RenderView and so subsequent WasResized
1495 // calls should not result in new IPC (unless the size has actually changed).
1496 host_->WasResized();
1497 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
1498 EXPECT_EQ(initial_size_, host_->old_resize_params_->new_size);
1499 EXPECT_TRUE(host_->resize_ack_pending_);
1502 } // namespace content