Roll src/third_party/skia 21b998b:bda7da8
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_unittest.cc
blob77fa004933c582ad3eaba28f4cee99361e7bdc98
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/location.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/shared_memory.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "base/timer/timer.h"
14 #include "content/browser/browser_thread_impl.h"
15 #include "content/browser/gpu/compositor_util.h"
16 #include "content/browser/renderer_host/input/input_router_impl.h"
17 #include "content/browser/renderer_host/render_widget_host_delegate.h"
18 #include "content/browser/renderer_host/render_widget_host_view_base.h"
19 #include "content/common/input/synthetic_web_input_event_builders.h"
20 #include "content/common/input_messages.h"
21 #include "content/common/view_messages.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/test/mock_render_process_host.h"
24 #include "content/public/test/test_browser_context.h"
25 #include "content/test/test_render_view_host.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/events/keycodes/keyboard_codes.h"
28 #include "ui/gfx/canvas.h"
29 #include "ui/gfx/screen.h"
31 #if defined(OS_ANDROID)
32 #include "content/browser/renderer_host/render_widget_host_view_android.h"
33 #endif
35 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
36 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
37 #endif
39 #if defined(USE_AURA)
40 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
41 #include "content/browser/renderer_host/ui_events_helper.h"
42 #include "ui/aura/test/test_screen.h"
43 #include "ui/events/event.h"
44 #endif
46 using base::TimeDelta;
47 using blink::WebGestureDevice;
48 using blink::WebGestureEvent;
49 using blink::WebInputEvent;
50 using blink::WebKeyboardEvent;
51 using blink::WebMouseEvent;
52 using blink::WebMouseWheelEvent;
53 using blink::WebTouchEvent;
54 using blink::WebTouchPoint;
56 namespace content {
58 // MockInputRouter -------------------------------------------------------------
60 class MockInputRouter : public InputRouter {
61 public:
62 explicit MockInputRouter(InputRouterClient* client)
63 : send_event_called_(false),
64 sent_mouse_event_(false),
65 sent_wheel_event_(false),
66 sent_keyboard_event_(false),
67 sent_gesture_event_(false),
68 send_touch_event_not_cancelled_(false),
69 message_received_(false),
70 client_(client) {
72 ~MockInputRouter() override {}
74 // InputRouter
75 bool SendInput(scoped_ptr<IPC::Message> message) override {
76 send_event_called_ = true;
77 return true;
79 void SendMouseEvent(const MouseEventWithLatencyInfo& mouse_event) override {
80 sent_mouse_event_ = true;
82 void SendWheelEvent(
83 const MouseWheelEventWithLatencyInfo& wheel_event) override {
84 sent_wheel_event_ = true;
86 void SendKeyboardEvent(const NativeWebKeyboardEventWithLatencyInfo& key_event,
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 NotifySiteIsMobileOptimized(bool is_mobile_optimized) override {}
104 void RequestNotificationWhenFlushed() override {}
105 bool HasPendingEvents() const override { return false; }
107 // IPC::Listener
108 bool OnMessageReceived(const IPC::Message& message) override {
109 message_received_ = true;
110 return false;
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 DisableGestureDebounce() {
162 input_router_.reset(new InputRouterImpl(
163 process_, this, this, routing_id_, InputRouterImpl::Config()));
166 WebInputEvent::Type acked_touch_event_type() const {
167 return acked_touch_event_type_;
170 void SetupForInputRouterTest() {
171 input_router_.reset(new MockInputRouter(this));
174 MockInputRouter* mock_input_router() {
175 return static_cast<MockInputRouter*>(input_router_.get());
178 protected:
179 void NotifyRendererUnresponsive() override {
180 unresponsive_timer_fired_ = true;
183 bool unresponsive_timer_fired_;
184 WebInputEvent::Type acked_touch_event_type_;
186 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
189 namespace {
191 // RenderWidgetHostProcess -----------------------------------------------------
193 class RenderWidgetHostProcess : public MockRenderProcessHost {
194 public:
195 explicit RenderWidgetHostProcess(BrowserContext* browser_context)
196 : MockRenderProcessHost(browser_context) {
198 ~RenderWidgetHostProcess() override {}
200 bool HasConnection() const override { return true; }
202 protected:
203 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess);
206 // TestView --------------------------------------------------------------------
208 // This test view allows us to specify the size, and keep track of acked
209 // touch-events.
210 class TestView : public TestRenderWidgetHostView {
211 public:
212 explicit TestView(RenderWidgetHostImpl* rwh)
213 : TestRenderWidgetHostView(rwh),
214 unhandled_wheel_event_count_(0),
215 acked_event_count_(0),
216 gesture_event_type_(-1),
217 use_fake_physical_backing_size_(false),
218 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
221 // Sets the bounds returned by GetViewBounds.
222 void set_bounds(const gfx::Rect& bounds) {
223 bounds_ = bounds;
226 const WebTouchEvent& acked_event() const { return acked_event_; }
227 int acked_event_count() const { return acked_event_count_; }
228 void ClearAckedEvent() {
229 acked_event_.type = blink::WebInputEvent::Undefined;
230 acked_event_count_ = 0;
233 const WebMouseWheelEvent& unhandled_wheel_event() const {
234 return unhandled_wheel_event_;
236 int unhandled_wheel_event_count() const {
237 return unhandled_wheel_event_count_;
239 int gesture_event_type() const { return gesture_event_type_; }
240 InputEventAckState ack_result() const { return ack_result_; }
242 void SetMockPhysicalBackingSize(const gfx::Size& mock_physical_backing_size) {
243 use_fake_physical_backing_size_ = true;
244 mock_physical_backing_size_ = mock_physical_backing_size;
246 void ClearMockPhysicalBackingSize() {
247 use_fake_physical_backing_size_ = false;
249 void SetScreenInfo(const blink::WebScreenInfo& screen_info) {
250 screen_info_ = screen_info;
253 // RenderWidgetHostView override.
254 gfx::Rect GetViewBounds() const override { return bounds_; }
255 void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
256 InputEventAckState ack_result) override {
257 acked_event_ = touch.event;
258 ++acked_event_count_;
260 void WheelEventAck(const WebMouseWheelEvent& event,
261 InputEventAckState ack_result) override {
262 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
263 return;
264 unhandled_wheel_event_count_++;
265 unhandled_wheel_event_ = event;
267 void GestureEventAck(const WebGestureEvent& event,
268 InputEventAckState ack_result) override {
269 gesture_event_type_ = event.type;
270 ack_result_ = ack_result;
272 gfx::Size GetPhysicalBackingSize() const override {
273 if (use_fake_physical_backing_size_)
274 return mock_physical_backing_size_;
275 return TestRenderWidgetHostView::GetPhysicalBackingSize();
277 void GetScreenInfo(blink::WebScreenInfo* screen_info) override {
278 *screen_info = screen_info_;
280 #if defined(USE_AURA)
281 ~TestView() override {
282 // Simulate the mouse exit event dispatched when an aura window is
283 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
284 // into WebInputEvent::MouseMove.)
285 WebMouseEvent event =
286 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove);
287 event.timeStampSeconds =
288 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
289 rwh_->input_router()->SendMouseEvent(
290 MouseEventWithLatencyInfo(event, ui::LatencyInfo()));
292 #endif
294 protected:
295 WebMouseWheelEvent unhandled_wheel_event_;
296 int unhandled_wheel_event_count_;
297 WebTouchEvent acked_event_;
298 int acked_event_count_;
299 int gesture_event_type_;
300 gfx::Rect bounds_;
301 bool use_fake_physical_backing_size_;
302 gfx::Size mock_physical_backing_size_;
303 InputEventAckState ack_result_;
304 blink::WebScreenInfo screen_info_;
306 DISALLOW_COPY_AND_ASSIGN(TestView);
309 // MockRenderWidgetHostDelegate --------------------------------------------
311 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
312 public:
313 MockRenderWidgetHostDelegate()
314 : prehandle_keyboard_event_(false),
315 prehandle_keyboard_event_called_(false),
316 prehandle_keyboard_event_type_(WebInputEvent::Undefined),
317 unhandled_keyboard_event_called_(false),
318 unhandled_keyboard_event_type_(WebInputEvent::Undefined),
319 handle_wheel_event_(false),
320 handle_wheel_event_called_(false) {
322 ~MockRenderWidgetHostDelegate() override {}
324 // Tests that make sure we ignore keyboard event acknowledgments to events we
325 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
326 bool unhandled_keyboard_event_called() const {
327 return unhandled_keyboard_event_called_;
330 WebInputEvent::Type unhandled_keyboard_event_type() const {
331 return unhandled_keyboard_event_type_;
334 bool prehandle_keyboard_event_called() const {
335 return prehandle_keyboard_event_called_;
338 WebInputEvent::Type prehandle_keyboard_event_type() const {
339 return prehandle_keyboard_event_type_;
342 void set_prehandle_keyboard_event(bool handle) {
343 prehandle_keyboard_event_ = handle;
346 void set_handle_wheel_event(bool handle) {
347 handle_wheel_event_ = handle;
350 bool handle_wheel_event_called() {
351 return handle_wheel_event_called_;
354 protected:
355 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
356 bool* is_keyboard_shortcut) override {
357 prehandle_keyboard_event_type_ = event.type;
358 prehandle_keyboard_event_called_ = true;
359 return prehandle_keyboard_event_;
362 void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override {
363 unhandled_keyboard_event_type_ = event.type;
364 unhandled_keyboard_event_called_ = true;
367 bool HandleWheelEvent(const blink::WebMouseWheelEvent& event) override {
368 handle_wheel_event_called_ = true;
369 return handle_wheel_event_;
372 void Cut() override {}
373 void Copy() override {}
374 void Paste() override {}
375 void SelectAll() override {}
377 private:
378 bool prehandle_keyboard_event_;
379 bool prehandle_keyboard_event_called_;
380 WebInputEvent::Type prehandle_keyboard_event_type_;
382 bool unhandled_keyboard_event_called_;
383 WebInputEvent::Type unhandled_keyboard_event_type_;
385 bool handle_wheel_event_;
386 bool handle_wheel_event_called_;
389 // RenderWidgetHostTest --------------------------------------------------------
391 class RenderWidgetHostTest : public testing::Test {
392 public:
393 RenderWidgetHostTest()
394 : process_(NULL),
395 handle_key_press_event_(false),
396 handle_mouse_event_(false),
397 simulated_event_time_delta_seconds_(0) {
398 last_simulated_event_time_seconds_ =
399 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
401 ~RenderWidgetHostTest() override {}
403 bool KeyPressEventCallback(const NativeWebKeyboardEvent& /* event */) {
404 return handle_key_press_event_;
406 bool MouseEventCallback(const blink::WebMouseEvent& /* event */) {
407 return handle_mouse_event_;
410 protected:
411 // testing::Test
412 void SetUp() override {
413 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
414 command_line->AppendSwitch(switches::kValidateInputEventStream);
416 browser_context_.reset(new TestBrowserContext());
417 delegate_.reset(new MockRenderWidgetHostDelegate());
418 process_ = new RenderWidgetHostProcess(browser_context_.get());
419 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
420 if (IsDelegatedRendererEnabled()) {
421 ImageTransportFactory::InitializeForUnitTests(
422 scoped_ptr<ImageTransportFactory>(
423 new NoTransportImageTransportFactory));
425 #endif
426 #if defined(USE_AURA)
427 screen_.reset(aura::TestScreen::Create(gfx::Size()));
428 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
429 #endif
430 host_.reset(
431 new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
432 view_.reset(new TestView(host_.get()));
433 ConfigureView(view_.get());
434 host_->SetView(view_.get());
435 SetInitialRenderSizeParams();
436 host_->Init();
437 host_->DisableGestureDebounce();
440 void TearDown() override {
441 view_.reset();
442 host_.reset();
443 delegate_.reset();
444 process_ = NULL;
445 browser_context_.reset();
447 #if defined(USE_AURA)
448 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, nullptr);
449 screen_.reset();
450 #endif
451 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
452 if (IsDelegatedRendererEnabled())
453 ImageTransportFactory::Terminate();
454 #endif
456 // Process all pending tasks to avoid leaks.
457 base::MessageLoop::current()->RunUntilIdle();
460 void SetInitialRenderSizeParams() {
461 ViewMsg_Resize_Params render_size_params;
462 host_->GetResizeParams(&render_size_params);
463 host_->SetInitialRenderSizeParams(render_size_params);
466 virtual void ConfigureView(TestView* view) {
469 int64 GetLatencyComponentId() {
470 return host_->GetLatencyComponentId();
473 void SendInputEventACK(WebInputEvent::Type type,
474 InputEventAckState ack_result) {
475 DCHECK(!WebInputEvent::isTouchEventType(type));
476 InputEventAck ack(type, ack_result);
477 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
480 double GetNextSimulatedEventTimeSeconds() {
481 last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_;
482 return last_simulated_event_time_seconds_;
485 void SimulateKeyboardEvent(WebInputEvent::Type type) {
486 SimulateKeyboardEvent(type, 0);
489 void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) {
490 WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
491 event.modifiers = modifiers;
492 NativeWebKeyboardEvent native_event;
493 memcpy(&native_event, &event, sizeof(event));
494 host_->ForwardKeyboardEvent(native_event);
497 void SimulateMouseEvent(WebInputEvent::Type type) {
498 host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type));
501 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type,
502 const ui::LatencyInfo& ui_latency) {
503 host_->ForwardMouseEventWithLatencyInfo(
504 SyntheticWebMouseEventBuilder::Build(type),
505 ui_latency);
508 void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
509 host_->ForwardWheelEvent(
510 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
513 void SimulateWheelEventWithLatencyInfo(float dX,
514 float dY,
515 int modifiers,
516 bool precise,
517 const ui::LatencyInfo& ui_latency) {
518 host_->ForwardWheelEventWithLatencyInfo(
519 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
520 ui_latency);
523 void SimulateMouseMove(int x, int y, int modifiers) {
524 SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false);
527 void SimulateMouseEvent(
528 WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) {
529 WebMouseEvent event =
530 SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers);
531 if (pressed)
532 event.button = WebMouseEvent::ButtonLeft;
533 event.timeStampSeconds = GetNextSimulatedEventTimeSeconds();
534 host_->ForwardMouseEvent(event);
537 // Inject simple synthetic WebGestureEvent instances.
538 void SimulateGestureEvent(WebInputEvent::Type type,
539 WebGestureDevice sourceDevice) {
540 host_->ForwardGestureEvent(
541 SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
544 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type,
545 WebGestureDevice sourceDevice,
546 const ui::LatencyInfo& ui_latency) {
547 host_->ForwardGestureEventWithLatencyInfo(
548 SyntheticWebGestureEventBuilder::Build(type, sourceDevice),
549 ui_latency);
552 // Set the timestamp for the touch-event.
553 void SetTouchTimestamp(base::TimeDelta timestamp) {
554 touch_event_.SetTimestamp(timestamp);
557 // Sends a touch event (irrespective of whether the page has a touch-event
558 // handler or not).
559 uint32 SendTouchEvent() {
560 uint32 touch_event_id = touch_event_.uniqueTouchEventId;
561 host_->ForwardTouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo());
563 touch_event_.ResetPoints();
564 return touch_event_id;
567 int PressTouchPoint(int x, int y) {
568 return touch_event_.PressPoint(x, y);
571 void MoveTouchPoint(int index, int x, int y) {
572 touch_event_.MovePoint(index, x, y);
575 void ReleaseTouchPoint(int index) {
576 touch_event_.ReleasePoint(index);
579 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
580 base::PickleIterator iter(message);
581 const char* data;
582 int data_length;
583 if (!iter.ReadData(&data, &data_length))
584 return NULL;
585 return reinterpret_cast<const WebInputEvent*>(data);
588 base::MessageLoopForUI message_loop_;
590 scoped_ptr<TestBrowserContext> browser_context_;
591 RenderWidgetHostProcess* process_; // Deleted automatically by the widget.
592 scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
593 scoped_ptr<MockRenderWidgetHost> host_;
594 scoped_ptr<TestView> view_;
595 scoped_ptr<gfx::Screen> screen_;
596 bool handle_key_press_event_;
597 bool handle_mouse_event_;
598 double last_simulated_event_time_seconds_;
599 double simulated_event_time_delta_seconds_;
601 private:
602 SyntheticWebTouchEvent touch_event_;
604 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest);
607 #if GTEST_HAS_PARAM_TEST
608 // RenderWidgetHostWithSourceTest ----------------------------------------------
610 // This is for tests that are to be run for all source devices.
611 class RenderWidgetHostWithSourceTest
612 : public RenderWidgetHostTest,
613 public testing::WithParamInterface<WebGestureDevice> {};
614 #endif // GTEST_HAS_PARAM_TEST
616 } // namespace
618 // -----------------------------------------------------------------------------
620 TEST_F(RenderWidgetHostTest, Resize) {
621 // The initial bounds is the empty rect, so setting it to the same thing
622 // shouldn't send the resize message.
623 view_->set_bounds(gfx::Rect());
624 host_->WasResized();
625 EXPECT_FALSE(host_->resize_ack_pending_);
626 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
628 // No resize ack if the physical backing gets set, but the view bounds are
629 // zero.
630 view_->SetMockPhysicalBackingSize(gfx::Size(200, 200));
631 host_->WasResized();
632 EXPECT_FALSE(host_->resize_ack_pending_);
634 // Setting the view bounds to nonzero should send out the notification.
635 // but should not expect ack for empty physical backing size.
636 gfx::Rect original_size(0, 0, 100, 100);
637 process_->sink().ClearMessages();
638 view_->set_bounds(original_size);
639 view_->SetMockPhysicalBackingSize(gfx::Size());
640 host_->WasResized();
641 EXPECT_FALSE(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));
645 // Setting the bounds and physical backing size to nonzero should send out
646 // the notification and expect an ack.
647 process_->sink().ClearMessages();
648 view_->ClearMockPhysicalBackingSize();
649 host_->WasResized();
650 EXPECT_TRUE(host_->resize_ack_pending_);
651 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
652 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
653 ViewHostMsg_UpdateRect_Params params;
654 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
655 params.view_size = original_size.size();
656 host_->OnUpdateRect(params);
657 EXPECT_FALSE(host_->resize_ack_pending_);
659 // Send out a update that's not a resize ack after setting resize ack pending
660 // flag. This should not clean the resize ack pending flag.
661 process_->sink().ClearMessages();
662 gfx::Rect second_size(0, 0, 110, 110);
663 EXPECT_FALSE(host_->resize_ack_pending_);
664 view_->set_bounds(second_size);
665 host_->WasResized();
666 EXPECT_TRUE(host_->resize_ack_pending_);
667 params.flags = 0;
668 params.view_size = gfx::Size(100, 100);
669 host_->OnUpdateRect(params);
670 EXPECT_TRUE(host_->resize_ack_pending_);
671 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
673 // Sending out a new notification should NOT send out a new IPC message since
674 // a resize ACK is pending.
675 gfx::Rect third_size(0, 0, 120, 120);
676 process_->sink().ClearMessages();
677 view_->set_bounds(third_size);
678 host_->WasResized();
679 EXPECT_TRUE(host_->resize_ack_pending_);
680 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
681 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
683 // Send a update that's a resize ack, but for the original_size we sent. Since
684 // this isn't the second_size, the message handler should immediately send
685 // a new resize message for the new size to the renderer.
686 process_->sink().ClearMessages();
687 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
688 params.view_size = original_size.size();
689 host_->OnUpdateRect(params);
690 EXPECT_TRUE(host_->resize_ack_pending_);
691 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
692 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
694 // Send the resize ack for the latest size.
695 process_->sink().ClearMessages();
696 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
697 params.view_size = third_size.size();
698 host_->OnUpdateRect(params);
699 EXPECT_FALSE(host_->resize_ack_pending_);
700 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
701 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
703 // Now clearing the bounds should send out a notification but we shouldn't
704 // expect a resize ack (since the renderer won't ack empty sizes). The message
705 // should contain the new size (0x0) and not the previous one that we skipped
706 process_->sink().ClearMessages();
707 view_->set_bounds(gfx::Rect());
708 host_->WasResized();
709 EXPECT_FALSE(host_->resize_ack_pending_);
710 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
711 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
713 // Send a rect that has no area but has either width or height set.
714 process_->sink().ClearMessages();
715 view_->set_bounds(gfx::Rect(0, 0, 0, 30));
716 host_->WasResized();
717 EXPECT_FALSE(host_->resize_ack_pending_);
718 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
719 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
721 // Set the same size again. It should not be sent again.
722 process_->sink().ClearMessages();
723 host_->WasResized();
724 EXPECT_FALSE(host_->resize_ack_pending_);
725 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
726 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
728 // A different size should be sent again, however.
729 view_->set_bounds(gfx::Rect(0, 0, 0, 31));
730 host_->WasResized();
731 EXPECT_FALSE(host_->resize_ack_pending_);
732 EXPECT_EQ(gfx::Size(0, 31), host_->old_resize_params_->new_size);
733 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
736 // Test that a resize event is sent if WasResized() is called after a
737 // WebScreenInfo change.
738 TEST_F(RenderWidgetHostTest, ResizeScreenInfo) {
739 blink::WebScreenInfo screen_info;
740 screen_info.deviceScaleFactor = 1.f;
741 screen_info.rect = blink::WebRect(0, 0, 800, 600);
742 screen_info.availableRect = blink::WebRect(0, 0, 800, 600);
743 screen_info.orientationAngle = 0;
744 screen_info.orientationType = blink::WebScreenOrientationPortraitPrimary;
746 view_->SetScreenInfo(screen_info);
747 host_->WasResized();
748 EXPECT_FALSE(host_->resize_ack_pending_);
749 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
750 process_->sink().ClearMessages();
752 screen_info.orientationAngle = 180;
753 screen_info.orientationType = blink::WebScreenOrientationLandscapePrimary;
755 view_->SetScreenInfo(screen_info);
756 host_->WasResized();
757 EXPECT_FALSE(host_->resize_ack_pending_);
758 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
759 process_->sink().ClearMessages();
761 screen_info.deviceScaleFactor = 2.f;
763 view_->SetScreenInfo(screen_info);
764 host_->WasResized();
765 EXPECT_FALSE(host_->resize_ack_pending_);
766 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
767 process_->sink().ClearMessages();
769 // No screen change.
770 view_->SetScreenInfo(screen_info);
771 host_->WasResized();
772 EXPECT_FALSE(host_->resize_ack_pending_);
773 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
776 // Test for crbug.com/25097. If a renderer crashes between a resize and the
777 // corresponding update message, we must be sure to clear the resize ack logic.
778 TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
779 // Clear the first Resize message that carried screen info.
780 process_->sink().ClearMessages();
782 // Setting the bounds to a "real" rect should send out the notification.
783 gfx::Rect original_size(0, 0, 100, 100);
784 view_->set_bounds(original_size);
785 host_->WasResized();
786 EXPECT_TRUE(host_->resize_ack_pending_);
787 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
788 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
790 // Simulate a renderer crash before the update message. Ensure all the
791 // resize ack logic is cleared. Must clear the view first so it doesn't get
792 // deleted.
793 host_->SetView(NULL);
794 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
795 EXPECT_FALSE(host_->resize_ack_pending_);
796 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
798 // Reset the view so we can exit the test cleanly.
799 host_->SetView(view_.get());
802 // Unable to include render_widget_host_view_mac.h and compile.
803 #if !defined(OS_MACOSX)
804 // Tests setting background transparency.
805 TEST_F(RenderWidgetHostTest, Background) {
806 scoped_ptr<RenderWidgetHostViewBase> view;
807 #if defined(USE_AURA)
808 view.reset(new RenderWidgetHostViewAura(host_.get(), false));
809 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
810 view->InitAsChild(NULL);
811 #elif defined(OS_ANDROID)
812 view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
813 #endif
814 host_->SetView(view.get());
816 EXPECT_TRUE(view->GetBackgroundOpaque());
817 view->SetBackgroundColor(SK_ColorTRANSPARENT);
818 EXPECT_FALSE(view->GetBackgroundOpaque());
820 const IPC::Message* set_background =
821 process_->sink().GetUniqueMessageMatching(
822 ViewMsg_SetBackgroundOpaque::ID);
823 ASSERT_TRUE(set_background);
824 base::Tuple<bool> sent_background;
825 ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
826 EXPECT_FALSE(base::get<0>(sent_background));
828 #if defined(USE_AURA)
829 // See the comment above |InitAsChild(NULL)|.
830 host_->SetView(NULL);
831 static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
832 #endif
834 #endif
836 // Test that we don't paint when we're hidden, but we still send the ACK. Most
837 // of the rest of the painting is tested in the GetBackingStore* ones.
838 TEST_F(RenderWidgetHostTest, HiddenPaint) {
839 BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
840 // Hide the widget, it should have sent out a message to the renderer.
841 EXPECT_FALSE(host_->is_hidden_);
842 host_->WasHidden();
843 EXPECT_TRUE(host_->is_hidden_);
844 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID));
846 // Send it an update as from the renderer.
847 process_->sink().ClearMessages();
848 ViewHostMsg_UpdateRect_Params params;
849 params.view_size = gfx::Size(100, 100);
850 host_->OnUpdateRect(params);
852 // Now unhide.
853 process_->sink().ClearMessages();
854 host_->WasShown(ui::LatencyInfo());
855 EXPECT_FALSE(host_->is_hidden_);
857 // It should have sent out a restored message with a request to paint.
858 const IPC::Message* restored = process_->sink().GetUniqueMessageMatching(
859 ViewMsg_WasShown::ID);
860 ASSERT_TRUE(restored);
861 base::Tuple<bool, ui::LatencyInfo> needs_repaint;
862 ViewMsg_WasShown::Read(restored, &needs_repaint);
863 EXPECT_TRUE(base::get<0>(needs_repaint));
866 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
867 // Simulate a keyboard event.
868 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
870 // Make sure we sent the input event to the renderer.
871 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
872 InputMsg_HandleInputEvent::ID));
873 process_->sink().ClearMessages();
875 // Send the simulated response from the renderer back.
876 SendInputEventACK(WebInputEvent::RawKeyDown,
877 INPUT_EVENT_ACK_STATE_CONSUMED);
878 EXPECT_FALSE(delegate_->unhandled_keyboard_event_called());
881 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
882 // Simluate the situation that the browser handled the key down event during
883 // pre-handle phrase.
884 delegate_->set_prehandle_keyboard_event(true);
885 process_->sink().ClearMessages();
887 // Simulate a keyboard event.
888 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
890 EXPECT_TRUE(delegate_->prehandle_keyboard_event_called());
891 EXPECT_EQ(WebInputEvent::RawKeyDown,
892 delegate_->prehandle_keyboard_event_type());
894 // Make sure the RawKeyDown event is not sent to the renderer.
895 EXPECT_EQ(0U, process_->sink().message_count());
897 // The browser won't pre-handle a Char event.
898 delegate_->set_prehandle_keyboard_event(false);
900 // Forward the Char event.
901 SimulateKeyboardEvent(WebInputEvent::Char);
903 // Make sure the Char event is suppressed.
904 EXPECT_EQ(0U, process_->sink().message_count());
906 // Forward the KeyUp event.
907 SimulateKeyboardEvent(WebInputEvent::KeyUp);
909 // Make sure only KeyUp was sent to the renderer.
910 EXPECT_EQ(1U, process_->sink().message_count());
911 EXPECT_EQ(InputMsg_HandleInputEvent::ID,
912 process_->sink().GetMessageAt(0)->type());
913 process_->sink().ClearMessages();
915 // Send the simulated response from the renderer back.
916 SendInputEventACK(WebInputEvent::KeyUp,
917 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
919 EXPECT_TRUE(delegate_->unhandled_keyboard_event_called());
920 EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type());
923 TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
924 SimulateWheelEvent(-5, 0, 0, true);
926 // Make sure we sent the input event to the renderer.
927 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
928 InputMsg_HandleInputEvent::ID));
929 process_->sink().ClearMessages();
931 // Send the simulated response from the renderer back.
932 SendInputEventACK(WebInputEvent::MouseWheel,
933 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
934 EXPECT_TRUE(delegate_->handle_wheel_event_called());
935 EXPECT_EQ(1, view_->unhandled_wheel_event_count());
936 EXPECT_EQ(-5, view_->unhandled_wheel_event().deltaX);
939 TEST_F(RenderWidgetHostTest, HandleWheelEvent) {
940 // Indicate that we're going to handle this wheel event
941 delegate_->set_handle_wheel_event(true);
943 SimulateWheelEvent(-5, 0, 0, true);
945 // Make sure we sent the input event to the renderer.
946 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
947 InputMsg_HandleInputEvent::ID));
948 process_->sink().ClearMessages();
950 // Send the simulated response from the renderer back.
951 SendInputEventACK(WebInputEvent::MouseWheel,
952 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
954 // ensure the wheel event handler was invoked
955 EXPECT_TRUE(delegate_->handle_wheel_event_called());
957 // and that it suppressed the unhandled wheel event handler.
958 EXPECT_EQ(0, view_->unhandled_wheel_event_count());
961 TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
962 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap,
963 blink::WebGestureDeviceTouchscreen);
965 // Make sure we sent the input event to the renderer.
966 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
967 InputMsg_HandleInputEvent::ID));
968 process_->sink().ClearMessages();
970 // Send the simulated response from the renderer back.
971 SendInputEventACK(WebInputEvent::GestureTwoFingerTap,
972 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
973 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap, view_->gesture_event_type());
974 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, view_->ack_result());
977 // Test that the hang monitor timer expires properly if a new timer is started
978 // while one is in progress (see crbug.com/11007).
979 TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) {
980 // Start with a short timeout.
981 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
983 // Immediately try to add a long 30 second timeout.
984 EXPECT_FALSE(host_->unresponsive_timer_fired());
985 host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
987 // Wait long enough for first timeout and see if it fired.
988 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
989 FROM_HERE, base::MessageLoop::QuitClosure(),
990 TimeDelta::FromMilliseconds(10));
991 base::MessageLoop::current()->Run();
992 EXPECT_TRUE(host_->unresponsive_timer_fired());
995 // Test that the hang monitor timer expires properly if it is started, stopped,
996 // and then started again.
997 TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
998 // Start with a short timeout, then stop it.
999 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1000 host_->StopHangMonitorTimeout();
1002 // Start it again to ensure it still works.
1003 EXPECT_FALSE(host_->unresponsive_timer_fired());
1004 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1006 // Wait long enough for first timeout and see if it fired.
1007 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1008 FROM_HERE, base::MessageLoop::QuitClosure(),
1009 TimeDelta::FromMilliseconds(40));
1010 base::MessageLoop::current()->Run();
1011 EXPECT_TRUE(host_->unresponsive_timer_fired());
1014 // Test that the hang monitor timer expires properly if it is started, then
1015 // updated to a shorter duration.
1016 TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) {
1017 // Start with a timeout.
1018 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
1020 // Start it again with shorter delay.
1021 EXPECT_FALSE(host_->unresponsive_timer_fired());
1022 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
1024 // Wait long enough for the second timeout and see if it fired.
1025 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1026 FROM_HERE, base::MessageLoop::QuitClosure(),
1027 TimeDelta::FromMilliseconds(25));
1028 base::MessageLoop::current()->Run();
1029 EXPECT_TRUE(host_->unresponsive_timer_fired());
1032 // Test that the hang monitor timer is effectively disabled when the widget is
1033 // hidden.
1034 TEST_F(RenderWidgetHostTest, HangMonitorTimeoutDisabledForInputWhenHidden) {
1035 host_->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(1));
1036 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1038 // Hiding the widget should deactivate the timeout.
1039 host_->WasHidden();
1041 // The timeout should not fire.
1042 EXPECT_FALSE(host_->unresponsive_timer_fired());
1043 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1044 FROM_HERE, base::MessageLoop::QuitClosure(),
1045 TimeDelta::FromMicroseconds(2));
1046 base::MessageLoop::current()->Run();
1047 EXPECT_FALSE(host_->unresponsive_timer_fired());
1049 // The timeout should never reactivate while hidden.
1050 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1051 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1052 FROM_HERE, base::MessageLoop::QuitClosure(),
1053 TimeDelta::FromMicroseconds(2));
1054 base::MessageLoop::current()->Run();
1055 EXPECT_FALSE(host_->unresponsive_timer_fired());
1057 // Showing the widget should restore the timeout, as the events have
1058 // not yet been ack'ed.
1059 host_->WasShown(ui::LatencyInfo());
1060 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1061 FROM_HERE, base::MessageLoop::QuitClosure(),
1062 TimeDelta::FromMicroseconds(2));
1063 base::MessageLoop::current()->Run();
1064 EXPECT_TRUE(host_->unresponsive_timer_fired());
1067 // Test that the hang monitor catches two input events but only one ack.
1068 // This can happen if the second input event causes the renderer to hang.
1069 // This test will catch a regression of crbug.com/111185.
1070 TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
1071 // Configure the host to wait 10ms before considering
1072 // the renderer hung.
1073 host_->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(10));
1075 // Send two events but only one ack.
1076 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1077 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1078 SendInputEventACK(WebInputEvent::RawKeyDown,
1079 INPUT_EVENT_ACK_STATE_CONSUMED);
1081 // Wait long enough for first timeout and see if it fired.
1082 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1083 FROM_HERE, base::MessageLoop::QuitClosure(),
1084 TimeDelta::FromMicroseconds(20));
1085 base::MessageLoop::current()->Run();
1086 EXPECT_TRUE(host_->unresponsive_timer_fired());
1089 std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
1090 std::string result;
1091 for (size_t i = 0; i < process->sink().message_count(); ++i) {
1092 const IPC::Message *message = process->sink().GetMessageAt(i);
1093 EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
1094 InputMsg_HandleInputEvent::Param params;
1095 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1096 const WebInputEvent* event = base::get<0>(params);
1097 if (i != 0)
1098 result += " ";
1099 result += WebInputEventTraits::GetName(event->type);
1101 process->sink().ClearMessages();
1102 return result;
1105 TEST_F(RenderWidgetHostTest, TouchEmulator) {
1106 simulated_event_time_delta_seconds_ = 0.1;
1107 // Immediately ack all touches instead of sending them to the renderer.
1108 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1109 host_->SetTouchEventEmulationEnabled(
1110 true, ui::GestureProviderConfigType::GENERIC_MOBILE);
1111 process_->sink().ClearMessages();
1112 view_->set_bounds(gfx::Rect(0, 0, 400, 200));
1113 view_->Show();
1115 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1116 EXPECT_EQ(0U, process_->sink().message_count());
1118 // Mouse press becomes touch start which in turn becomes tap.
1119 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1120 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1121 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1123 // Mouse drag generates touch move, cancels tap and starts scroll.
1124 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1125 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1126 EXPECT_EQ(
1127 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1128 GetInputMessageTypes(process_));
1129 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1130 INPUT_EVENT_ACK_STATE_CONSUMED);
1131 EXPECT_EQ(0U, process_->sink().message_count());
1133 // Mouse drag with shift becomes pinch.
1134 SimulateMouseEvent(
1135 WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true);
1136 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1137 EXPECT_EQ("GesturePinchBegin",
1138 GetInputMessageTypes(process_));
1139 EXPECT_EQ(0U, process_->sink().message_count());
1141 SimulateMouseEvent(
1142 WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true);
1143 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1144 EXPECT_EQ("GesturePinchUpdate",
1145 GetInputMessageTypes(process_));
1146 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1147 INPUT_EVENT_ACK_STATE_CONSUMED);
1148 EXPECT_EQ(0U, process_->sink().message_count());
1150 // Mouse drag without shift becomes scroll again.
1151 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true);
1152 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1153 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1154 GetInputMessageTypes(process_));
1155 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1156 INPUT_EVENT_ACK_STATE_CONSUMED);
1157 EXPECT_EQ(0U, process_->sink().message_count());
1159 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true);
1160 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1161 EXPECT_EQ("GestureScrollUpdate",
1162 GetInputMessageTypes(process_));
1163 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1164 INPUT_EVENT_ACK_STATE_CONSUMED);
1165 EXPECT_EQ(0U, process_->sink().message_count());
1167 SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true);
1168 EXPECT_EQ(WebInputEvent::TouchEnd, host_->acked_touch_event_type());
1169 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1170 EXPECT_EQ(0U, process_->sink().message_count());
1172 // Mouse move does nothing.
1173 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false);
1174 EXPECT_EQ(0U, process_->sink().message_count());
1176 // Another mouse down continues scroll.
1177 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true);
1178 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1179 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1180 EXPECT_EQ(0U, process_->sink().message_count());
1182 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true);
1183 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1184 EXPECT_EQ(
1185 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1186 GetInputMessageTypes(process_));
1187 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1188 INPUT_EVENT_ACK_STATE_CONSUMED);
1189 EXPECT_EQ(0U, process_->sink().message_count());
1191 // Another pinch.
1192 SimulateMouseEvent(
1193 WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true);
1194 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1195 EXPECT_EQ("GesturePinchBegin",
1196 GetInputMessageTypes(process_));
1197 EXPECT_EQ(0U, process_->sink().message_count());
1199 SimulateMouseEvent(
1200 WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true);
1201 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1202 EXPECT_EQ("GesturePinchUpdate",
1203 GetInputMessageTypes(process_));
1204 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1205 INPUT_EVENT_ACK_STATE_CONSUMED);
1206 EXPECT_EQ(0U, process_->sink().message_count());
1208 // Turn off emulation during a pinch.
1209 host_->SetTouchEventEmulationEnabled(
1210 false, ui::GestureProviderConfigType::GENERIC_MOBILE);
1211 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1212 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1213 GetInputMessageTypes(process_));
1214 EXPECT_EQ(0U, process_->sink().message_count());
1216 // Mouse event should pass untouched.
1217 SimulateMouseEvent(
1218 WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true);
1219 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_));
1220 SendInputEventACK(WebInputEvent::MouseMove,
1221 INPUT_EVENT_ACK_STATE_CONSUMED);
1222 EXPECT_EQ(0U, process_->sink().message_count());
1224 // Turn on emulation.
1225 host_->SetTouchEventEmulationEnabled(
1226 true, ui::GestureProviderConfigType::GENERIC_MOBILE);
1227 EXPECT_EQ(0U, process_->sink().message_count());
1229 // Another touch.
1230 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1231 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1232 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1233 EXPECT_EQ(0U, process_->sink().message_count());
1235 // Scroll.
1236 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1237 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1238 EXPECT_EQ(
1239 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1240 GetInputMessageTypes(process_));
1241 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1242 INPUT_EVENT_ACK_STATE_CONSUMED);
1244 // Turn off emulation during a scroll.
1245 host_->SetTouchEventEmulationEnabled(
1246 false, ui::GestureProviderConfigType::GENERIC_MOBILE);
1247 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1249 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1250 EXPECT_EQ(0U, process_->sink().message_count());
1253 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1254 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1255 host_->SetupForInputRouterTest(); \
1256 host_->INPUTMSG(); \
1257 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1260 TEST_InputRouterRoutes_NOARGS(Focus);
1261 TEST_InputRouterRoutes_NOARGS(Blur);
1262 TEST_InputRouterRoutes_NOARGS(LostCapture);
1264 #undef TEST_InputRouterRoutes_NOARGS
1266 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1267 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1268 host_->SetupForInputRouterTest(); \
1269 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1270 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1273 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo);
1274 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo);
1275 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut);
1276 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy);
1277 #if defined(OS_MACOSX)
1278 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard);
1279 #endif
1280 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste);
1281 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle);
1282 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete);
1283 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll);
1284 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect);
1286 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1288 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplace) {
1289 host_->SetupForInputRouterTest();
1290 host_->Send(new InputMsg_Replace(host_->GetRoutingID(), base::string16()));
1291 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1294 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplaceMisspelling) {
1295 host_->SetupForInputRouterTest();
1296 host_->Send(new InputMsg_ReplaceMisspelling(host_->GetRoutingID(),
1297 base::string16()));
1298 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1301 TEST_F(RenderWidgetHostTest, IgnoreInputEvent) {
1302 host_->SetupForInputRouterTest();
1304 host_->SetIgnoreInputEvents(true);
1306 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1307 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1309 SimulateMouseEvent(WebInputEvent::MouseMove);
1310 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1312 SimulateWheelEvent(0, 100, 0, true);
1313 EXPECT_FALSE(host_->mock_input_router()->sent_wheel_event_);
1315 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1316 blink::WebGestureDeviceTouchpad);
1317 EXPECT_FALSE(host_->mock_input_router()->sent_gesture_event_);
1319 PressTouchPoint(100, 100);
1320 SendTouchEvent();
1321 EXPECT_FALSE(host_->mock_input_router()->send_touch_event_not_cancelled_);
1324 TEST_F(RenderWidgetHostTest, KeyboardListenerIgnoresEvent) {
1325 host_->SetupForInputRouterTest();
1326 host_->AddKeyPressEventCallback(
1327 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1328 base::Unretained(this)));
1329 handle_key_press_event_ = false;
1330 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1332 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1335 TEST_F(RenderWidgetHostTest, KeyboardListenerSuppressFollowingEvents) {
1336 host_->SetupForInputRouterTest();
1338 host_->AddKeyPressEventCallback(
1339 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1340 base::Unretained(this)));
1342 // The callback handles the first event
1343 handle_key_press_event_ = true;
1344 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1346 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1348 // Following Char events should be suppressed
1349 handle_key_press_event_ = false;
1350 SimulateKeyboardEvent(WebInputEvent::Char);
1351 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1352 SimulateKeyboardEvent(WebInputEvent::Char);
1353 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1355 // Sending RawKeyDown event should stop suppression
1356 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1357 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1359 host_->mock_input_router()->sent_keyboard_event_ = false;
1360 SimulateKeyboardEvent(WebInputEvent::Char);
1361 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1364 TEST_F(RenderWidgetHostTest, MouseEventCallbackCanHandleEvent) {
1365 host_->SetupForInputRouterTest();
1367 host_->AddMouseEventCallback(
1368 base::Bind(&RenderWidgetHostTest::MouseEventCallback,
1369 base::Unretained(this)));
1371 handle_mouse_event_ = true;
1372 SimulateMouseEvent(WebInputEvent::MouseDown);
1374 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1376 handle_mouse_event_ = false;
1377 SimulateMouseEvent(WebInputEvent::MouseDown);
1379 EXPECT_TRUE(host_->mock_input_router()->sent_mouse_event_);
1382 TEST_F(RenderWidgetHostTest, InputRouterReceivesHandleInputEvent_ACK) {
1383 host_->SetupForInputRouterTest();
1385 SendInputEventACK(WebInputEvent::RawKeyDown,
1386 INPUT_EVENT_ACK_STATE_CONSUMED);
1388 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1391 TEST_F(RenderWidgetHostTest, InputRouterReceivesMoveCaret_ACK) {
1392 host_->SetupForInputRouterTest();
1394 host_->OnMessageReceived(InputHostMsg_MoveCaret_ACK(0));
1396 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1399 TEST_F(RenderWidgetHostTest, InputRouterReceivesSelectRange_ACK) {
1400 host_->SetupForInputRouterTest();
1402 host_->OnMessageReceived(InputHostMsg_SelectRange_ACK(0));
1404 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1407 TEST_F(RenderWidgetHostTest, InputRouterReceivesHasTouchEventHandlers) {
1408 host_->SetupForInputRouterTest();
1410 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1412 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1415 ui::LatencyInfo GetLatencyInfoFromInputEvent(RenderWidgetHostProcess* process) {
1416 const IPC::Message* message = process->sink().GetUniqueMessageMatching(
1417 InputMsg_HandleInputEvent::ID);
1418 EXPECT_TRUE(message);
1419 InputMsg_HandleInputEvent::Param params;
1420 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1421 process->sink().ClearMessages();
1422 return base::get<1>(params);
1425 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process,
1426 int64 component_id,
1427 WebInputEvent::Type input_type) {
1428 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process);
1429 EXPECT_TRUE(latency_info.FindLatency(
1430 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
1431 component_id,
1432 NULL));
1435 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1436 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1437 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1438 // event's LatencyInfo.
1439 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
1440 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1441 process_->sink().ClearMessages();
1443 // Tests RWHI::ForwardWheelEvent().
1444 SimulateWheelEvent(-5, 0, 0, true);
1445 CheckLatencyInfoComponentInMessage(
1446 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1447 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1449 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1450 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1451 CheckLatencyInfoComponentInMessage(
1452 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1453 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1455 // Tests RWHI::ForwardMouseEvent().
1456 SimulateMouseEvent(WebInputEvent::MouseMove);
1457 CheckLatencyInfoComponentInMessage(
1458 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1459 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1461 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1462 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove,
1463 ui::LatencyInfo());
1464 CheckLatencyInfoComponentInMessage(
1465 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1466 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1468 // Tests RWHI::ForwardGestureEvent().
1469 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1470 blink::WebGestureDeviceTouchscreen);
1471 CheckLatencyInfoComponentInMessage(
1472 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin);
1474 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1475 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate,
1476 blink::WebGestureDeviceTouchscreen,
1477 ui::LatencyInfo());
1478 CheckLatencyInfoComponentInMessage(
1479 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate);
1480 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1481 INPUT_EVENT_ACK_STATE_CONSUMED);
1483 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1484 PressTouchPoint(0, 1);
1485 uint32 touch_event_id = SendTouchEvent();
1486 InputEventAck ack(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
1487 touch_event_id);
1488 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
1489 CheckLatencyInfoComponentInMessage(
1490 process_, GetLatencyComponentId(), WebInputEvent::TouchStart);
1493 TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) {
1494 // RendererExited will delete the view.
1495 host_->SetView(new TestView(host_.get()));
1496 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1498 // Make sure the input router is in a fresh state.
1499 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1502 // Regression test for http://crbug.com/401859.
1503 TEST_F(RenderWidgetHostTest, RendererExitedResetsIsHidden) {
1504 // RendererExited will delete the view.
1505 host_->SetView(new TestView(host_.get()));
1506 host_->WasHidden();
1508 ASSERT_TRUE(host_->is_hidden());
1509 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1510 ASSERT_FALSE(host_->is_hidden());
1512 // Make sure the input router is in a fresh state.
1513 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1516 TEST_F(RenderWidgetHostTest, ResizeParams) {
1517 gfx::Rect bounds(0, 0, 100, 100);
1518 gfx::Size physical_backing_size(40, 50);
1519 view_->set_bounds(bounds);
1520 view_->SetMockPhysicalBackingSize(physical_backing_size);
1522 ViewMsg_Resize_Params resize_params;
1523 host_->GetResizeParams(&resize_params);
1524 EXPECT_EQ(bounds.size(), resize_params.new_size);
1525 EXPECT_EQ(physical_backing_size, resize_params.physical_backing_size);
1528 class RenderWidgetHostInitialSizeTest : public RenderWidgetHostTest {
1529 public:
1530 RenderWidgetHostInitialSizeTest()
1531 : RenderWidgetHostTest(), initial_size_(200, 100) {}
1533 void ConfigureView(TestView* view) override {
1534 view->set_bounds(gfx::Rect(initial_size_));
1537 protected:
1538 gfx::Size initial_size_;
1541 TEST_F(RenderWidgetHostInitialSizeTest, InitialSize) {
1542 // Having an initial size set means that the size information had been sent
1543 // with the reqiest to new up the RenderView and so subsequent WasResized
1544 // calls should not result in new IPC (unless the size has actually changed).
1545 host_->WasResized();
1546 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
1547 EXPECT_EQ(initial_size_, host_->old_resize_params_->new_size);
1548 EXPECT_TRUE(host_->resize_ack_pending_);
1551 } // namespace content