Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_unittest.cc
blob9d3f0dc026a60ce528671ddb8daf949281f788f5
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/env.h"
43 #include "ui/aura/test/test_screen.h"
44 #include "ui/events/event.h"
45 #endif
47 using base::TimeDelta;
48 using blink::WebGestureDevice;
49 using blink::WebGestureEvent;
50 using blink::WebInputEvent;
51 using blink::WebKeyboardEvent;
52 using blink::WebMouseEvent;
53 using blink::WebMouseWheelEvent;
54 using blink::WebTouchEvent;
55 using blink::WebTouchPoint;
57 namespace content {
59 // MockInputRouter -------------------------------------------------------------
61 class MockInputRouter : public InputRouter {
62 public:
63 explicit MockInputRouter(InputRouterClient* client)
64 : send_event_called_(false),
65 sent_mouse_event_(false),
66 sent_wheel_event_(false),
67 sent_keyboard_event_(false),
68 sent_gesture_event_(false),
69 send_touch_event_not_cancelled_(false),
70 message_received_(false),
71 client_(client) {
73 ~MockInputRouter() override {}
75 // InputRouter
76 bool SendInput(scoped_ptr<IPC::Message> message) override {
77 send_event_called_ = true;
78 return true;
80 void SendMouseEvent(const MouseEventWithLatencyInfo& mouse_event) override {
81 sent_mouse_event_ = true;
83 void SendWheelEvent(
84 const MouseWheelEventWithLatencyInfo& wheel_event) override {
85 sent_wheel_event_ = true;
87 void SendKeyboardEvent(const NativeWebKeyboardEvent& key_event,
88 const ui::LatencyInfo& latency_info,
89 bool is_shortcut) override {
90 sent_keyboard_event_ = true;
92 void SendGestureEvent(
93 const GestureEventWithLatencyInfo& gesture_event) override {
94 sent_gesture_event_ = true;
96 void SendTouchEvent(const TouchEventWithLatencyInfo& touch_event) override {
97 send_touch_event_not_cancelled_ =
98 client_->FilterInputEvent(touch_event.event, touch_event.latency) ==
99 INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
101 const NativeWebKeyboardEvent* GetLastKeyboardEvent() const override {
102 NOTREACHED();
103 return NULL;
105 void NotifySiteIsMobileOptimized(bool is_mobile_optimized) override {}
106 void RequestNotificationWhenFlushed() override {}
107 bool HasPendingEvents() const override { return false; }
109 // IPC::Listener
110 bool OnMessageReceived(const IPC::Message& message) override {
111 message_received_ = true;
112 return false;
115 bool send_event_called_;
116 bool sent_mouse_event_;
117 bool sent_wheel_event_;
118 bool sent_keyboard_event_;
119 bool sent_gesture_event_;
120 bool send_touch_event_not_cancelled_;
121 bool message_received_;
123 private:
124 InputRouterClient* client_;
126 DISALLOW_COPY_AND_ASSIGN(MockInputRouter);
129 // MockRenderWidgetHost ----------------------------------------------------
131 class MockRenderWidgetHost : public RenderWidgetHostImpl {
132 public:
133 MockRenderWidgetHost(
134 RenderWidgetHostDelegate* delegate,
135 RenderProcessHost* process,
136 int routing_id)
137 : RenderWidgetHostImpl(delegate, process, routing_id, false),
138 unresponsive_timer_fired_(false) {
139 acked_touch_event_type_ = blink::WebInputEvent::Undefined;
142 // Allow poking at a few private members.
143 using RenderWidgetHostImpl::GetResizeParams;
144 using RenderWidgetHostImpl::OnUpdateRect;
145 using RenderWidgetHostImpl::RendererExited;
146 using RenderWidgetHostImpl::SetInitialRenderSizeParams;
147 using RenderWidgetHostImpl::old_resize_params_;
148 using RenderWidgetHostImpl::is_hidden_;
149 using RenderWidgetHostImpl::resize_ack_pending_;
150 using RenderWidgetHostImpl::input_router_;
152 void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
153 InputEventAckState ack_result) override {
154 // Sniff touch acks.
155 acked_touch_event_type_ = event.event.type;
156 RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
159 bool unresponsive_timer_fired() const {
160 return unresponsive_timer_fired_;
163 void DisableGestureDebounce() {
164 input_router_.reset(new InputRouterImpl(
165 process_, this, this, routing_id_, InputRouterImpl::Config()));
168 WebInputEvent::Type acked_touch_event_type() const {
169 return acked_touch_event_type_;
172 void SetupForInputRouterTest() {
173 input_router_.reset(new MockInputRouter(this));
176 MockInputRouter* mock_input_router() {
177 return static_cast<MockInputRouter*>(input_router_.get());
180 protected:
181 void NotifyRendererUnresponsive() override {
182 unresponsive_timer_fired_ = true;
185 bool unresponsive_timer_fired_;
186 WebInputEvent::Type acked_touch_event_type_;
188 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
191 namespace {
193 // RenderWidgetHostProcess -----------------------------------------------------
195 class RenderWidgetHostProcess : public MockRenderProcessHost {
196 public:
197 explicit RenderWidgetHostProcess(BrowserContext* browser_context)
198 : MockRenderProcessHost(browser_context) {
200 ~RenderWidgetHostProcess() override {}
202 bool HasConnection() const override { return true; }
204 protected:
205 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess);
208 // TestView --------------------------------------------------------------------
210 // This test view allows us to specify the size, and keep track of acked
211 // touch-events.
212 class TestView : public TestRenderWidgetHostView {
213 public:
214 explicit TestView(RenderWidgetHostImpl* rwh)
215 : TestRenderWidgetHostView(rwh),
216 unhandled_wheel_event_count_(0),
217 acked_event_count_(0),
218 gesture_event_type_(-1),
219 use_fake_physical_backing_size_(false),
220 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
223 // Sets the bounds returned by GetViewBounds.
224 void set_bounds(const gfx::Rect& bounds) {
225 bounds_ = bounds;
228 const WebTouchEvent& acked_event() const { return acked_event_; }
229 int acked_event_count() const { return acked_event_count_; }
230 void ClearAckedEvent() {
231 acked_event_.type = blink::WebInputEvent::Undefined;
232 acked_event_count_ = 0;
235 const WebMouseWheelEvent& unhandled_wheel_event() const {
236 return unhandled_wheel_event_;
238 int unhandled_wheel_event_count() const {
239 return unhandled_wheel_event_count_;
241 int gesture_event_type() const { return gesture_event_type_; }
242 InputEventAckState ack_result() const { return ack_result_; }
244 void SetMockPhysicalBackingSize(const gfx::Size& mock_physical_backing_size) {
245 use_fake_physical_backing_size_ = true;
246 mock_physical_backing_size_ = mock_physical_backing_size;
248 void ClearMockPhysicalBackingSize() {
249 use_fake_physical_backing_size_ = false;
251 void SetScreenInfo(const blink::WebScreenInfo& screen_info) {
252 screen_info_ = screen_info;
255 // RenderWidgetHostView override.
256 gfx::Rect GetViewBounds() const override { return bounds_; }
257 void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
258 InputEventAckState ack_result) override {
259 acked_event_ = touch.event;
260 ++acked_event_count_;
262 void WheelEventAck(const WebMouseWheelEvent& event,
263 InputEventAckState ack_result) override {
264 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
265 return;
266 unhandled_wheel_event_count_++;
267 unhandled_wheel_event_ = event;
269 void GestureEventAck(const WebGestureEvent& event,
270 InputEventAckState ack_result) override {
271 gesture_event_type_ = event.type;
272 ack_result_ = ack_result;
274 gfx::Size GetPhysicalBackingSize() const override {
275 if (use_fake_physical_backing_size_)
276 return mock_physical_backing_size_;
277 return TestRenderWidgetHostView::GetPhysicalBackingSize();
279 void GetScreenInfo(blink::WebScreenInfo* screen_info) override {
280 *screen_info = screen_info_;
282 #if defined(USE_AURA)
283 ~TestView() override {
284 // Simulate the mouse exit event dispatched when an aura window is
285 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
286 // into WebInputEvent::MouseMove.)
287 rwh_->input_router()->SendMouseEvent(
288 MouseEventWithLatencyInfo(
289 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove),
290 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 aura::Env::CreateInstance(true);
428 screen_.reset(aura::TestScreen::Create(gfx::Size()));
429 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
430 #endif
431 host_.reset(
432 new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
433 view_.reset(new TestView(host_.get()));
434 ConfigureView(view_.get());
435 host_->SetView(view_.get());
436 SetInitialRenderSizeParams();
437 host_->Init();
438 host_->DisableGestureDebounce();
441 void TearDown() override {
442 view_.reset();
443 host_.reset();
444 delegate_.reset();
445 process_ = NULL;
446 browser_context_.reset();
448 #if defined(USE_AURA)
449 aura::Env::DeleteInstance();
450 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, nullptr);
451 screen_.reset();
452 #endif
453 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
454 if (IsDelegatedRendererEnabled())
455 ImageTransportFactory::Terminate();
456 #endif
458 // Process all pending tasks to avoid leaks.
459 base::MessageLoop::current()->RunUntilIdle();
462 void SetInitialRenderSizeParams() {
463 ViewMsg_Resize_Params render_size_params;
464 host_->GetResizeParams(&render_size_params);
465 host_->SetInitialRenderSizeParams(render_size_params);
468 virtual void ConfigureView(TestView* view) {
471 int64 GetLatencyComponentId() {
472 return host_->GetLatencyComponentId();
475 void SendInputEventACK(WebInputEvent::Type type,
476 InputEventAckState ack_result) {
477 DCHECK(!WebInputEvent::isTouchEventType(type));
478 InputEventAck ack(type, ack_result);
479 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
482 double GetNextSimulatedEventTimeSeconds() {
483 last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_;
484 return last_simulated_event_time_seconds_;
487 void SimulateKeyboardEvent(WebInputEvent::Type type) {
488 SimulateKeyboardEvent(type, 0);
491 void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) {
492 WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
493 event.modifiers = modifiers;
494 NativeWebKeyboardEvent native_event;
495 memcpy(&native_event, &event, sizeof(event));
496 host_->ForwardKeyboardEvent(native_event);
499 void SimulateMouseEvent(WebInputEvent::Type type) {
500 host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type));
503 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type,
504 const ui::LatencyInfo& ui_latency) {
505 host_->ForwardMouseEventWithLatencyInfo(
506 SyntheticWebMouseEventBuilder::Build(type),
507 ui_latency);
510 void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
511 host_->ForwardWheelEvent(
512 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
515 void SimulateWheelEventWithLatencyInfo(float dX,
516 float dY,
517 int modifiers,
518 bool precise,
519 const ui::LatencyInfo& ui_latency) {
520 host_->ForwardWheelEventWithLatencyInfo(
521 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
522 ui_latency);
525 void SimulateMouseMove(int x, int y, int modifiers) {
526 SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false);
529 void SimulateMouseEvent(
530 WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) {
531 WebMouseEvent event =
532 SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers);
533 if (pressed)
534 event.button = WebMouseEvent::ButtonLeft;
535 event.timeStampSeconds = GetNextSimulatedEventTimeSeconds();
536 host_->ForwardMouseEvent(event);
539 // Inject simple synthetic WebGestureEvent instances.
540 void SimulateGestureEvent(WebInputEvent::Type type,
541 WebGestureDevice sourceDevice) {
542 host_->ForwardGestureEvent(
543 SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
546 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type,
547 WebGestureDevice sourceDevice,
548 const ui::LatencyInfo& ui_latency) {
549 host_->ForwardGestureEventWithLatencyInfo(
550 SyntheticWebGestureEventBuilder::Build(type, sourceDevice),
551 ui_latency);
554 // Set the timestamp for the touch-event.
555 void SetTouchTimestamp(base::TimeDelta timestamp) {
556 touch_event_.SetTimestamp(timestamp);
559 // Sends a touch event (irrespective of whether the page has a touch-event
560 // handler or not).
561 uint32 SendTouchEvent() {
562 uint32 touch_event_id = touch_event_.uniqueTouchEventId;
563 host_->ForwardTouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo());
565 touch_event_.ResetPoints();
566 return touch_event_id;
569 int PressTouchPoint(int x, int y) {
570 return touch_event_.PressPoint(x, y);
573 void MoveTouchPoint(int index, int x, int y) {
574 touch_event_.MovePoint(index, x, y);
577 void ReleaseTouchPoint(int index) {
578 touch_event_.ReleasePoint(index);
581 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
582 base::PickleIterator iter(message);
583 const char* data;
584 int data_length;
585 if (!iter.ReadData(&data, &data_length))
586 return NULL;
587 return reinterpret_cast<const WebInputEvent*>(data);
590 base::MessageLoopForUI message_loop_;
592 scoped_ptr<TestBrowserContext> browser_context_;
593 RenderWidgetHostProcess* process_; // Deleted automatically by the widget.
594 scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
595 scoped_ptr<MockRenderWidgetHost> host_;
596 scoped_ptr<TestView> view_;
597 scoped_ptr<gfx::Screen> screen_;
598 bool handle_key_press_event_;
599 bool handle_mouse_event_;
600 double last_simulated_event_time_seconds_;
601 double simulated_event_time_delta_seconds_;
603 private:
604 SyntheticWebTouchEvent touch_event_;
606 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest);
609 #if GTEST_HAS_PARAM_TEST
610 // RenderWidgetHostWithSourceTest ----------------------------------------------
612 // This is for tests that are to be run for all source devices.
613 class RenderWidgetHostWithSourceTest
614 : public RenderWidgetHostTest,
615 public testing::WithParamInterface<WebGestureDevice> {};
616 #endif // GTEST_HAS_PARAM_TEST
618 } // namespace
620 // -----------------------------------------------------------------------------
622 TEST_F(RenderWidgetHostTest, Resize) {
623 // The initial bounds is the empty rect, so setting it to the same thing
624 // shouldn't send the resize message.
625 view_->set_bounds(gfx::Rect());
626 host_->WasResized();
627 EXPECT_FALSE(host_->resize_ack_pending_);
628 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
630 // No resize ack if the physical backing gets set, but the view bounds are
631 // zero.
632 view_->SetMockPhysicalBackingSize(gfx::Size(200, 200));
633 host_->WasResized();
634 EXPECT_FALSE(host_->resize_ack_pending_);
636 // Setting the view bounds to nonzero should send out the notification.
637 // but should not expect ack for empty physical backing size.
638 gfx::Rect original_size(0, 0, 100, 100);
639 process_->sink().ClearMessages();
640 view_->set_bounds(original_size);
641 view_->SetMockPhysicalBackingSize(gfx::Size());
642 host_->WasResized();
643 EXPECT_FALSE(host_->resize_ack_pending_);
644 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
645 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
647 // Setting the bounds and physical backing size to nonzero should send out
648 // the notification and expect an ack.
649 process_->sink().ClearMessages();
650 view_->ClearMockPhysicalBackingSize();
651 host_->WasResized();
652 EXPECT_TRUE(host_->resize_ack_pending_);
653 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
654 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
655 ViewHostMsg_UpdateRect_Params params;
656 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
657 params.view_size = original_size.size();
658 host_->OnUpdateRect(params);
659 EXPECT_FALSE(host_->resize_ack_pending_);
661 // Send out a update that's not a resize ack after setting resize ack pending
662 // flag. This should not clean the resize ack pending flag.
663 process_->sink().ClearMessages();
664 gfx::Rect second_size(0, 0, 110, 110);
665 EXPECT_FALSE(host_->resize_ack_pending_);
666 view_->set_bounds(second_size);
667 host_->WasResized();
668 EXPECT_TRUE(host_->resize_ack_pending_);
669 params.flags = 0;
670 params.view_size = gfx::Size(100, 100);
671 host_->OnUpdateRect(params);
672 EXPECT_TRUE(host_->resize_ack_pending_);
673 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
675 // Sending out a new notification should NOT send out a new IPC message since
676 // a resize ACK is pending.
677 gfx::Rect third_size(0, 0, 120, 120);
678 process_->sink().ClearMessages();
679 view_->set_bounds(third_size);
680 host_->WasResized();
681 EXPECT_TRUE(host_->resize_ack_pending_);
682 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
683 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
685 // Send a update that's a resize ack, but for the original_size we sent. Since
686 // this isn't the second_size, the message handler should immediately send
687 // a new resize message for the new size to the renderer.
688 process_->sink().ClearMessages();
689 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
690 params.view_size = original_size.size();
691 host_->OnUpdateRect(params);
692 EXPECT_TRUE(host_->resize_ack_pending_);
693 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
694 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
696 // Send the resize ack for the latest size.
697 process_->sink().ClearMessages();
698 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
699 params.view_size = third_size.size();
700 host_->OnUpdateRect(params);
701 EXPECT_FALSE(host_->resize_ack_pending_);
702 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
703 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
705 // Now clearing the bounds should send out a notification but we shouldn't
706 // expect a resize ack (since the renderer won't ack empty sizes). The message
707 // should contain the new size (0x0) and not the previous one that we skipped
708 process_->sink().ClearMessages();
709 view_->set_bounds(gfx::Rect());
710 host_->WasResized();
711 EXPECT_FALSE(host_->resize_ack_pending_);
712 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
713 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
715 // Send a rect that has no area but has either width or height set.
716 process_->sink().ClearMessages();
717 view_->set_bounds(gfx::Rect(0, 0, 0, 30));
718 host_->WasResized();
719 EXPECT_FALSE(host_->resize_ack_pending_);
720 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
721 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
723 // Set the same size again. It should not be sent again.
724 process_->sink().ClearMessages();
725 host_->WasResized();
726 EXPECT_FALSE(host_->resize_ack_pending_);
727 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
728 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
730 // A different size should be sent again, however.
731 view_->set_bounds(gfx::Rect(0, 0, 0, 31));
732 host_->WasResized();
733 EXPECT_FALSE(host_->resize_ack_pending_);
734 EXPECT_EQ(gfx::Size(0, 31), host_->old_resize_params_->new_size);
735 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
738 // Test that a resize event is sent if WasResized() is called after a
739 // WebScreenInfo change.
740 TEST_F(RenderWidgetHostTest, ResizeScreenInfo) {
741 blink::WebScreenInfo screen_info;
742 screen_info.deviceScaleFactor = 1.f;
743 screen_info.rect = blink::WebRect(0, 0, 800, 600);
744 screen_info.availableRect = blink::WebRect(0, 0, 800, 600);
745 screen_info.orientationAngle = 0;
746 screen_info.orientationType = blink::WebScreenOrientationPortraitPrimary;
748 view_->SetScreenInfo(screen_info);
749 host_->WasResized();
750 EXPECT_FALSE(host_->resize_ack_pending_);
751 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
752 process_->sink().ClearMessages();
754 screen_info.orientationAngle = 180;
755 screen_info.orientationType = blink::WebScreenOrientationLandscapePrimary;
757 view_->SetScreenInfo(screen_info);
758 host_->WasResized();
759 EXPECT_FALSE(host_->resize_ack_pending_);
760 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
761 process_->sink().ClearMessages();
763 screen_info.deviceScaleFactor = 2.f;
765 view_->SetScreenInfo(screen_info);
766 host_->WasResized();
767 EXPECT_FALSE(host_->resize_ack_pending_);
768 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
769 process_->sink().ClearMessages();
771 // No screen change.
772 view_->SetScreenInfo(screen_info);
773 host_->WasResized();
774 EXPECT_FALSE(host_->resize_ack_pending_);
775 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
778 // Test for crbug.com/25097. If a renderer crashes between a resize and the
779 // corresponding update message, we must be sure to clear the resize ack logic.
780 TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
781 // Clear the first Resize message that carried screen info.
782 process_->sink().ClearMessages();
784 // Setting the bounds to a "real" rect should send out the notification.
785 gfx::Rect original_size(0, 0, 100, 100);
786 view_->set_bounds(original_size);
787 host_->WasResized();
788 EXPECT_TRUE(host_->resize_ack_pending_);
789 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
790 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
792 // Simulate a renderer crash before the update message. Ensure all the
793 // resize ack logic is cleared. Must clear the view first so it doesn't get
794 // deleted.
795 host_->SetView(NULL);
796 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
797 EXPECT_FALSE(host_->resize_ack_pending_);
798 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
800 // Reset the view so we can exit the test cleanly.
801 host_->SetView(view_.get());
804 // Unable to include render_widget_host_view_mac.h and compile.
805 #if !defined(OS_MACOSX)
806 // Tests setting background transparency.
807 TEST_F(RenderWidgetHostTest, Background) {
808 scoped_ptr<RenderWidgetHostViewBase> view;
809 #if defined(USE_AURA)
810 view.reset(new RenderWidgetHostViewAura(host_.get(), false));
811 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
812 view->InitAsChild(NULL);
813 #elif defined(OS_ANDROID)
814 view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
815 #endif
816 host_->SetView(view.get());
818 EXPECT_TRUE(view->GetBackgroundOpaque());
819 view->SetBackgroundColor(SK_ColorTRANSPARENT);
820 EXPECT_FALSE(view->GetBackgroundOpaque());
822 const IPC::Message* set_background =
823 process_->sink().GetUniqueMessageMatching(
824 ViewMsg_SetBackgroundOpaque::ID);
825 ASSERT_TRUE(set_background);
826 base::Tuple<bool> sent_background;
827 ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
828 EXPECT_FALSE(base::get<0>(sent_background));
830 #if defined(USE_AURA)
831 // See the comment above |InitAsChild(NULL)|.
832 host_->SetView(NULL);
833 static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
834 #endif
836 #endif
838 // Test that we don't paint when we're hidden, but we still send the ACK. Most
839 // of the rest of the painting is tested in the GetBackingStore* ones.
840 TEST_F(RenderWidgetHostTest, HiddenPaint) {
841 BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
842 // Hide the widget, it should have sent out a message to the renderer.
843 EXPECT_FALSE(host_->is_hidden_);
844 host_->WasHidden();
845 EXPECT_TRUE(host_->is_hidden_);
846 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID));
848 // Send it an update as from the renderer.
849 process_->sink().ClearMessages();
850 ViewHostMsg_UpdateRect_Params params;
851 params.view_size = gfx::Size(100, 100);
852 host_->OnUpdateRect(params);
854 // Now unhide.
855 process_->sink().ClearMessages();
856 host_->WasShown(ui::LatencyInfo());
857 EXPECT_FALSE(host_->is_hidden_);
859 // It should have sent out a restored message with a request to paint.
860 const IPC::Message* restored = process_->sink().GetUniqueMessageMatching(
861 ViewMsg_WasShown::ID);
862 ASSERT_TRUE(restored);
863 base::Tuple<bool, ui::LatencyInfo> needs_repaint;
864 ViewMsg_WasShown::Read(restored, &needs_repaint);
865 EXPECT_TRUE(base::get<0>(needs_repaint));
868 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
869 // Simulate a keyboard event.
870 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
872 // Make sure we sent the input event to the renderer.
873 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
874 InputMsg_HandleInputEvent::ID));
875 process_->sink().ClearMessages();
877 // Send the simulated response from the renderer back.
878 SendInputEventACK(WebInputEvent::RawKeyDown,
879 INPUT_EVENT_ACK_STATE_CONSUMED);
880 EXPECT_FALSE(delegate_->unhandled_keyboard_event_called());
883 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
884 // Simluate the situation that the browser handled the key down event during
885 // pre-handle phrase.
886 delegate_->set_prehandle_keyboard_event(true);
887 process_->sink().ClearMessages();
889 // Simulate a keyboard event.
890 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
892 EXPECT_TRUE(delegate_->prehandle_keyboard_event_called());
893 EXPECT_EQ(WebInputEvent::RawKeyDown,
894 delegate_->prehandle_keyboard_event_type());
896 // Make sure the RawKeyDown event is not sent to the renderer.
897 EXPECT_EQ(0U, process_->sink().message_count());
899 // The browser won't pre-handle a Char event.
900 delegate_->set_prehandle_keyboard_event(false);
902 // Forward the Char event.
903 SimulateKeyboardEvent(WebInputEvent::Char);
905 // Make sure the Char event is suppressed.
906 EXPECT_EQ(0U, process_->sink().message_count());
908 // Forward the KeyUp event.
909 SimulateKeyboardEvent(WebInputEvent::KeyUp);
911 // Make sure only KeyUp was sent to the renderer.
912 EXPECT_EQ(1U, process_->sink().message_count());
913 EXPECT_EQ(InputMsg_HandleInputEvent::ID,
914 process_->sink().GetMessageAt(0)->type());
915 process_->sink().ClearMessages();
917 // Send the simulated response from the renderer back.
918 SendInputEventACK(WebInputEvent::KeyUp,
919 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
921 EXPECT_TRUE(delegate_->unhandled_keyboard_event_called());
922 EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type());
925 TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
926 SimulateWheelEvent(-5, 0, 0, true);
928 // Make sure we sent the input event to the renderer.
929 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
930 InputMsg_HandleInputEvent::ID));
931 process_->sink().ClearMessages();
933 // Send the simulated response from the renderer back.
934 SendInputEventACK(WebInputEvent::MouseWheel,
935 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
936 EXPECT_TRUE(delegate_->handle_wheel_event_called());
937 EXPECT_EQ(1, view_->unhandled_wheel_event_count());
938 EXPECT_EQ(-5, view_->unhandled_wheel_event().deltaX);
941 TEST_F(RenderWidgetHostTest, HandleWheelEvent) {
942 // Indicate that we're going to handle this wheel event
943 delegate_->set_handle_wheel_event(true);
945 SimulateWheelEvent(-5, 0, 0, true);
947 // Make sure we sent the input event to the renderer.
948 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
949 InputMsg_HandleInputEvent::ID));
950 process_->sink().ClearMessages();
952 // Send the simulated response from the renderer back.
953 SendInputEventACK(WebInputEvent::MouseWheel,
954 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
956 // ensure the wheel event handler was invoked
957 EXPECT_TRUE(delegate_->handle_wheel_event_called());
959 // and that it suppressed the unhandled wheel event handler.
960 EXPECT_EQ(0, view_->unhandled_wheel_event_count());
963 TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
964 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap,
965 blink::WebGestureDeviceTouchscreen);
967 // Make sure we sent the input event to the renderer.
968 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
969 InputMsg_HandleInputEvent::ID));
970 process_->sink().ClearMessages();
972 // Send the simulated response from the renderer back.
973 SendInputEventACK(WebInputEvent::GestureTwoFingerTap,
974 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
975 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap, view_->gesture_event_type());
976 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, view_->ack_result());
979 // Test that the hang monitor timer expires properly if a new timer is started
980 // while one is in progress (see crbug.com/11007).
981 TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) {
982 // Start with a short timeout.
983 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
985 // Immediately try to add a long 30 second timeout.
986 EXPECT_FALSE(host_->unresponsive_timer_fired());
987 host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
989 // Wait long enough for first timeout and see if it fired.
990 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
991 FROM_HERE, base::MessageLoop::QuitClosure(),
992 TimeDelta::FromMilliseconds(10));
993 base::MessageLoop::current()->Run();
994 EXPECT_TRUE(host_->unresponsive_timer_fired());
997 // Test that the hang monitor timer expires properly if it is started, stopped,
998 // and then started again.
999 TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
1000 // Start with a short timeout, then stop it.
1001 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1002 host_->StopHangMonitorTimeout();
1004 // Start it again to ensure it still works.
1005 EXPECT_FALSE(host_->unresponsive_timer_fired());
1006 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1008 // Wait long enough for first timeout and see if it fired.
1009 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1010 FROM_HERE, base::MessageLoop::QuitClosure(),
1011 TimeDelta::FromMilliseconds(40));
1012 base::MessageLoop::current()->Run();
1013 EXPECT_TRUE(host_->unresponsive_timer_fired());
1016 // Test that the hang monitor timer expires properly if it is started, then
1017 // updated to a shorter duration.
1018 TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) {
1019 // Start with a timeout.
1020 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
1022 // Start it again with shorter delay.
1023 EXPECT_FALSE(host_->unresponsive_timer_fired());
1024 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
1026 // Wait long enough for the second timeout and see if it fired.
1027 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1028 FROM_HERE, base::MessageLoop::QuitClosure(),
1029 TimeDelta::FromMilliseconds(25));
1030 base::MessageLoop::current()->Run();
1031 EXPECT_TRUE(host_->unresponsive_timer_fired());
1034 // Test that the hang monitor timer is effectively disabled when the widget is
1035 // hidden.
1036 TEST_F(RenderWidgetHostTest, HangMonitorTimeoutDisabledForInputWhenHidden) {
1037 host_->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(1));
1038 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1040 // Hiding the widget should deactivate the timeout.
1041 host_->WasHidden();
1043 // The timeout should not fire.
1044 EXPECT_FALSE(host_->unresponsive_timer_fired());
1045 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1046 FROM_HERE, base::MessageLoop::QuitClosure(),
1047 TimeDelta::FromMicroseconds(2));
1048 base::MessageLoop::current()->Run();
1049 EXPECT_FALSE(host_->unresponsive_timer_fired());
1051 // The timeout should never reactivate while hidden.
1052 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1053 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1054 FROM_HERE, base::MessageLoop::QuitClosure(),
1055 TimeDelta::FromMicroseconds(2));
1056 base::MessageLoop::current()->Run();
1057 EXPECT_FALSE(host_->unresponsive_timer_fired());
1059 // Showing the widget should restore the timeout, as the events have
1060 // not yet been ack'ed.
1061 host_->WasShown(ui::LatencyInfo());
1062 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1063 FROM_HERE, base::MessageLoop::QuitClosure(),
1064 TimeDelta::FromMicroseconds(2));
1065 base::MessageLoop::current()->Run();
1066 EXPECT_TRUE(host_->unresponsive_timer_fired());
1069 // Test that the hang monitor catches two input events but only one ack.
1070 // This can happen if the second input event causes the renderer to hang.
1071 // This test will catch a regression of crbug.com/111185.
1072 TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
1073 // Configure the host to wait 10ms before considering
1074 // the renderer hung.
1075 host_->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(10));
1077 // Send two events but only one ack.
1078 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1079 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1080 SendInputEventACK(WebInputEvent::RawKeyDown,
1081 INPUT_EVENT_ACK_STATE_CONSUMED);
1083 // Wait long enough for first timeout and see if it fired.
1084 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1085 FROM_HERE, base::MessageLoop::QuitClosure(),
1086 TimeDelta::FromMicroseconds(20));
1087 base::MessageLoop::current()->Run();
1088 EXPECT_TRUE(host_->unresponsive_timer_fired());
1091 std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
1092 std::string result;
1093 for (size_t i = 0; i < process->sink().message_count(); ++i) {
1094 const IPC::Message *message = process->sink().GetMessageAt(i);
1095 EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
1096 InputMsg_HandleInputEvent::Param params;
1097 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1098 const WebInputEvent* event = base::get<0>(params);
1099 if (i != 0)
1100 result += " ";
1101 result += WebInputEventTraits::GetName(event->type);
1103 process->sink().ClearMessages();
1104 return result;
1107 TEST_F(RenderWidgetHostTest, TouchEmulator) {
1108 simulated_event_time_delta_seconds_ = 0.1;
1109 // Immediately ack all touches instead of sending them to the renderer.
1110 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1111 host_->SetTouchEventEmulationEnabled(
1112 true, ui::GestureProviderConfigType::GENERIC_MOBILE);
1113 process_->sink().ClearMessages();
1114 view_->set_bounds(gfx::Rect(0, 0, 400, 200));
1115 view_->Show();
1117 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1118 EXPECT_EQ(0U, process_->sink().message_count());
1120 // Mouse press becomes touch start which in turn becomes tap.
1121 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1122 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1123 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1125 // Mouse drag generates touch move, cancels tap and starts scroll.
1126 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1127 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1128 EXPECT_EQ(
1129 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1130 GetInputMessageTypes(process_));
1131 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1132 INPUT_EVENT_ACK_STATE_CONSUMED);
1133 EXPECT_EQ(0U, process_->sink().message_count());
1135 // Mouse drag with shift becomes pinch.
1136 SimulateMouseEvent(
1137 WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true);
1138 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1139 EXPECT_EQ("GesturePinchBegin",
1140 GetInputMessageTypes(process_));
1141 EXPECT_EQ(0U, process_->sink().message_count());
1143 SimulateMouseEvent(
1144 WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true);
1145 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1146 EXPECT_EQ("GesturePinchUpdate",
1147 GetInputMessageTypes(process_));
1148 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1149 INPUT_EVENT_ACK_STATE_CONSUMED);
1150 EXPECT_EQ(0U, process_->sink().message_count());
1152 // Mouse drag without shift becomes scroll again.
1153 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true);
1154 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1155 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1156 GetInputMessageTypes(process_));
1157 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1158 INPUT_EVENT_ACK_STATE_CONSUMED);
1159 EXPECT_EQ(0U, process_->sink().message_count());
1161 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true);
1162 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1163 EXPECT_EQ("GestureScrollUpdate",
1164 GetInputMessageTypes(process_));
1165 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1166 INPUT_EVENT_ACK_STATE_CONSUMED);
1167 EXPECT_EQ(0U, process_->sink().message_count());
1169 SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true);
1170 EXPECT_EQ(WebInputEvent::TouchEnd, host_->acked_touch_event_type());
1171 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1172 EXPECT_EQ(0U, process_->sink().message_count());
1174 // Mouse move does nothing.
1175 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false);
1176 EXPECT_EQ(0U, process_->sink().message_count());
1178 // Another mouse down continues scroll.
1179 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true);
1180 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1181 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1182 EXPECT_EQ(0U, process_->sink().message_count());
1184 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true);
1185 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1186 EXPECT_EQ(
1187 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1188 GetInputMessageTypes(process_));
1189 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1190 INPUT_EVENT_ACK_STATE_CONSUMED);
1191 EXPECT_EQ(0U, process_->sink().message_count());
1193 // Another pinch.
1194 SimulateMouseEvent(
1195 WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true);
1196 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1197 EXPECT_EQ("GesturePinchBegin",
1198 GetInputMessageTypes(process_));
1199 EXPECT_EQ(0U, process_->sink().message_count());
1201 SimulateMouseEvent(
1202 WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true);
1203 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1204 EXPECT_EQ("GesturePinchUpdate",
1205 GetInputMessageTypes(process_));
1206 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1207 INPUT_EVENT_ACK_STATE_CONSUMED);
1208 EXPECT_EQ(0U, process_->sink().message_count());
1210 // Turn off emulation during a pinch.
1211 host_->SetTouchEventEmulationEnabled(
1212 false, ui::GestureProviderConfigType::GENERIC_MOBILE);
1213 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1214 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1215 GetInputMessageTypes(process_));
1216 EXPECT_EQ(0U, process_->sink().message_count());
1218 // Mouse event should pass untouched.
1219 SimulateMouseEvent(
1220 WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true);
1221 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_));
1222 SendInputEventACK(WebInputEvent::MouseMove,
1223 INPUT_EVENT_ACK_STATE_CONSUMED);
1224 EXPECT_EQ(0U, process_->sink().message_count());
1226 // Turn on emulation.
1227 host_->SetTouchEventEmulationEnabled(
1228 true, ui::GestureProviderConfigType::GENERIC_MOBILE);
1229 EXPECT_EQ(0U, process_->sink().message_count());
1231 // Another touch.
1232 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1233 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1234 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1235 EXPECT_EQ(0U, process_->sink().message_count());
1237 // Scroll.
1238 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1239 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1240 EXPECT_EQ(
1241 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1242 GetInputMessageTypes(process_));
1243 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1244 INPUT_EVENT_ACK_STATE_CONSUMED);
1246 // Turn off emulation during a scroll.
1247 host_->SetTouchEventEmulationEnabled(
1248 false, ui::GestureProviderConfigType::GENERIC_MOBILE);
1249 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1251 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1252 EXPECT_EQ(0U, process_->sink().message_count());
1255 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1256 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1257 host_->SetupForInputRouterTest(); \
1258 host_->INPUTMSG(); \
1259 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1262 TEST_InputRouterRoutes_NOARGS(Focus);
1263 TEST_InputRouterRoutes_NOARGS(Blur);
1264 TEST_InputRouterRoutes_NOARGS(LostCapture);
1266 #undef TEST_InputRouterRoutes_NOARGS
1268 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1269 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1270 host_->SetupForInputRouterTest(); \
1271 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1272 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1275 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo);
1276 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo);
1277 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut);
1278 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy);
1279 #if defined(OS_MACOSX)
1280 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard);
1281 #endif
1282 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste);
1283 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle);
1284 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete);
1285 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll);
1286 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect);
1288 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1290 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplace) {
1291 host_->SetupForInputRouterTest();
1292 host_->Send(new InputMsg_Replace(host_->GetRoutingID(), base::string16()));
1293 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1296 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplaceMisspelling) {
1297 host_->SetupForInputRouterTest();
1298 host_->Send(new InputMsg_ReplaceMisspelling(host_->GetRoutingID(),
1299 base::string16()));
1300 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1303 TEST_F(RenderWidgetHostTest, IgnoreInputEvent) {
1304 host_->SetupForInputRouterTest();
1306 host_->SetIgnoreInputEvents(true);
1308 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1309 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1311 SimulateMouseEvent(WebInputEvent::MouseMove);
1312 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1314 SimulateWheelEvent(0, 100, 0, true);
1315 EXPECT_FALSE(host_->mock_input_router()->sent_wheel_event_);
1317 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1318 blink::WebGestureDeviceTouchpad);
1319 EXPECT_FALSE(host_->mock_input_router()->sent_gesture_event_);
1321 PressTouchPoint(100, 100);
1322 SendTouchEvent();
1323 EXPECT_FALSE(host_->mock_input_router()->send_touch_event_not_cancelled_);
1326 TEST_F(RenderWidgetHostTest, KeyboardListenerIgnoresEvent) {
1327 host_->SetupForInputRouterTest();
1328 host_->AddKeyPressEventCallback(
1329 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1330 base::Unretained(this)));
1331 handle_key_press_event_ = false;
1332 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1334 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1337 TEST_F(RenderWidgetHostTest, KeyboardListenerSuppressFollowingEvents) {
1338 host_->SetupForInputRouterTest();
1340 host_->AddKeyPressEventCallback(
1341 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1342 base::Unretained(this)));
1344 // The callback handles the first event
1345 handle_key_press_event_ = true;
1346 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1348 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1350 // Following Char events should be suppressed
1351 handle_key_press_event_ = false;
1352 SimulateKeyboardEvent(WebInputEvent::Char);
1353 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1354 SimulateKeyboardEvent(WebInputEvent::Char);
1355 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1357 // Sending RawKeyDown event should stop suppression
1358 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1359 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1361 host_->mock_input_router()->sent_keyboard_event_ = false;
1362 SimulateKeyboardEvent(WebInputEvent::Char);
1363 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1366 TEST_F(RenderWidgetHostTest, MouseEventCallbackCanHandleEvent) {
1367 host_->SetupForInputRouterTest();
1369 host_->AddMouseEventCallback(
1370 base::Bind(&RenderWidgetHostTest::MouseEventCallback,
1371 base::Unretained(this)));
1373 handle_mouse_event_ = true;
1374 SimulateMouseEvent(WebInputEvent::MouseDown);
1376 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1378 handle_mouse_event_ = false;
1379 SimulateMouseEvent(WebInputEvent::MouseDown);
1381 EXPECT_TRUE(host_->mock_input_router()->sent_mouse_event_);
1384 TEST_F(RenderWidgetHostTest, InputRouterReceivesHandleInputEvent_ACK) {
1385 host_->SetupForInputRouterTest();
1387 SendInputEventACK(WebInputEvent::RawKeyDown,
1388 INPUT_EVENT_ACK_STATE_CONSUMED);
1390 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1393 TEST_F(RenderWidgetHostTest, InputRouterReceivesMoveCaret_ACK) {
1394 host_->SetupForInputRouterTest();
1396 host_->OnMessageReceived(InputHostMsg_MoveCaret_ACK(0));
1398 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1401 TEST_F(RenderWidgetHostTest, InputRouterReceivesSelectRange_ACK) {
1402 host_->SetupForInputRouterTest();
1404 host_->OnMessageReceived(InputHostMsg_SelectRange_ACK(0));
1406 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1409 TEST_F(RenderWidgetHostTest, InputRouterReceivesHasTouchEventHandlers) {
1410 host_->SetupForInputRouterTest();
1412 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1414 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1417 ui::LatencyInfo GetLatencyInfoFromInputEvent(RenderWidgetHostProcess* process) {
1418 const IPC::Message* message = process->sink().GetUniqueMessageMatching(
1419 InputMsg_HandleInputEvent::ID);
1420 EXPECT_TRUE(message);
1421 InputMsg_HandleInputEvent::Param params;
1422 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1423 process->sink().ClearMessages();
1424 return base::get<1>(params);
1427 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process,
1428 int64 component_id,
1429 WebInputEvent::Type input_type) {
1430 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process);
1431 EXPECT_TRUE(latency_info.FindLatency(
1432 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
1433 component_id,
1434 NULL));
1437 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1438 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1439 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1440 // event's LatencyInfo.
1441 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
1442 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1443 process_->sink().ClearMessages();
1445 // Tests RWHI::ForwardWheelEvent().
1446 SimulateWheelEvent(-5, 0, 0, true);
1447 CheckLatencyInfoComponentInMessage(
1448 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1449 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1451 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1452 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1453 CheckLatencyInfoComponentInMessage(
1454 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1455 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1457 // Tests RWHI::ForwardMouseEvent().
1458 SimulateMouseEvent(WebInputEvent::MouseMove);
1459 CheckLatencyInfoComponentInMessage(
1460 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1461 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1463 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1464 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove,
1465 ui::LatencyInfo());
1466 CheckLatencyInfoComponentInMessage(
1467 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1468 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1470 // Tests RWHI::ForwardGestureEvent().
1471 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1472 blink::WebGestureDeviceTouchscreen);
1473 CheckLatencyInfoComponentInMessage(
1474 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin);
1476 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1477 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate,
1478 blink::WebGestureDeviceTouchscreen,
1479 ui::LatencyInfo());
1480 CheckLatencyInfoComponentInMessage(
1481 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate);
1482 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1483 INPUT_EVENT_ACK_STATE_CONSUMED);
1485 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1486 PressTouchPoint(0, 1);
1487 uint32 touch_event_id = SendTouchEvent();
1488 InputEventAck ack(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
1489 touch_event_id);
1490 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
1491 CheckLatencyInfoComponentInMessage(
1492 process_, GetLatencyComponentId(), WebInputEvent::TouchStart);
1495 TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) {
1496 // RendererExited will delete the view.
1497 host_->SetView(new TestView(host_.get()));
1498 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1500 // Make sure the input router is in a fresh state.
1501 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1504 // Regression test for http://crbug.com/401859.
1505 TEST_F(RenderWidgetHostTest, RendererExitedResetsIsHidden) {
1506 // RendererExited will delete the view.
1507 host_->SetView(new TestView(host_.get()));
1508 host_->WasHidden();
1510 ASSERT_TRUE(host_->is_hidden());
1511 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1512 ASSERT_FALSE(host_->is_hidden());
1514 // Make sure the input router is in a fresh state.
1515 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1518 TEST_F(RenderWidgetHostTest, ResizeParams) {
1519 gfx::Rect bounds(0, 0, 100, 100);
1520 gfx::Size physical_backing_size(40, 50);
1521 view_->set_bounds(bounds);
1522 view_->SetMockPhysicalBackingSize(physical_backing_size);
1524 ViewMsg_Resize_Params resize_params;
1525 host_->GetResizeParams(&resize_params);
1526 EXPECT_EQ(bounds.size(), resize_params.new_size);
1527 EXPECT_EQ(physical_backing_size, resize_params.physical_backing_size);
1530 class RenderWidgetHostInitialSizeTest : public RenderWidgetHostTest {
1531 public:
1532 RenderWidgetHostInitialSizeTest()
1533 : RenderWidgetHostTest(), initial_size_(200, 100) {}
1535 void ConfigureView(TestView* view) override {
1536 view->set_bounds(gfx::Rect(initial_size_));
1539 protected:
1540 gfx::Size initial_size_;
1543 TEST_F(RenderWidgetHostInitialSizeTest, InitialSize) {
1544 // Having an initial size set means that the size information had been sent
1545 // with the reqiest to new up the RenderView and so subsequent WasResized
1546 // calls should not result in new IPC (unless the size has actually changed).
1547 host_->WasResized();
1548 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
1549 EXPECT_EQ(initial_size_, host_->old_resize_params_->new_size);
1550 EXPECT_TRUE(host_->resize_ack_pending_);
1553 } // namespace content