ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_unittest.cc
blob74b40f07c8b5a75b826a813702f164770ba43503
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 void Flush() override { flush_called_ = true; }
74 bool SendInput(scoped_ptr<IPC::Message> message) override {
75 send_event_called_ = true;
76 return true;
78 void SendMouseEvent(const MouseEventWithLatencyInfo& mouse_event) override {
79 sent_mouse_event_ = true;
81 void SendWheelEvent(
82 const MouseWheelEventWithLatencyInfo& wheel_event) override {
83 sent_wheel_event_ = true;
85 void SendKeyboardEvent(const NativeWebKeyboardEvent& key_event,
86 const ui::LatencyInfo& latency_info,
87 bool is_shortcut) override {
88 sent_keyboard_event_ = true;
90 void SendGestureEvent(
91 const GestureEventWithLatencyInfo& gesture_event) override {
92 sent_gesture_event_ = true;
94 void SendTouchEvent(const TouchEventWithLatencyInfo& touch_event) override {
95 send_touch_event_not_cancelled_ =
96 client_->FilterInputEvent(touch_event.event, touch_event.latency) ==
97 INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
99 const NativeWebKeyboardEvent* GetLastKeyboardEvent() const override {
100 NOTREACHED();
101 return NULL;
103 void OnViewUpdated(int view_flags) 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 flush_called_;
113 bool send_event_called_;
114 bool sent_mouse_event_;
115 bool sent_wheel_event_;
116 bool sent_keyboard_event_;
117 bool sent_gesture_event_;
118 bool send_touch_event_not_cancelled_;
119 bool message_received_;
121 private:
122 InputRouterClient* client_;
124 DISALLOW_COPY_AND_ASSIGN(MockInputRouter);
127 // MockRenderWidgetHost ----------------------------------------------------
129 class MockRenderWidgetHost : public RenderWidgetHostImpl {
130 public:
131 MockRenderWidgetHost(
132 RenderWidgetHostDelegate* delegate,
133 RenderProcessHost* process,
134 int routing_id)
135 : RenderWidgetHostImpl(delegate, process, routing_id, false),
136 unresponsive_timer_fired_(false) {
137 acked_touch_event_type_ = blink::WebInputEvent::Undefined;
140 // Allow poking at a few private members.
141 using RenderWidgetHostImpl::GetResizeParams;
142 using RenderWidgetHostImpl::OnUpdateRect;
143 using RenderWidgetHostImpl::RendererExited;
144 using RenderWidgetHostImpl::SetInitialRenderSizeParams;
145 using RenderWidgetHostImpl::old_resize_params_;
146 using RenderWidgetHostImpl::is_hidden_;
147 using RenderWidgetHostImpl::resize_ack_pending_;
148 using RenderWidgetHostImpl::input_router_;
150 void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
151 InputEventAckState ack_result) override {
152 // Sniff touch acks.
153 acked_touch_event_type_ = event.event.type;
154 RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
157 bool unresponsive_timer_fired() const {
158 return unresponsive_timer_fired_;
161 void set_hung_renderer_delay_ms(int64 delay_ms) {
162 hung_renderer_delay_ms_ = delay_ms;
165 void DisableGestureDebounce() {
166 input_router_.reset(new InputRouterImpl(
167 process_, this, this, routing_id_, InputRouterImpl::Config()));
170 WebInputEvent::Type acked_touch_event_type() const {
171 return acked_touch_event_type_;
174 void SetupForInputRouterTest() {
175 input_router_.reset(new MockInputRouter(this));
178 MockInputRouter* mock_input_router() {
179 return static_cast<MockInputRouter*>(input_router_.get());
182 protected:
183 void NotifyRendererUnresponsive() override {
184 unresponsive_timer_fired_ = true;
187 bool unresponsive_timer_fired_;
188 WebInputEvent::Type acked_touch_event_type_;
190 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
193 namespace {
195 // RenderWidgetHostProcess -----------------------------------------------------
197 class RenderWidgetHostProcess : public MockRenderProcessHost {
198 public:
199 explicit RenderWidgetHostProcess(BrowserContext* browser_context)
200 : MockRenderProcessHost(browser_context) {
202 ~RenderWidgetHostProcess() override {}
204 bool HasConnection() const override { return true; }
206 protected:
207 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess);
210 // TestView --------------------------------------------------------------------
212 // This test view allows us to specify the size, and keep track of acked
213 // touch-events.
214 class TestView : public TestRenderWidgetHostView {
215 public:
216 explicit TestView(RenderWidgetHostImpl* rwh)
217 : TestRenderWidgetHostView(rwh),
218 unhandled_wheel_event_count_(0),
219 acked_event_count_(0),
220 gesture_event_type_(-1),
221 use_fake_physical_backing_size_(false),
222 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
225 // Sets the bounds returned by GetViewBounds.
226 void set_bounds(const gfx::Rect& bounds) {
227 bounds_ = bounds;
230 const WebTouchEvent& acked_event() const { return acked_event_; }
231 int acked_event_count() const { return acked_event_count_; }
232 void ClearAckedEvent() {
233 acked_event_.type = blink::WebInputEvent::Undefined;
234 acked_event_count_ = 0;
237 const WebMouseWheelEvent& unhandled_wheel_event() const {
238 return unhandled_wheel_event_;
240 int unhandled_wheel_event_count() const {
241 return unhandled_wheel_event_count_;
243 int gesture_event_type() const { return gesture_event_type_; }
244 InputEventAckState ack_result() const { return ack_result_; }
246 void SetMockPhysicalBackingSize(const gfx::Size& mock_physical_backing_size) {
247 use_fake_physical_backing_size_ = true;
248 mock_physical_backing_size_ = mock_physical_backing_size;
250 void ClearMockPhysicalBackingSize() {
251 use_fake_physical_backing_size_ = false;
254 // RenderWidgetHostView override.
255 gfx::Rect GetViewBounds() const override { return bounds_; }
256 void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
257 InputEventAckState ack_result) override {
258 acked_event_ = touch.event;
259 ++acked_event_count_;
261 void WheelEventAck(const WebMouseWheelEvent& event,
262 InputEventAckState ack_result) override {
263 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
264 return;
265 unhandled_wheel_event_count_++;
266 unhandled_wheel_event_ = event;
268 void GestureEventAck(const WebGestureEvent& event,
269 InputEventAckState ack_result) override {
270 gesture_event_type_ = event.type;
271 ack_result_ = ack_result;
273 gfx::Size GetPhysicalBackingSize() const override {
274 if (use_fake_physical_backing_size_)
275 return mock_physical_backing_size_;
276 return TestRenderWidgetHostView::GetPhysicalBackingSize();
278 #if defined(USE_AURA)
279 ~TestView() override {
280 // Simulate the mouse exit event dispatched when an aura window is
281 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
282 // into WebInputEvent::MouseMove.)
283 rwh_->input_router()->SendMouseEvent(
284 MouseEventWithLatencyInfo(
285 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove),
286 ui::LatencyInfo()));
288 #endif
290 protected:
291 WebMouseWheelEvent unhandled_wheel_event_;
292 int unhandled_wheel_event_count_;
293 WebTouchEvent acked_event_;
294 int acked_event_count_;
295 int gesture_event_type_;
296 gfx::Rect bounds_;
297 bool use_fake_physical_backing_size_;
298 gfx::Size mock_physical_backing_size_;
299 InputEventAckState ack_result_;
301 DISALLOW_COPY_AND_ASSIGN(TestView);
304 // MockRenderWidgetHostDelegate --------------------------------------------
306 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
307 public:
308 MockRenderWidgetHostDelegate()
309 : prehandle_keyboard_event_(false),
310 prehandle_keyboard_event_called_(false),
311 prehandle_keyboard_event_type_(WebInputEvent::Undefined),
312 unhandled_keyboard_event_called_(false),
313 unhandled_keyboard_event_type_(WebInputEvent::Undefined),
314 handle_wheel_event_(false),
315 handle_wheel_event_called_(false) {
317 ~MockRenderWidgetHostDelegate() override {}
319 // Tests that make sure we ignore keyboard event acknowledgments to events we
320 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
321 bool unhandled_keyboard_event_called() const {
322 return unhandled_keyboard_event_called_;
325 WebInputEvent::Type unhandled_keyboard_event_type() const {
326 return unhandled_keyboard_event_type_;
329 bool prehandle_keyboard_event_called() const {
330 return prehandle_keyboard_event_called_;
333 WebInputEvent::Type prehandle_keyboard_event_type() const {
334 return prehandle_keyboard_event_type_;
337 void set_prehandle_keyboard_event(bool handle) {
338 prehandle_keyboard_event_ = handle;
341 void set_handle_wheel_event(bool handle) {
342 handle_wheel_event_ = handle;
345 bool handle_wheel_event_called() {
346 return handle_wheel_event_called_;
349 protected:
350 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
351 bool* is_keyboard_shortcut) override {
352 prehandle_keyboard_event_type_ = event.type;
353 prehandle_keyboard_event_called_ = true;
354 return prehandle_keyboard_event_;
357 void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override {
358 unhandled_keyboard_event_type_ = event.type;
359 unhandled_keyboard_event_called_ = true;
362 bool HandleWheelEvent(const blink::WebMouseWheelEvent& event) override {
363 handle_wheel_event_called_ = true;
364 return handle_wheel_event_;
367 private:
368 bool prehandle_keyboard_event_;
369 bool prehandle_keyboard_event_called_;
370 WebInputEvent::Type prehandle_keyboard_event_type_;
372 bool unhandled_keyboard_event_called_;
373 WebInputEvent::Type unhandled_keyboard_event_type_;
375 bool handle_wheel_event_;
376 bool handle_wheel_event_called_;
379 // RenderWidgetHostTest --------------------------------------------------------
381 class RenderWidgetHostTest : public testing::Test {
382 public:
383 RenderWidgetHostTest()
384 : process_(NULL),
385 handle_key_press_event_(false),
386 handle_mouse_event_(false),
387 simulated_event_time_delta_seconds_(0) {
388 last_simulated_event_time_seconds_ =
389 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
391 ~RenderWidgetHostTest() override {}
393 bool KeyPressEventCallback(const NativeWebKeyboardEvent& /* event */) {
394 return handle_key_press_event_;
396 bool MouseEventCallback(const blink::WebMouseEvent& /* event */) {
397 return handle_mouse_event_;
400 protected:
401 // testing::Test
402 void SetUp() override {
403 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
404 command_line->AppendSwitch(switches::kValidateInputEventStream);
406 browser_context_.reset(new TestBrowserContext());
407 delegate_.reset(new MockRenderWidgetHostDelegate());
408 process_ = new RenderWidgetHostProcess(browser_context_.get());
409 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
410 if (IsDelegatedRendererEnabled()) {
411 ImageTransportFactory::InitializeForUnitTests(
412 scoped_ptr<ImageTransportFactory>(
413 new NoTransportImageTransportFactory));
415 #endif
416 #if defined(USE_AURA)
417 aura::Env::CreateInstance(true);
418 screen_.reset(aura::TestScreen::Create(gfx::Size()));
419 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
420 #endif
421 host_.reset(
422 new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
423 view_.reset(new TestView(host_.get()));
424 ConfigureView(view_.get());
425 host_->SetView(view_.get());
426 SetInitialRenderSizeParams();
427 host_->Init();
428 host_->DisableGestureDebounce();
431 void TearDown() override {
432 view_.reset();
433 host_.reset();
434 delegate_.reset();
435 process_ = NULL;
436 browser_context_.reset();
438 #if defined(USE_AURA)
439 aura::Env::DeleteInstance();
440 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, nullptr);
441 screen_.reset();
442 #endif
443 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
444 if (IsDelegatedRendererEnabled())
445 ImageTransportFactory::Terminate();
446 #endif
448 // Process all pending tasks to avoid leaks.
449 base::MessageLoop::current()->RunUntilIdle();
452 void SetInitialRenderSizeParams() {
453 ViewMsg_Resize_Params render_size_params;
454 host_->GetResizeParams(&render_size_params);
455 host_->SetInitialRenderSizeParams(render_size_params);
458 virtual void ConfigureView(TestView* view) {
461 int64 GetLatencyComponentId() {
462 return host_->GetLatencyComponentId();
465 void SendInputEventACK(WebInputEvent::Type type,
466 InputEventAckState ack_result) {
467 InputHostMsg_HandleInputEvent_ACK_Params ack;
468 ack.type = type;
469 ack.state = ack_result;
470 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
473 double GetNextSimulatedEventTimeSeconds() {
474 last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_;
475 return last_simulated_event_time_seconds_;
478 void SimulateKeyboardEvent(WebInputEvent::Type type) {
479 SimulateKeyboardEvent(type, 0);
482 void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) {
483 WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
484 event.modifiers = modifiers;
485 NativeWebKeyboardEvent native_event;
486 memcpy(&native_event, &event, sizeof(event));
487 host_->ForwardKeyboardEvent(native_event);
490 void SimulateMouseEvent(WebInputEvent::Type type) {
491 host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type));
494 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type,
495 const ui::LatencyInfo& ui_latency) {
496 host_->ForwardMouseEventWithLatencyInfo(
497 SyntheticWebMouseEventBuilder::Build(type),
498 ui_latency);
501 void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
502 host_->ForwardWheelEvent(
503 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
506 void SimulateWheelEventWithLatencyInfo(float dX,
507 float dY,
508 int modifiers,
509 bool precise,
510 const ui::LatencyInfo& ui_latency) {
511 host_->ForwardWheelEventWithLatencyInfo(
512 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
513 ui_latency);
516 void SimulateMouseMove(int x, int y, int modifiers) {
517 SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false);
520 void SimulateMouseEvent(
521 WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) {
522 WebMouseEvent event =
523 SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers);
524 if (pressed)
525 event.button = WebMouseEvent::ButtonLeft;
526 event.timeStampSeconds = GetNextSimulatedEventTimeSeconds();
527 host_->ForwardMouseEvent(event);
530 // Inject simple synthetic WebGestureEvent instances.
531 void SimulateGestureEvent(WebInputEvent::Type type,
532 WebGestureDevice sourceDevice) {
533 host_->ForwardGestureEvent(
534 SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
537 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type,
538 WebGestureDevice sourceDevice,
539 const ui::LatencyInfo& ui_latency) {
540 host_->ForwardGestureEventWithLatencyInfo(
541 SyntheticWebGestureEventBuilder::Build(type, sourceDevice),
542 ui_latency);
545 // Set the timestamp for the touch-event.
546 void SetTouchTimestamp(base::TimeDelta timestamp) {
547 touch_event_.SetTimestamp(timestamp);
550 // Sends a touch event (irrespective of whether the page has a touch-event
551 // handler or not).
552 void SendTouchEvent() {
553 host_->ForwardTouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo());
555 touch_event_.ResetPoints();
558 int PressTouchPoint(int x, int y) {
559 return touch_event_.PressPoint(x, y);
562 void MoveTouchPoint(int index, int x, int y) {
563 touch_event_.MovePoint(index, x, y);
566 void ReleaseTouchPoint(int index) {
567 touch_event_.ReleasePoint(index);
570 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
571 PickleIterator iter(message);
572 const char* data;
573 int data_length;
574 if (!iter.ReadData(&data, &data_length))
575 return NULL;
576 return reinterpret_cast<const WebInputEvent*>(data);
579 base::MessageLoopForUI message_loop_;
581 scoped_ptr<TestBrowserContext> browser_context_;
582 RenderWidgetHostProcess* process_; // Deleted automatically by the widget.
583 scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
584 scoped_ptr<MockRenderWidgetHost> host_;
585 scoped_ptr<TestView> view_;
586 scoped_ptr<gfx::Screen> screen_;
587 bool handle_key_press_event_;
588 bool handle_mouse_event_;
589 double last_simulated_event_time_seconds_;
590 double simulated_event_time_delta_seconds_;
592 private:
593 SyntheticWebTouchEvent touch_event_;
595 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest);
598 #if GTEST_HAS_PARAM_TEST
599 // RenderWidgetHostWithSourceTest ----------------------------------------------
601 // This is for tests that are to be run for all source devices.
602 class RenderWidgetHostWithSourceTest
603 : public RenderWidgetHostTest,
604 public testing::WithParamInterface<WebGestureDevice> {};
605 #endif // GTEST_HAS_PARAM_TEST
607 } // namespace
609 // -----------------------------------------------------------------------------
611 TEST_F(RenderWidgetHostTest, Resize) {
612 // The initial bounds is the empty rect, and the screen info hasn't been sent
613 // yet, so setting it to the same thing shouldn't send the resize message.
614 view_->set_bounds(gfx::Rect());
615 host_->WasResized();
616 EXPECT_FALSE(host_->resize_ack_pending_);
617 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
619 // No resize ack if the physical backing gets set, but the view bounds are
620 // zero.
621 view_->SetMockPhysicalBackingSize(gfx::Size(200, 200));
622 host_->WasResized();
623 EXPECT_FALSE(host_->resize_ack_pending_);
625 // Setting the view bounds to nonzero should send out the notification.
626 // but should not expect ack for empty physical backing size.
627 gfx::Rect original_size(0, 0, 100, 100);
628 process_->sink().ClearMessages();
629 view_->set_bounds(original_size);
630 view_->SetMockPhysicalBackingSize(gfx::Size());
631 host_->WasResized();
632 EXPECT_FALSE(host_->resize_ack_pending_);
633 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
634 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
636 // Setting the bounds and physical backing size to nonzero should send out
637 // the notification and expect an ack.
638 process_->sink().ClearMessages();
639 view_->ClearMockPhysicalBackingSize();
640 host_->WasResized();
641 EXPECT_TRUE(host_->resize_ack_pending_);
642 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
643 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
644 ViewHostMsg_UpdateRect_Params params;
645 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
646 params.view_size = original_size.size();
647 host_->OnUpdateRect(params);
648 EXPECT_FALSE(host_->resize_ack_pending_);
650 // Send out a update that's not a resize ack after setting resize ack pending
651 // flag. This should not clean the resize ack pending flag.
652 process_->sink().ClearMessages();
653 gfx::Rect second_size(0, 0, 110, 110);
654 EXPECT_FALSE(host_->resize_ack_pending_);
655 view_->set_bounds(second_size);
656 host_->WasResized();
657 EXPECT_TRUE(host_->resize_ack_pending_);
658 params.flags = 0;
659 params.view_size = gfx::Size(100, 100);
660 host_->OnUpdateRect(params);
661 EXPECT_TRUE(host_->resize_ack_pending_);
662 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
664 // Sending out a new notification should NOT send out a new IPC message since
665 // a resize ACK is pending.
666 gfx::Rect third_size(0, 0, 120, 120);
667 process_->sink().ClearMessages();
668 view_->set_bounds(third_size);
669 host_->WasResized();
670 EXPECT_TRUE(host_->resize_ack_pending_);
671 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
672 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
674 // Send a update that's a resize ack, but for the original_size we sent. Since
675 // this isn't the second_size, the message handler should immediately send
676 // a new resize message for the new size to the renderer.
677 process_->sink().ClearMessages();
678 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
679 params.view_size = original_size.size();
680 host_->OnUpdateRect(params);
681 EXPECT_TRUE(host_->resize_ack_pending_);
682 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
683 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
685 // Send the resize ack for the latest size.
686 process_->sink().ClearMessages();
687 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
688 params.view_size = third_size.size();
689 host_->OnUpdateRect(params);
690 EXPECT_FALSE(host_->resize_ack_pending_);
691 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
692 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
694 // Now clearing the bounds should send out a notification but we shouldn't
695 // expect a resize ack (since the renderer won't ack empty sizes). The message
696 // should contain the new size (0x0) and not the previous one that we skipped
697 process_->sink().ClearMessages();
698 view_->set_bounds(gfx::Rect());
699 host_->WasResized();
700 EXPECT_FALSE(host_->resize_ack_pending_);
701 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
702 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
704 // Send a rect that has no area but has either width or height set.
705 process_->sink().ClearMessages();
706 view_->set_bounds(gfx::Rect(0, 0, 0, 30));
707 host_->WasResized();
708 EXPECT_FALSE(host_->resize_ack_pending_);
709 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
710 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
712 // Set the same size again. It should not be sent again.
713 process_->sink().ClearMessages();
714 host_->WasResized();
715 EXPECT_FALSE(host_->resize_ack_pending_);
716 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
717 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
719 // A different size should be sent again, however.
720 view_->set_bounds(gfx::Rect(0, 0, 0, 31));
721 host_->WasResized();
722 EXPECT_FALSE(host_->resize_ack_pending_);
723 EXPECT_EQ(gfx::Size(0, 31), host_->old_resize_params_->new_size);
724 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
727 // Test for crbug.com/25097. If a renderer crashes between a resize and the
728 // corresponding update message, we must be sure to clear the resize ack logic.
729 TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
730 // Clear the first Resize message that carried screen info.
731 process_->sink().ClearMessages();
733 // Setting the bounds to a "real" rect should send out the notification.
734 gfx::Rect original_size(0, 0, 100, 100);
735 view_->set_bounds(original_size);
736 host_->WasResized();
737 EXPECT_TRUE(host_->resize_ack_pending_);
738 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
739 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
741 // Simulate a renderer crash before the update message. Ensure all the
742 // resize ack logic is cleared. Must clear the view first so it doesn't get
743 // deleted.
744 host_->SetView(NULL);
745 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
746 EXPECT_FALSE(host_->resize_ack_pending_);
747 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
749 // Reset the view so we can exit the test cleanly.
750 host_->SetView(view_.get());
753 // Unable to include render_widget_host_view_mac.h and compile.
754 #if !defined(OS_MACOSX)
755 // Tests setting background transparency.
756 TEST_F(RenderWidgetHostTest, Background) {
757 scoped_ptr<RenderWidgetHostViewBase> view;
758 #if defined(USE_AURA)
759 view.reset(new RenderWidgetHostViewAura(host_.get(), false));
760 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
761 view->InitAsChild(NULL);
762 #elif defined(OS_ANDROID)
763 view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
764 #endif
765 host_->SetView(view.get());
767 EXPECT_TRUE(view->GetBackgroundOpaque());
768 view->SetBackgroundColor(SK_ColorTRANSPARENT);
769 EXPECT_FALSE(view->GetBackgroundOpaque());
771 const IPC::Message* set_background =
772 process_->sink().GetUniqueMessageMatching(
773 ViewMsg_SetBackgroundOpaque::ID);
774 ASSERT_TRUE(set_background);
775 Tuple<bool> sent_background;
776 ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
777 EXPECT_FALSE(get<0>(sent_background));
779 #if defined(USE_AURA)
780 // See the comment above |InitAsChild(NULL)|.
781 host_->SetView(NULL);
782 static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
783 #endif
785 #endif
787 // Test that we don't paint when we're hidden, but we still send the ACK. Most
788 // of the rest of the painting is tested in the GetBackingStore* ones.
789 TEST_F(RenderWidgetHostTest, HiddenPaint) {
790 BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
791 // Hide the widget, it should have sent out a message to the renderer.
792 EXPECT_FALSE(host_->is_hidden_);
793 host_->WasHidden();
794 EXPECT_TRUE(host_->is_hidden_);
795 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID));
797 // Send it an update as from the renderer.
798 process_->sink().ClearMessages();
799 ViewHostMsg_UpdateRect_Params params;
800 params.view_size = gfx::Size(100, 100);
801 host_->OnUpdateRect(params);
803 // Now unhide.
804 process_->sink().ClearMessages();
805 host_->WasShown(ui::LatencyInfo());
806 EXPECT_FALSE(host_->is_hidden_);
808 // It should have sent out a restored message with a request to paint.
809 const IPC::Message* restored = process_->sink().GetUniqueMessageMatching(
810 ViewMsg_WasShown::ID);
811 ASSERT_TRUE(restored);
812 Tuple<bool, ui::LatencyInfo> needs_repaint;
813 ViewMsg_WasShown::Read(restored, &needs_repaint);
814 EXPECT_TRUE(get<0>(needs_repaint));
817 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
818 // Simulate a keyboard event.
819 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
821 // Make sure we sent the input event to the renderer.
822 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
823 InputMsg_HandleInputEvent::ID));
824 process_->sink().ClearMessages();
826 // Send the simulated response from the renderer back.
827 SendInputEventACK(WebInputEvent::RawKeyDown,
828 INPUT_EVENT_ACK_STATE_CONSUMED);
829 EXPECT_FALSE(delegate_->unhandled_keyboard_event_called());
832 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
833 // Simluate the situation that the browser handled the key down event during
834 // pre-handle phrase.
835 delegate_->set_prehandle_keyboard_event(true);
836 process_->sink().ClearMessages();
838 // Simulate a keyboard event.
839 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
841 EXPECT_TRUE(delegate_->prehandle_keyboard_event_called());
842 EXPECT_EQ(WebInputEvent::RawKeyDown,
843 delegate_->prehandle_keyboard_event_type());
845 // Make sure the RawKeyDown event is not sent to the renderer.
846 EXPECT_EQ(0U, process_->sink().message_count());
848 // The browser won't pre-handle a Char event.
849 delegate_->set_prehandle_keyboard_event(false);
851 // Forward the Char event.
852 SimulateKeyboardEvent(WebInputEvent::Char);
854 // Make sure the Char event is suppressed.
855 EXPECT_EQ(0U, process_->sink().message_count());
857 // Forward the KeyUp event.
858 SimulateKeyboardEvent(WebInputEvent::KeyUp);
860 // Make sure only KeyUp was sent to the renderer.
861 EXPECT_EQ(1U, process_->sink().message_count());
862 EXPECT_EQ(InputMsg_HandleInputEvent::ID,
863 process_->sink().GetMessageAt(0)->type());
864 process_->sink().ClearMessages();
866 // Send the simulated response from the renderer back.
867 SendInputEventACK(WebInputEvent::KeyUp,
868 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
870 EXPECT_TRUE(delegate_->unhandled_keyboard_event_called());
871 EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type());
874 TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
875 SimulateWheelEvent(-5, 0, 0, true);
877 // Make sure we sent the input event to the renderer.
878 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
879 InputMsg_HandleInputEvent::ID));
880 process_->sink().ClearMessages();
882 // Send the simulated response from the renderer back.
883 SendInputEventACK(WebInputEvent::MouseWheel,
884 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
885 EXPECT_TRUE(delegate_->handle_wheel_event_called());
886 EXPECT_EQ(1, view_->unhandled_wheel_event_count());
887 EXPECT_EQ(-5, view_->unhandled_wheel_event().deltaX);
890 TEST_F(RenderWidgetHostTest, HandleWheelEvent) {
891 // Indicate that we're going to handle this wheel event
892 delegate_->set_handle_wheel_event(true);
894 SimulateWheelEvent(-5, 0, 0, true);
896 // Make sure we sent the input event to the renderer.
897 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
898 InputMsg_HandleInputEvent::ID));
899 process_->sink().ClearMessages();
901 // Send the simulated response from the renderer back.
902 SendInputEventACK(WebInputEvent::MouseWheel,
903 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
905 // ensure the wheel event handler was invoked
906 EXPECT_TRUE(delegate_->handle_wheel_event_called());
908 // and that it suppressed the unhandled wheel event handler.
909 EXPECT_EQ(0, view_->unhandled_wheel_event_count());
912 TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
913 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap,
914 blink::WebGestureDeviceTouchscreen);
916 // Make sure we sent the input event to the renderer.
917 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
918 InputMsg_HandleInputEvent::ID));
919 process_->sink().ClearMessages();
921 // Send the simulated response from the renderer back.
922 SendInputEventACK(WebInputEvent::GestureTwoFingerTap,
923 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
924 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap, view_->gesture_event_type());
925 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, view_->ack_result());
928 // Test that the hang monitor timer expires properly if a new timer is started
929 // while one is in progress (see crbug.com/11007).
930 TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) {
931 // Start with a short timeout.
932 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
934 // Immediately try to add a long 30 second timeout.
935 EXPECT_FALSE(host_->unresponsive_timer_fired());
936 host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
938 // Wait long enough for first timeout and see if it fired.
939 base::MessageLoop::current()->PostDelayedTask(
940 FROM_HERE,
941 base::MessageLoop::QuitClosure(),
942 TimeDelta::FromMilliseconds(10));
943 base::MessageLoop::current()->Run();
944 EXPECT_TRUE(host_->unresponsive_timer_fired());
947 // Test that the hang monitor timer expires properly if it is started, stopped,
948 // and then started again.
949 TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
950 // Start with a short timeout, then stop it.
951 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
952 host_->StopHangMonitorTimeout();
954 // Start it again to ensure it still works.
955 EXPECT_FALSE(host_->unresponsive_timer_fired());
956 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
958 // Wait long enough for first timeout and see if it fired.
959 base::MessageLoop::current()->PostDelayedTask(
960 FROM_HERE,
961 base::MessageLoop::QuitClosure(),
962 TimeDelta::FromMilliseconds(40));
963 base::MessageLoop::current()->Run();
964 EXPECT_TRUE(host_->unresponsive_timer_fired());
967 // Test that the hang monitor timer expires properly if it is started, then
968 // updated to a shorter duration.
969 TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) {
970 // Start with a timeout.
971 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
973 // Start it again with shorter delay.
974 EXPECT_FALSE(host_->unresponsive_timer_fired());
975 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
977 // Wait long enough for the second timeout and see if it fired.
978 base::MessageLoop::current()->PostDelayedTask(
979 FROM_HERE,
980 base::MessageLoop::QuitClosure(),
981 TimeDelta::FromMilliseconds(25));
982 base::MessageLoop::current()->Run();
983 EXPECT_TRUE(host_->unresponsive_timer_fired());
986 // Test that the hang monitor catches two input events but only one ack.
987 // This can happen if the second input event causes the renderer to hang.
988 // This test will catch a regression of crbug.com/111185.
989 TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
990 // Configure the host to wait 10ms before considering
991 // the renderer hung.
992 host_->set_hung_renderer_delay_ms(10);
994 // Send two events but only one ack.
995 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
996 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
997 SendInputEventACK(WebInputEvent::RawKeyDown,
998 INPUT_EVENT_ACK_STATE_CONSUMED);
1000 // Wait long enough for first timeout and see if it fired.
1001 base::MessageLoop::current()->PostDelayedTask(
1002 FROM_HERE,
1003 base::MessageLoop::QuitClosure(),
1004 TimeDelta::FromMilliseconds(40));
1005 base::MessageLoop::current()->Run();
1006 EXPECT_TRUE(host_->unresponsive_timer_fired());
1009 std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
1010 std::string result;
1011 for (size_t i = 0; i < process->sink().message_count(); ++i) {
1012 const IPC::Message *message = process->sink().GetMessageAt(i);
1013 EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
1014 InputMsg_HandleInputEvent::Param params;
1015 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1016 const WebInputEvent* event = get<0>(params);
1017 if (i != 0)
1018 result += " ";
1019 result += WebInputEventTraits::GetName(event->type);
1021 process->sink().ClearMessages();
1022 return result;
1025 TEST_F(RenderWidgetHostTest, TouchEmulator) {
1026 simulated_event_time_delta_seconds_ = 0.1;
1027 // Immediately ack all touches instead of sending them to the renderer.
1028 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1029 host_->SetTouchEventEmulationEnabled(
1030 true, ui::GestureProviderConfigType::GENERIC_MOBILE);
1031 process_->sink().ClearMessages();
1032 view_->set_bounds(gfx::Rect(0, 0, 400, 200));
1033 view_->Show();
1035 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1036 EXPECT_EQ(0U, process_->sink().message_count());
1038 // Mouse press becomes touch start which in turn becomes tap.
1039 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1040 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1041 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1043 // Mouse drag generates touch move, cancels tap and starts scroll.
1044 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1045 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1046 EXPECT_EQ(
1047 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1048 GetInputMessageTypes(process_));
1049 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1050 INPUT_EVENT_ACK_STATE_CONSUMED);
1051 EXPECT_EQ(0U, process_->sink().message_count());
1053 // Mouse drag with shift becomes pinch.
1054 SimulateMouseEvent(
1055 WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true);
1056 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1057 EXPECT_EQ("GesturePinchBegin",
1058 GetInputMessageTypes(process_));
1059 EXPECT_EQ(0U, process_->sink().message_count());
1061 SimulateMouseEvent(
1062 WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true);
1063 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1064 EXPECT_EQ("GesturePinchUpdate",
1065 GetInputMessageTypes(process_));
1066 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1067 INPUT_EVENT_ACK_STATE_CONSUMED);
1068 EXPECT_EQ(0U, process_->sink().message_count());
1070 // Mouse drag without shift becomes scroll again.
1071 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true);
1072 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1073 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1074 GetInputMessageTypes(process_));
1075 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1076 INPUT_EVENT_ACK_STATE_CONSUMED);
1077 EXPECT_EQ(0U, process_->sink().message_count());
1079 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true);
1080 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1081 EXPECT_EQ("GestureScrollUpdate",
1082 GetInputMessageTypes(process_));
1083 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1084 INPUT_EVENT_ACK_STATE_CONSUMED);
1085 EXPECT_EQ(0U, process_->sink().message_count());
1087 SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true);
1088 EXPECT_EQ(WebInputEvent::TouchEnd, host_->acked_touch_event_type());
1089 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1090 EXPECT_EQ(0U, process_->sink().message_count());
1092 // Mouse move does nothing.
1093 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false);
1094 EXPECT_EQ(0U, process_->sink().message_count());
1096 // Another mouse down continues scroll.
1097 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true);
1098 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1099 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1100 EXPECT_EQ(0U, process_->sink().message_count());
1102 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true);
1103 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1104 EXPECT_EQ(
1105 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1106 GetInputMessageTypes(process_));
1107 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1108 INPUT_EVENT_ACK_STATE_CONSUMED);
1109 EXPECT_EQ(0U, process_->sink().message_count());
1111 // Another pinch.
1112 SimulateMouseEvent(
1113 WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true);
1114 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1115 EXPECT_EQ("GesturePinchBegin",
1116 GetInputMessageTypes(process_));
1117 EXPECT_EQ(0U, process_->sink().message_count());
1119 SimulateMouseEvent(
1120 WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true);
1121 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1122 EXPECT_EQ("GesturePinchUpdate",
1123 GetInputMessageTypes(process_));
1124 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1125 INPUT_EVENT_ACK_STATE_CONSUMED);
1126 EXPECT_EQ(0U, process_->sink().message_count());
1128 // Turn off emulation during a pinch.
1129 host_->SetTouchEventEmulationEnabled(
1130 false, ui::GestureProviderConfigType::GENERIC_MOBILE);
1131 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1132 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1133 GetInputMessageTypes(process_));
1134 EXPECT_EQ(0U, process_->sink().message_count());
1136 // Mouse event should pass untouched.
1137 SimulateMouseEvent(
1138 WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true);
1139 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_));
1140 SendInputEventACK(WebInputEvent::MouseMove,
1141 INPUT_EVENT_ACK_STATE_CONSUMED);
1142 EXPECT_EQ(0U, process_->sink().message_count());
1144 // Turn on emulation.
1145 host_->SetTouchEventEmulationEnabled(
1146 true, ui::GestureProviderConfigType::GENERIC_MOBILE);
1147 EXPECT_EQ(0U, process_->sink().message_count());
1149 // Another touch.
1150 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1151 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1152 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1153 EXPECT_EQ(0U, process_->sink().message_count());
1155 // Scroll.
1156 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1157 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1158 EXPECT_EQ(
1159 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1160 GetInputMessageTypes(process_));
1161 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1162 INPUT_EVENT_ACK_STATE_CONSUMED);
1164 // Turn off emulation during a scroll.
1165 host_->SetTouchEventEmulationEnabled(
1166 false, ui::GestureProviderConfigType::GENERIC_MOBILE);
1167 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1169 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1170 EXPECT_EQ(0U, process_->sink().message_count());
1173 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1174 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1175 host_->SetupForInputRouterTest(); \
1176 host_->INPUTMSG(); \
1177 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1180 TEST_InputRouterRoutes_NOARGS(Focus);
1181 TEST_InputRouterRoutes_NOARGS(Blur);
1182 TEST_InputRouterRoutes_NOARGS(LostCapture);
1184 #undef TEST_InputRouterRoutes_NOARGS
1186 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1187 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1188 host_->SetupForInputRouterTest(); \
1189 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1190 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1193 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo);
1194 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo);
1195 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut);
1196 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy);
1197 #if defined(OS_MACOSX)
1198 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard);
1199 #endif
1200 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste);
1201 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle);
1202 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete);
1203 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll);
1204 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect);
1206 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1208 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplace) {
1209 host_->SetupForInputRouterTest();
1210 host_->Send(new InputMsg_Replace(host_->GetRoutingID(), base::string16()));
1211 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1214 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplaceMisspelling) {
1215 host_->SetupForInputRouterTest();
1216 host_->Send(new InputMsg_ReplaceMisspelling(host_->GetRoutingID(),
1217 base::string16()));
1218 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1221 TEST_F(RenderWidgetHostTest, IgnoreInputEvent) {
1222 host_->SetupForInputRouterTest();
1224 host_->SetIgnoreInputEvents(true);
1226 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1227 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1229 SimulateMouseEvent(WebInputEvent::MouseMove);
1230 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1232 SimulateWheelEvent(0, 100, 0, true);
1233 EXPECT_FALSE(host_->mock_input_router()->sent_wheel_event_);
1235 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1236 blink::WebGestureDeviceTouchpad);
1237 EXPECT_FALSE(host_->mock_input_router()->sent_gesture_event_);
1239 PressTouchPoint(100, 100);
1240 SendTouchEvent();
1241 EXPECT_FALSE(host_->mock_input_router()->send_touch_event_not_cancelled_);
1244 TEST_F(RenderWidgetHostTest, KeyboardListenerIgnoresEvent) {
1245 host_->SetupForInputRouterTest();
1246 host_->AddKeyPressEventCallback(
1247 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1248 base::Unretained(this)));
1249 handle_key_press_event_ = false;
1250 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1252 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1255 TEST_F(RenderWidgetHostTest, KeyboardListenerSuppressFollowingEvents) {
1256 host_->SetupForInputRouterTest();
1258 host_->AddKeyPressEventCallback(
1259 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1260 base::Unretained(this)));
1262 // The callback handles the first event
1263 handle_key_press_event_ = true;
1264 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1266 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1268 // Following Char events should be suppressed
1269 handle_key_press_event_ = false;
1270 SimulateKeyboardEvent(WebInputEvent::Char);
1271 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1272 SimulateKeyboardEvent(WebInputEvent::Char);
1273 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1275 // Sending RawKeyDown event should stop suppression
1276 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1277 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1279 host_->mock_input_router()->sent_keyboard_event_ = false;
1280 SimulateKeyboardEvent(WebInputEvent::Char);
1281 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1284 TEST_F(RenderWidgetHostTest, MouseEventCallbackCanHandleEvent) {
1285 host_->SetupForInputRouterTest();
1287 host_->AddMouseEventCallback(
1288 base::Bind(&RenderWidgetHostTest::MouseEventCallback,
1289 base::Unretained(this)));
1291 handle_mouse_event_ = true;
1292 SimulateMouseEvent(WebInputEvent::MouseDown);
1294 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1296 handle_mouse_event_ = false;
1297 SimulateMouseEvent(WebInputEvent::MouseDown);
1299 EXPECT_TRUE(host_->mock_input_router()->sent_mouse_event_);
1302 TEST_F(RenderWidgetHostTest, InputRouterReceivesHandleInputEvent_ACK) {
1303 host_->SetupForInputRouterTest();
1305 SendInputEventACK(WebInputEvent::RawKeyDown,
1306 INPUT_EVENT_ACK_STATE_CONSUMED);
1308 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1311 TEST_F(RenderWidgetHostTest, InputRouterReceivesMoveCaret_ACK) {
1312 host_->SetupForInputRouterTest();
1314 host_->OnMessageReceived(InputHostMsg_MoveCaret_ACK(0));
1316 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1319 TEST_F(RenderWidgetHostTest, InputRouterReceivesSelectRange_ACK) {
1320 host_->SetupForInputRouterTest();
1322 host_->OnMessageReceived(InputHostMsg_SelectRange_ACK(0));
1324 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1327 TEST_F(RenderWidgetHostTest, InputRouterReceivesHasTouchEventHandlers) {
1328 host_->SetupForInputRouterTest();
1330 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1332 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1335 ui::LatencyInfo GetLatencyInfoFromInputEvent(RenderWidgetHostProcess* process) {
1336 const IPC::Message* message = process->sink().GetUniqueMessageMatching(
1337 InputMsg_HandleInputEvent::ID);
1338 EXPECT_TRUE(message);
1339 InputMsg_HandleInputEvent::Param params;
1340 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1341 process->sink().ClearMessages();
1342 return get<1>(params);
1345 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process,
1346 int64 component_id,
1347 WebInputEvent::Type input_type) {
1348 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process);
1349 EXPECT_TRUE(latency_info.FindLatency(
1350 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
1351 component_id,
1352 NULL));
1355 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1356 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1357 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1358 // event's LatencyInfo.
1359 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
1360 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1361 process_->sink().ClearMessages();
1363 // Tests RWHI::ForwardWheelEvent().
1364 SimulateWheelEvent(-5, 0, 0, true);
1365 CheckLatencyInfoComponentInMessage(
1366 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1367 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1369 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1370 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1371 CheckLatencyInfoComponentInMessage(
1372 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1373 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1375 // Tests RWHI::ForwardMouseEvent().
1376 SimulateMouseEvent(WebInputEvent::MouseMove);
1377 CheckLatencyInfoComponentInMessage(
1378 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1379 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1381 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1382 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove,
1383 ui::LatencyInfo());
1384 CheckLatencyInfoComponentInMessage(
1385 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1386 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1388 // Tests RWHI::ForwardGestureEvent().
1389 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1390 blink::WebGestureDeviceTouchscreen);
1391 CheckLatencyInfoComponentInMessage(
1392 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin);
1394 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1395 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate,
1396 blink::WebGestureDeviceTouchscreen,
1397 ui::LatencyInfo());
1398 CheckLatencyInfoComponentInMessage(
1399 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate);
1400 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1401 INPUT_EVENT_ACK_STATE_CONSUMED);
1403 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1404 PressTouchPoint(0, 1);
1405 SendTouchEvent();
1406 CheckLatencyInfoComponentInMessage(
1407 process_, GetLatencyComponentId(), WebInputEvent::TouchStart);
1408 SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
1411 TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) {
1412 // RendererExited will delete the view.
1413 host_->SetView(new TestView(host_.get()));
1414 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1416 // Make sure the input router is in a fresh state.
1417 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1420 // Regression test for http://crbug.com/401859.
1421 TEST_F(RenderWidgetHostTest, RendererExitedResetsIsHidden) {
1422 // RendererExited will delete the view.
1423 host_->SetView(new TestView(host_.get()));
1424 host_->WasHidden();
1426 ASSERT_TRUE(host_->is_hidden());
1427 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1428 ASSERT_FALSE(host_->is_hidden());
1430 // Make sure the input router is in a fresh state.
1431 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1434 TEST_F(RenderWidgetHostTest, ResizeParams) {
1435 gfx::Rect bounds(0, 0, 100, 100);
1436 gfx::Size physical_backing_size(40, 50);
1437 view_->set_bounds(bounds);
1438 view_->SetMockPhysicalBackingSize(physical_backing_size);
1440 ViewMsg_Resize_Params resize_params;
1441 host_->GetResizeParams(&resize_params);
1442 EXPECT_EQ(bounds.size(), resize_params.new_size);
1443 EXPECT_EQ(physical_backing_size, resize_params.physical_backing_size);
1446 class RenderWidgetHostInitialSizeTest : public RenderWidgetHostTest {
1447 public:
1448 RenderWidgetHostInitialSizeTest()
1449 : RenderWidgetHostTest(), initial_size_(200, 100) {}
1451 void ConfigureView(TestView* view) override {
1452 view->set_bounds(gfx::Rect(initial_size_));
1455 protected:
1456 gfx::Size initial_size_;
1459 TEST_F(RenderWidgetHostInitialSizeTest, InitialSize) {
1460 // Having an initial size set means that the size information had been sent
1461 // with the reqiest to new up the RenderView and so subsequent WasResized
1462 // calls should not result in new IPC (unless the size has actually changed).
1463 host_->WasResized();
1464 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
1465 EXPECT_EQ(initial_size_, host_->old_resize_params_->new_size);
1466 EXPECT_TRUE(host_->resize_ack_pending_);
1469 } // namespace content