[MacViews] Show comboboxes with a native NSMenu
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_unittest.cc
blob3cd868ae20351596bc62fac007ed9a3e1a5c898d
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/gpu/gpu_surface_tracker.h"
17 #include "content/browser/renderer_host/input/input_router_impl.h"
18 #include "content/browser/renderer_host/render_widget_host_delegate.h"
19 #include "content/browser/renderer_host/render_widget_host_view_base.h"
20 #include "content/common/input/synthetic_web_input_event_builders.h"
21 #include "content/common/input_messages.h"
22 #include "content/common/view_messages.h"
23 #include "content/public/common/content_switches.h"
24 #include "content/public/test/mock_render_process_host.h"
25 #include "content/public/test/test_browser_context.h"
26 #include "content/test/test_render_view_host.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "ui/events/keycodes/keyboard_codes.h"
29 #include "ui/gfx/canvas.h"
30 #include "ui/gfx/screen.h"
32 #if defined(OS_ANDROID)
33 #include "content/browser/renderer_host/render_widget_host_view_android.h"
34 #endif
36 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
37 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
38 #endif
40 #if defined(USE_AURA)
41 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
42 #include "content/browser/renderer_host/ui_events_helper.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 NativeWebKeyboardEventWithLatencyInfo& key_event,
88 bool is_shortcut) override {
89 sent_keyboard_event_ = true;
91 void SendGestureEvent(
92 const GestureEventWithLatencyInfo& gesture_event) override {
93 sent_gesture_event_ = true;
95 void SendTouchEvent(const TouchEventWithLatencyInfo& touch_event) override {
96 send_touch_event_not_cancelled_ =
97 client_->FilterInputEvent(touch_event.event, touch_event.latency) ==
98 INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
100 const NativeWebKeyboardEvent* GetLastKeyboardEvent() const override {
101 NOTREACHED();
102 return NULL;
104 void NotifySiteIsMobileOptimized(bool is_mobile_optimized) override {}
105 void RequestNotificationWhenFlushed() override {}
106 bool HasPendingEvents() const override { return false; }
108 // IPC::Listener
109 bool OnMessageReceived(const IPC::Message& message) override {
110 message_received_ = true;
111 return false;
114 bool send_event_called_;
115 bool sent_mouse_event_;
116 bool sent_wheel_event_;
117 bool sent_keyboard_event_;
118 bool sent_gesture_event_;
119 bool send_touch_event_not_cancelled_;
120 bool message_received_;
122 private:
123 InputRouterClient* client_;
125 DISALLOW_COPY_AND_ASSIGN(MockInputRouter);
128 // MockRenderWidgetHost ----------------------------------------------------
130 class MockRenderWidgetHost : public RenderWidgetHostImpl {
131 public:
132 MockRenderWidgetHost(RenderWidgetHostDelegate* delegate,
133 RenderProcessHost* process,
134 int routing_id)
135 : RenderWidgetHostImpl(
136 delegate,
137 process,
138 routing_id,
139 GpuSurfaceTracker::Get()->AddSurfaceForRenderer(process->GetID(),
140 routing_id),
141 false),
142 unresponsive_timer_fired_(false) {
143 acked_touch_event_type_ = blink::WebInputEvent::Undefined;
146 // Allow poking at a few private members.
147 using RenderWidgetHostImpl::GetResizeParams;
148 using RenderWidgetHostImpl::OnUpdateRect;
149 using RenderWidgetHostImpl::RendererExited;
150 using RenderWidgetHostImpl::SetInitialRenderSizeParams;
151 using RenderWidgetHostImpl::old_resize_params_;
152 using RenderWidgetHostImpl::is_hidden_;
153 using RenderWidgetHostImpl::resize_ack_pending_;
154 using RenderWidgetHostImpl::input_router_;
156 void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
157 InputEventAckState ack_result) override {
158 // Sniff touch acks.
159 acked_touch_event_type_ = event.event.type;
160 RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
163 bool unresponsive_timer_fired() const {
164 return unresponsive_timer_fired_;
167 void DisableGestureDebounce() {
168 input_router_.reset(new InputRouterImpl(
169 process_, this, this, routing_id_, InputRouterImpl::Config()));
172 WebInputEvent::Type acked_touch_event_type() const {
173 return acked_touch_event_type_;
176 void SetupForInputRouterTest() {
177 input_router_.reset(new MockInputRouter(this));
180 MockInputRouter* mock_input_router() {
181 return static_cast<MockInputRouter*>(input_router_.get());
184 protected:
185 void NotifyRendererUnresponsive() override {
186 unresponsive_timer_fired_ = true;
189 bool unresponsive_timer_fired_;
190 WebInputEvent::Type acked_touch_event_type_;
192 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
195 namespace {
197 // RenderWidgetHostProcess -----------------------------------------------------
199 class RenderWidgetHostProcess : public MockRenderProcessHost {
200 public:
201 explicit RenderWidgetHostProcess(BrowserContext* browser_context)
202 : MockRenderProcessHost(browser_context) {
204 ~RenderWidgetHostProcess() override {}
206 bool HasConnection() const override { return true; }
208 protected:
209 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess);
212 // TestView --------------------------------------------------------------------
214 // This test view allows us to specify the size, and keep track of acked
215 // touch-events.
216 class TestView : public TestRenderWidgetHostView {
217 public:
218 explicit TestView(RenderWidgetHostImpl* rwh)
219 : TestRenderWidgetHostView(rwh),
220 unhandled_wheel_event_count_(0),
221 acked_event_count_(0),
222 gesture_event_type_(-1),
223 use_fake_physical_backing_size_(false),
224 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
227 // Sets the bounds returned by GetViewBounds.
228 void set_bounds(const gfx::Rect& bounds) {
229 bounds_ = bounds;
232 const WebTouchEvent& acked_event() const { return acked_event_; }
233 int acked_event_count() const { return acked_event_count_; }
234 void ClearAckedEvent() {
235 acked_event_.type = blink::WebInputEvent::Undefined;
236 acked_event_count_ = 0;
239 const WebMouseWheelEvent& unhandled_wheel_event() const {
240 return unhandled_wheel_event_;
242 int unhandled_wheel_event_count() const {
243 return unhandled_wheel_event_count_;
245 int gesture_event_type() const { return gesture_event_type_; }
246 InputEventAckState ack_result() const { return ack_result_; }
248 void SetMockPhysicalBackingSize(const gfx::Size& mock_physical_backing_size) {
249 use_fake_physical_backing_size_ = true;
250 mock_physical_backing_size_ = mock_physical_backing_size;
252 void ClearMockPhysicalBackingSize() {
253 use_fake_physical_backing_size_ = false;
255 void SetScreenInfo(const blink::WebScreenInfo& screen_info) {
256 screen_info_ = screen_info;
259 // RenderWidgetHostView override.
260 gfx::Rect GetViewBounds() const override { return bounds_; }
261 void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
262 InputEventAckState ack_result) override {
263 acked_event_ = touch.event;
264 ++acked_event_count_;
266 void WheelEventAck(const WebMouseWheelEvent& event,
267 InputEventAckState ack_result) override {
268 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
269 return;
270 unhandled_wheel_event_count_++;
271 unhandled_wheel_event_ = event;
273 void GestureEventAck(const WebGestureEvent& event,
274 InputEventAckState ack_result) override {
275 gesture_event_type_ = event.type;
276 ack_result_ = ack_result;
278 gfx::Size GetPhysicalBackingSize() const override {
279 if (use_fake_physical_backing_size_)
280 return mock_physical_backing_size_;
281 return TestRenderWidgetHostView::GetPhysicalBackingSize();
283 void GetScreenInfo(blink::WebScreenInfo* screen_info) override {
284 *screen_info = screen_info_;
286 #if defined(USE_AURA)
287 ~TestView() override {
288 // Simulate the mouse exit event dispatched when an aura window is
289 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
290 // into WebInputEvent::MouseMove.)
291 WebMouseEvent event =
292 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove);
293 event.timeStampSeconds =
294 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
295 rwh_->input_router()->SendMouseEvent(
296 MouseEventWithLatencyInfo(event, ui::LatencyInfo()));
298 #endif
300 protected:
301 WebMouseWheelEvent unhandled_wheel_event_;
302 int unhandled_wheel_event_count_;
303 WebTouchEvent acked_event_;
304 int acked_event_count_;
305 int gesture_event_type_;
306 gfx::Rect bounds_;
307 bool use_fake_physical_backing_size_;
308 gfx::Size mock_physical_backing_size_;
309 InputEventAckState ack_result_;
310 blink::WebScreenInfo screen_info_;
312 DISALLOW_COPY_AND_ASSIGN(TestView);
315 // MockRenderWidgetHostDelegate --------------------------------------------
317 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
318 public:
319 MockRenderWidgetHostDelegate()
320 : prehandle_keyboard_event_(false),
321 prehandle_keyboard_event_called_(false),
322 prehandle_keyboard_event_type_(WebInputEvent::Undefined),
323 unhandled_keyboard_event_called_(false),
324 unhandled_keyboard_event_type_(WebInputEvent::Undefined),
325 handle_wheel_event_(false),
326 handle_wheel_event_called_(false) {
328 ~MockRenderWidgetHostDelegate() override {}
330 // Tests that make sure we ignore keyboard event acknowledgments to events we
331 // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
332 bool unhandled_keyboard_event_called() const {
333 return unhandled_keyboard_event_called_;
336 WebInputEvent::Type unhandled_keyboard_event_type() const {
337 return unhandled_keyboard_event_type_;
340 bool prehandle_keyboard_event_called() const {
341 return prehandle_keyboard_event_called_;
344 WebInputEvent::Type prehandle_keyboard_event_type() const {
345 return prehandle_keyboard_event_type_;
348 void set_prehandle_keyboard_event(bool handle) {
349 prehandle_keyboard_event_ = handle;
352 void set_handle_wheel_event(bool handle) {
353 handle_wheel_event_ = handle;
356 bool handle_wheel_event_called() {
357 return handle_wheel_event_called_;
360 protected:
361 bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
362 bool* is_keyboard_shortcut) override {
363 prehandle_keyboard_event_type_ = event.type;
364 prehandle_keyboard_event_called_ = true;
365 return prehandle_keyboard_event_;
368 void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override {
369 unhandled_keyboard_event_type_ = event.type;
370 unhandled_keyboard_event_called_ = true;
373 bool HandleWheelEvent(const blink::WebMouseWheelEvent& event) override {
374 handle_wheel_event_called_ = true;
375 return handle_wheel_event_;
378 void Cut() override {}
379 void Copy() override {}
380 void Paste() override {}
381 void SelectAll() override {}
383 private:
384 bool prehandle_keyboard_event_;
385 bool prehandle_keyboard_event_called_;
386 WebInputEvent::Type prehandle_keyboard_event_type_;
388 bool unhandled_keyboard_event_called_;
389 WebInputEvent::Type unhandled_keyboard_event_type_;
391 bool handle_wheel_event_;
392 bool handle_wheel_event_called_;
395 // RenderWidgetHostTest --------------------------------------------------------
397 class RenderWidgetHostTest : public testing::Test {
398 public:
399 RenderWidgetHostTest()
400 : process_(NULL),
401 handle_key_press_event_(false),
402 handle_mouse_event_(false),
403 simulated_event_time_delta_seconds_(0) {
404 last_simulated_event_time_seconds_ =
405 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
407 ~RenderWidgetHostTest() override {}
409 bool KeyPressEventCallback(const NativeWebKeyboardEvent& /* event */) {
410 return handle_key_press_event_;
412 bool MouseEventCallback(const blink::WebMouseEvent& /* event */) {
413 return handle_mouse_event_;
416 protected:
417 // testing::Test
418 void SetUp() override {
419 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
420 command_line->AppendSwitch(switches::kValidateInputEventStream);
422 browser_context_.reset(new TestBrowserContext());
423 delegate_.reset(new MockRenderWidgetHostDelegate());
424 process_ = new RenderWidgetHostProcess(browser_context_.get());
425 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
426 if (IsDelegatedRendererEnabled()) {
427 ImageTransportFactory::InitializeForUnitTests(
428 scoped_ptr<ImageTransportFactory>(
429 new NoTransportImageTransportFactory));
431 #endif
432 #if defined(USE_AURA)
433 screen_.reset(aura::TestScreen::Create(gfx::Size()));
434 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
435 #endif
436 host_.reset(new MockRenderWidgetHost(delegate_.get(), process_,
437 process_->GetNextRoutingID()));
438 view_.reset(new TestView(host_.get()));
439 ConfigureView(view_.get());
440 host_->SetView(view_.get());
441 SetInitialRenderSizeParams();
442 host_->Init();
443 host_->DisableGestureDebounce();
446 void TearDown() override {
447 view_.reset();
448 host_.reset();
449 delegate_.reset();
450 process_ = NULL;
451 browser_context_.reset();
453 #if defined(USE_AURA)
454 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, nullptr);
455 screen_.reset();
456 #endif
457 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
458 if (IsDelegatedRendererEnabled())
459 ImageTransportFactory::Terminate();
460 #endif
462 // Process all pending tasks to avoid leaks.
463 base::MessageLoop::current()->RunUntilIdle();
466 void SetInitialRenderSizeParams() {
467 ViewMsg_Resize_Params render_size_params;
468 host_->GetResizeParams(&render_size_params);
469 host_->SetInitialRenderSizeParams(render_size_params);
472 virtual void ConfigureView(TestView* view) {
475 int64 GetLatencyComponentId() {
476 return host_->GetLatencyComponentId();
479 void SendInputEventACK(WebInputEvent::Type type,
480 InputEventAckState ack_result) {
481 DCHECK(!WebInputEvent::isTouchEventType(type));
482 InputEventAck ack(type, ack_result);
483 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
486 double GetNextSimulatedEventTimeSeconds() {
487 last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_;
488 return last_simulated_event_time_seconds_;
491 void SimulateKeyboardEvent(WebInputEvent::Type type) {
492 SimulateKeyboardEvent(type, 0);
495 void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) {
496 WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
497 event.modifiers = modifiers;
498 NativeWebKeyboardEvent native_event;
499 memcpy(&native_event, &event, sizeof(event));
500 host_->ForwardKeyboardEvent(native_event);
503 void SimulateMouseEvent(WebInputEvent::Type type) {
504 host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type));
507 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type,
508 const ui::LatencyInfo& ui_latency) {
509 host_->ForwardMouseEventWithLatencyInfo(
510 SyntheticWebMouseEventBuilder::Build(type),
511 ui_latency);
514 void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
515 host_->ForwardWheelEvent(
516 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
519 void SimulateWheelEventWithLatencyInfo(float dX,
520 float dY,
521 int modifiers,
522 bool precise,
523 const ui::LatencyInfo& ui_latency) {
524 host_->ForwardWheelEventWithLatencyInfo(
525 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
526 ui_latency);
529 void SimulateMouseMove(int x, int y, int modifiers) {
530 SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false);
533 void SimulateMouseEvent(
534 WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) {
535 WebMouseEvent event =
536 SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers);
537 if (pressed)
538 event.button = WebMouseEvent::ButtonLeft;
539 event.timeStampSeconds = GetNextSimulatedEventTimeSeconds();
540 host_->ForwardMouseEvent(event);
543 // Inject simple synthetic WebGestureEvent instances.
544 void SimulateGestureEvent(WebInputEvent::Type type,
545 WebGestureDevice sourceDevice) {
546 host_->ForwardGestureEvent(
547 SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
550 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type,
551 WebGestureDevice sourceDevice,
552 const ui::LatencyInfo& ui_latency) {
553 host_->ForwardGestureEventWithLatencyInfo(
554 SyntheticWebGestureEventBuilder::Build(type, sourceDevice),
555 ui_latency);
558 // Set the timestamp for the touch-event.
559 void SetTouchTimestamp(base::TimeDelta timestamp) {
560 touch_event_.SetTimestamp(timestamp);
563 // Sends a touch event (irrespective of whether the page has a touch-event
564 // handler or not).
565 uint32 SendTouchEvent() {
566 uint32 touch_event_id = touch_event_.uniqueTouchEventId;
567 host_->ForwardTouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo());
569 touch_event_.ResetPoints();
570 return touch_event_id;
573 int PressTouchPoint(int x, int y) {
574 return touch_event_.PressPoint(x, y);
577 void MoveTouchPoint(int index, int x, int y) {
578 touch_event_.MovePoint(index, x, y);
581 void ReleaseTouchPoint(int index) {
582 touch_event_.ReleasePoint(index);
585 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
586 base::PickleIterator iter(message);
587 const char* data;
588 int data_length;
589 if (!iter.ReadData(&data, &data_length))
590 return NULL;
591 return reinterpret_cast<const WebInputEvent*>(data);
594 base::MessageLoopForUI message_loop_;
596 scoped_ptr<TestBrowserContext> browser_context_;
597 RenderWidgetHostProcess* process_; // Deleted automatically by the widget.
598 scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
599 scoped_ptr<MockRenderWidgetHost> host_;
600 scoped_ptr<TestView> view_;
601 scoped_ptr<gfx::Screen> screen_;
602 bool handle_key_press_event_;
603 bool handle_mouse_event_;
604 double last_simulated_event_time_seconds_;
605 double simulated_event_time_delta_seconds_;
607 private:
608 SyntheticWebTouchEvent touch_event_;
610 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest);
613 #if GTEST_HAS_PARAM_TEST
614 // RenderWidgetHostWithSourceTest ----------------------------------------------
616 // This is for tests that are to be run for all source devices.
617 class RenderWidgetHostWithSourceTest
618 : public RenderWidgetHostTest,
619 public testing::WithParamInterface<WebGestureDevice> {};
620 #endif // GTEST_HAS_PARAM_TEST
622 } // namespace
624 // -----------------------------------------------------------------------------
626 TEST_F(RenderWidgetHostTest, Resize) {
627 // The initial bounds is the empty rect, so setting it to the same thing
628 // shouldn't send the resize message.
629 view_->set_bounds(gfx::Rect());
630 host_->WasResized();
631 EXPECT_FALSE(host_->resize_ack_pending_);
632 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
634 // No resize ack if the physical backing gets set, but the view bounds are
635 // zero.
636 view_->SetMockPhysicalBackingSize(gfx::Size(200, 200));
637 host_->WasResized();
638 EXPECT_FALSE(host_->resize_ack_pending_);
640 // Setting the view bounds to nonzero should send out the notification.
641 // but should not expect ack for empty physical backing size.
642 gfx::Rect original_size(0, 0, 100, 100);
643 process_->sink().ClearMessages();
644 view_->set_bounds(original_size);
645 view_->SetMockPhysicalBackingSize(gfx::Size());
646 host_->WasResized();
647 EXPECT_FALSE(host_->resize_ack_pending_);
648 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
649 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
651 // Setting the bounds and physical backing size to nonzero should send out
652 // the notification and expect an ack.
653 process_->sink().ClearMessages();
654 view_->ClearMockPhysicalBackingSize();
655 host_->WasResized();
656 EXPECT_TRUE(host_->resize_ack_pending_);
657 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
658 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
659 ViewHostMsg_UpdateRect_Params params;
660 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
661 params.view_size = original_size.size();
662 host_->OnUpdateRect(params);
663 EXPECT_FALSE(host_->resize_ack_pending_);
665 // Send out a update that's not a resize ack after setting resize ack pending
666 // flag. This should not clean the resize ack pending flag.
667 process_->sink().ClearMessages();
668 gfx::Rect second_size(0, 0, 110, 110);
669 EXPECT_FALSE(host_->resize_ack_pending_);
670 view_->set_bounds(second_size);
671 host_->WasResized();
672 EXPECT_TRUE(host_->resize_ack_pending_);
673 params.flags = 0;
674 params.view_size = gfx::Size(100, 100);
675 host_->OnUpdateRect(params);
676 EXPECT_TRUE(host_->resize_ack_pending_);
677 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
679 // Sending out a new notification should NOT send out a new IPC message since
680 // a resize ACK is pending.
681 gfx::Rect third_size(0, 0, 120, 120);
682 process_->sink().ClearMessages();
683 view_->set_bounds(third_size);
684 host_->WasResized();
685 EXPECT_TRUE(host_->resize_ack_pending_);
686 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
687 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
689 // Send a update that's a resize ack, but for the original_size we sent. Since
690 // this isn't the second_size, the message handler should immediately send
691 // a new resize message for the new size to the renderer.
692 process_->sink().ClearMessages();
693 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
694 params.view_size = original_size.size();
695 host_->OnUpdateRect(params);
696 EXPECT_TRUE(host_->resize_ack_pending_);
697 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
698 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
700 // Send the resize ack for the latest size.
701 process_->sink().ClearMessages();
702 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
703 params.view_size = third_size.size();
704 host_->OnUpdateRect(params);
705 EXPECT_FALSE(host_->resize_ack_pending_);
706 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
707 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
709 // Now clearing the bounds should send out a notification but we shouldn't
710 // expect a resize ack (since the renderer won't ack empty sizes). The message
711 // should contain the new size (0x0) and not the previous one that we skipped
712 process_->sink().ClearMessages();
713 view_->set_bounds(gfx::Rect());
714 host_->WasResized();
715 EXPECT_FALSE(host_->resize_ack_pending_);
716 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
717 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
719 // Send a rect that has no area but has either width or height set.
720 process_->sink().ClearMessages();
721 view_->set_bounds(gfx::Rect(0, 0, 0, 30));
722 host_->WasResized();
723 EXPECT_FALSE(host_->resize_ack_pending_);
724 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
725 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
727 // Set the same size again. It should not be sent again.
728 process_->sink().ClearMessages();
729 host_->WasResized();
730 EXPECT_FALSE(host_->resize_ack_pending_);
731 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
732 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
734 // A different size should be sent again, however.
735 view_->set_bounds(gfx::Rect(0, 0, 0, 31));
736 host_->WasResized();
737 EXPECT_FALSE(host_->resize_ack_pending_);
738 EXPECT_EQ(gfx::Size(0, 31), host_->old_resize_params_->new_size);
739 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
742 // Test that a resize event is sent if WasResized() is called after a
743 // WebScreenInfo change.
744 TEST_F(RenderWidgetHostTest, ResizeScreenInfo) {
745 blink::WebScreenInfo screen_info;
746 screen_info.deviceScaleFactor = 1.f;
747 screen_info.rect = blink::WebRect(0, 0, 800, 600);
748 screen_info.availableRect = blink::WebRect(0, 0, 800, 600);
749 screen_info.orientationAngle = 0;
750 screen_info.orientationType = blink::WebScreenOrientationPortraitPrimary;
752 view_->SetScreenInfo(screen_info);
753 host_->WasResized();
754 EXPECT_FALSE(host_->resize_ack_pending_);
755 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
756 process_->sink().ClearMessages();
758 screen_info.orientationAngle = 180;
759 screen_info.orientationType = blink::WebScreenOrientationLandscapePrimary;
761 view_->SetScreenInfo(screen_info);
762 host_->WasResized();
763 EXPECT_FALSE(host_->resize_ack_pending_);
764 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
765 process_->sink().ClearMessages();
767 screen_info.deviceScaleFactor = 2.f;
769 view_->SetScreenInfo(screen_info);
770 host_->WasResized();
771 EXPECT_FALSE(host_->resize_ack_pending_);
772 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
773 process_->sink().ClearMessages();
775 // No screen change.
776 view_->SetScreenInfo(screen_info);
777 host_->WasResized();
778 EXPECT_FALSE(host_->resize_ack_pending_);
779 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
782 // Test for crbug.com/25097. If a renderer crashes between a resize and the
783 // corresponding update message, we must be sure to clear the resize ack logic.
784 TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
785 // Clear the first Resize message that carried screen info.
786 process_->sink().ClearMessages();
788 // Setting the bounds to a "real" rect should send out the notification.
789 gfx::Rect original_size(0, 0, 100, 100);
790 view_->set_bounds(original_size);
791 host_->WasResized();
792 EXPECT_TRUE(host_->resize_ack_pending_);
793 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
794 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
796 // Simulate a renderer crash before the update message. Ensure all the
797 // resize ack logic is cleared. Must clear the view first so it doesn't get
798 // deleted.
799 host_->SetView(NULL);
800 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
801 EXPECT_FALSE(host_->resize_ack_pending_);
802 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
804 // Reset the view so we can exit the test cleanly.
805 host_->SetView(view_.get());
808 // Unable to include render_widget_host_view_mac.h and compile.
809 #if !defined(OS_MACOSX)
810 // Tests setting background transparency.
811 TEST_F(RenderWidgetHostTest, Background) {
812 scoped_ptr<RenderWidgetHostViewBase> view;
813 #if defined(USE_AURA)
814 view.reset(new RenderWidgetHostViewAura(host_.get(), false));
815 // TODO(derat): Call this on all platforms: http://crbug.com/102450.
816 view->InitAsChild(NULL);
817 #elif defined(OS_ANDROID)
818 view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
819 #endif
820 host_->SetView(view.get());
822 EXPECT_TRUE(view->GetBackgroundOpaque());
823 view->SetBackgroundColor(SK_ColorTRANSPARENT);
824 EXPECT_FALSE(view->GetBackgroundOpaque());
826 const IPC::Message* set_background =
827 process_->sink().GetUniqueMessageMatching(
828 ViewMsg_SetBackgroundOpaque::ID);
829 ASSERT_TRUE(set_background);
830 base::Tuple<bool> sent_background;
831 ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
832 EXPECT_FALSE(base::get<0>(sent_background));
834 #if defined(USE_AURA)
835 // See the comment above |InitAsChild(NULL)|.
836 host_->SetView(NULL);
837 static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
838 #endif
840 #endif
842 // Test that we don't paint when we're hidden, but we still send the ACK. Most
843 // of the rest of the painting is tested in the GetBackingStore* ones.
844 TEST_F(RenderWidgetHostTest, HiddenPaint) {
845 BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
846 // Hide the widget, it should have sent out a message to the renderer.
847 EXPECT_FALSE(host_->is_hidden_);
848 host_->WasHidden();
849 EXPECT_TRUE(host_->is_hidden_);
850 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID));
852 // Send it an update as from the renderer.
853 process_->sink().ClearMessages();
854 ViewHostMsg_UpdateRect_Params params;
855 params.view_size = gfx::Size(100, 100);
856 host_->OnUpdateRect(params);
858 // Now unhide.
859 process_->sink().ClearMessages();
860 host_->WasShown(ui::LatencyInfo());
861 EXPECT_FALSE(host_->is_hidden_);
863 // It should have sent out a restored message with a request to paint.
864 const IPC::Message* restored = process_->sink().GetUniqueMessageMatching(
865 ViewMsg_WasShown::ID);
866 ASSERT_TRUE(restored);
867 base::Tuple<bool, ui::LatencyInfo> needs_repaint;
868 ViewMsg_WasShown::Read(restored, &needs_repaint);
869 EXPECT_TRUE(base::get<0>(needs_repaint));
872 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
873 // Simulate a keyboard event.
874 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
876 // Make sure we sent the input event to the renderer.
877 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
878 InputMsg_HandleInputEvent::ID));
879 process_->sink().ClearMessages();
881 // Send the simulated response from the renderer back.
882 SendInputEventACK(WebInputEvent::RawKeyDown,
883 INPUT_EVENT_ACK_STATE_CONSUMED);
884 EXPECT_FALSE(delegate_->unhandled_keyboard_event_called());
887 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
888 // Simluate the situation that the browser handled the key down event during
889 // pre-handle phrase.
890 delegate_->set_prehandle_keyboard_event(true);
891 process_->sink().ClearMessages();
893 // Simulate a keyboard event.
894 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
896 EXPECT_TRUE(delegate_->prehandle_keyboard_event_called());
897 EXPECT_EQ(WebInputEvent::RawKeyDown,
898 delegate_->prehandle_keyboard_event_type());
900 // Make sure the RawKeyDown event is not sent to the renderer.
901 EXPECT_EQ(0U, process_->sink().message_count());
903 // The browser won't pre-handle a Char event.
904 delegate_->set_prehandle_keyboard_event(false);
906 // Forward the Char event.
907 SimulateKeyboardEvent(WebInputEvent::Char);
909 // Make sure the Char event is suppressed.
910 EXPECT_EQ(0U, process_->sink().message_count());
912 // Forward the KeyUp event.
913 SimulateKeyboardEvent(WebInputEvent::KeyUp);
915 // Make sure only KeyUp was sent to the renderer.
916 EXPECT_EQ(1U, process_->sink().message_count());
917 EXPECT_EQ(InputMsg_HandleInputEvent::ID,
918 process_->sink().GetMessageAt(0)->type());
919 process_->sink().ClearMessages();
921 // Send the simulated response from the renderer back.
922 SendInputEventACK(WebInputEvent::KeyUp,
923 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
925 EXPECT_TRUE(delegate_->unhandled_keyboard_event_called());
926 EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type());
929 TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
930 SimulateWheelEvent(-5, 0, 0, true);
932 // Make sure we sent the input event to the renderer.
933 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
934 InputMsg_HandleInputEvent::ID));
935 process_->sink().ClearMessages();
937 // Send the simulated response from the renderer back.
938 SendInputEventACK(WebInputEvent::MouseWheel,
939 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
940 EXPECT_TRUE(delegate_->handle_wheel_event_called());
941 EXPECT_EQ(1, view_->unhandled_wheel_event_count());
942 EXPECT_EQ(-5, view_->unhandled_wheel_event().deltaX);
945 TEST_F(RenderWidgetHostTest, HandleWheelEvent) {
946 // Indicate that we're going to handle this wheel event
947 delegate_->set_handle_wheel_event(true);
949 SimulateWheelEvent(-5, 0, 0, true);
951 // Make sure we sent the input event to the renderer.
952 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
953 InputMsg_HandleInputEvent::ID));
954 process_->sink().ClearMessages();
956 // Send the simulated response from the renderer back.
957 SendInputEventACK(WebInputEvent::MouseWheel,
958 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
960 // ensure the wheel event handler was invoked
961 EXPECT_TRUE(delegate_->handle_wheel_event_called());
963 // and that it suppressed the unhandled wheel event handler.
964 EXPECT_EQ(0, view_->unhandled_wheel_event_count());
967 TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
968 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap,
969 blink::WebGestureDeviceTouchscreen);
971 // Make sure we sent the input event to the renderer.
972 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
973 InputMsg_HandleInputEvent::ID));
974 process_->sink().ClearMessages();
976 // Send the simulated response from the renderer back.
977 SendInputEventACK(WebInputEvent::GestureTwoFingerTap,
978 INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
979 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap, view_->gesture_event_type());
980 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, view_->ack_result());
983 // Test that the hang monitor timer expires properly if a new timer is started
984 // while one is in progress (see crbug.com/11007).
985 TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) {
986 // Start with a short timeout.
987 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
989 // Immediately try to add a long 30 second timeout.
990 EXPECT_FALSE(host_->unresponsive_timer_fired());
991 host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
993 // Wait long enough for first timeout and see if it fired.
994 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
995 FROM_HERE, base::MessageLoop::QuitClosure(),
996 TimeDelta::FromMilliseconds(10));
997 base::MessageLoop::current()->Run();
998 EXPECT_TRUE(host_->unresponsive_timer_fired());
1001 // Test that the hang monitor timer expires properly if it is started, stopped,
1002 // and then started again.
1003 TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
1004 // Start with a short timeout, then stop it.
1005 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1006 host_->StopHangMonitorTimeout();
1008 // Start it again to ensure it still works.
1009 EXPECT_FALSE(host_->unresponsive_timer_fired());
1010 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
1012 // Wait long enough for first timeout and see if it fired.
1013 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1014 FROM_HERE, base::MessageLoop::QuitClosure(),
1015 TimeDelta::FromMilliseconds(40));
1016 base::MessageLoop::current()->Run();
1017 EXPECT_TRUE(host_->unresponsive_timer_fired());
1020 // Test that the hang monitor timer expires properly if it is started, then
1021 // updated to a shorter duration.
1022 TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) {
1023 // Start with a timeout.
1024 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
1026 // Start it again with shorter delay.
1027 EXPECT_FALSE(host_->unresponsive_timer_fired());
1028 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
1030 // Wait long enough for the second timeout and see if it fired.
1031 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1032 FROM_HERE, base::MessageLoop::QuitClosure(),
1033 TimeDelta::FromMilliseconds(25));
1034 base::MessageLoop::current()->Run();
1035 EXPECT_TRUE(host_->unresponsive_timer_fired());
1038 // Test that the hang monitor timer is effectively disabled when the widget is
1039 // hidden.
1040 TEST_F(RenderWidgetHostTest, HangMonitorTimeoutDisabledForInputWhenHidden) {
1041 host_->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(1));
1042 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1044 // Hiding the widget should deactivate the timeout.
1045 host_->WasHidden();
1047 // The timeout should not fire.
1048 EXPECT_FALSE(host_->unresponsive_timer_fired());
1049 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1050 FROM_HERE, base::MessageLoop::QuitClosure(),
1051 TimeDelta::FromMicroseconds(2));
1052 base::MessageLoop::current()->Run();
1053 EXPECT_FALSE(host_->unresponsive_timer_fired());
1055 // The timeout should never reactivate while hidden.
1056 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1057 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1058 FROM_HERE, base::MessageLoop::QuitClosure(),
1059 TimeDelta::FromMicroseconds(2));
1060 base::MessageLoop::current()->Run();
1061 EXPECT_FALSE(host_->unresponsive_timer_fired());
1063 // Showing the widget should restore the timeout, as the events have
1064 // not yet been ack'ed.
1065 host_->WasShown(ui::LatencyInfo());
1066 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1067 FROM_HERE, base::MessageLoop::QuitClosure(),
1068 TimeDelta::FromMicroseconds(2));
1069 base::MessageLoop::current()->Run();
1070 EXPECT_TRUE(host_->unresponsive_timer_fired());
1073 // Test that the hang monitor catches two input events but only one ack.
1074 // This can happen if the second input event causes the renderer to hang.
1075 // This test will catch a regression of crbug.com/111185.
1076 TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
1077 // Configure the host to wait 10ms before considering
1078 // the renderer hung.
1079 host_->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(10));
1081 // Send two events but only one ack.
1082 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1083 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1084 SendInputEventACK(WebInputEvent::RawKeyDown,
1085 INPUT_EVENT_ACK_STATE_CONSUMED);
1087 // Wait long enough for first timeout and see if it fired.
1088 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1089 FROM_HERE, base::MessageLoop::QuitClosure(),
1090 TimeDelta::FromMicroseconds(20));
1091 base::MessageLoop::current()->Run();
1092 EXPECT_TRUE(host_->unresponsive_timer_fired());
1095 std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
1096 std::string result;
1097 for (size_t i = 0; i < process->sink().message_count(); ++i) {
1098 const IPC::Message *message = process->sink().GetMessageAt(i);
1099 EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
1100 InputMsg_HandleInputEvent::Param params;
1101 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1102 const WebInputEvent* event = base::get<0>(params);
1103 if (i != 0)
1104 result += " ";
1105 result += WebInputEventTraits::GetName(event->type);
1107 process->sink().ClearMessages();
1108 return result;
1111 TEST_F(RenderWidgetHostTest, TouchEmulator) {
1112 simulated_event_time_delta_seconds_ = 0.1;
1113 // Immediately ack all touches instead of sending them to the renderer.
1114 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1115 host_->SetTouchEventEmulationEnabled(
1116 true, ui::GestureProviderConfigType::GENERIC_MOBILE);
1117 process_->sink().ClearMessages();
1118 view_->set_bounds(gfx::Rect(0, 0, 400, 200));
1119 view_->Show();
1121 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1122 EXPECT_EQ(0U, process_->sink().message_count());
1124 // Mouse press becomes touch start which in turn becomes tap.
1125 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1126 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1127 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1129 // Mouse drag generates touch move, cancels tap and starts scroll.
1130 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1131 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1132 EXPECT_EQ(
1133 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1134 GetInputMessageTypes(process_));
1135 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1136 INPUT_EVENT_ACK_STATE_CONSUMED);
1137 EXPECT_EQ(0U, process_->sink().message_count());
1139 // Mouse drag with shift becomes pinch.
1140 SimulateMouseEvent(
1141 WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true);
1142 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1143 EXPECT_EQ("GesturePinchBegin",
1144 GetInputMessageTypes(process_));
1145 EXPECT_EQ(0U, process_->sink().message_count());
1147 SimulateMouseEvent(
1148 WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true);
1149 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1150 EXPECT_EQ("GesturePinchUpdate",
1151 GetInputMessageTypes(process_));
1152 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1153 INPUT_EVENT_ACK_STATE_CONSUMED);
1154 EXPECT_EQ(0U, process_->sink().message_count());
1156 // Mouse drag without shift becomes scroll again.
1157 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true);
1158 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1159 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1160 GetInputMessageTypes(process_));
1161 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1162 INPUT_EVENT_ACK_STATE_CONSUMED);
1163 EXPECT_EQ(0U, process_->sink().message_count());
1165 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true);
1166 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1167 EXPECT_EQ("GestureScrollUpdate",
1168 GetInputMessageTypes(process_));
1169 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1170 INPUT_EVENT_ACK_STATE_CONSUMED);
1171 EXPECT_EQ(0U, process_->sink().message_count());
1173 SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true);
1174 EXPECT_EQ(WebInputEvent::TouchEnd, host_->acked_touch_event_type());
1175 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1176 EXPECT_EQ(0U, process_->sink().message_count());
1178 // Mouse move does nothing.
1179 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false);
1180 EXPECT_EQ(0U, process_->sink().message_count());
1182 // Another mouse down continues scroll.
1183 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true);
1184 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1185 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1186 EXPECT_EQ(0U, process_->sink().message_count());
1188 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true);
1189 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1190 EXPECT_EQ(
1191 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1192 GetInputMessageTypes(process_));
1193 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1194 INPUT_EVENT_ACK_STATE_CONSUMED);
1195 EXPECT_EQ(0U, process_->sink().message_count());
1197 // Another pinch.
1198 SimulateMouseEvent(
1199 WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true);
1200 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1201 EXPECT_EQ("GesturePinchBegin",
1202 GetInputMessageTypes(process_));
1203 EXPECT_EQ(0U, process_->sink().message_count());
1205 SimulateMouseEvent(
1206 WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true);
1207 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1208 EXPECT_EQ("GesturePinchUpdate",
1209 GetInputMessageTypes(process_));
1210 SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1211 INPUT_EVENT_ACK_STATE_CONSUMED);
1212 EXPECT_EQ(0U, process_->sink().message_count());
1214 // Turn off emulation during a pinch.
1215 host_->SetTouchEventEmulationEnabled(
1216 false, ui::GestureProviderConfigType::GENERIC_MOBILE);
1217 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1218 EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1219 GetInputMessageTypes(process_));
1220 EXPECT_EQ(0U, process_->sink().message_count());
1222 // Mouse event should pass untouched.
1223 SimulateMouseEvent(
1224 WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true);
1225 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_));
1226 SendInputEventACK(WebInputEvent::MouseMove,
1227 INPUT_EVENT_ACK_STATE_CONSUMED);
1228 EXPECT_EQ(0U, process_->sink().message_count());
1230 // Turn on emulation.
1231 host_->SetTouchEventEmulationEnabled(
1232 true, ui::GestureProviderConfigType::GENERIC_MOBILE);
1233 EXPECT_EQ(0U, process_->sink().message_count());
1235 // Another touch.
1236 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1237 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1238 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1239 EXPECT_EQ(0U, process_->sink().message_count());
1241 // Scroll.
1242 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1243 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1244 EXPECT_EQ(
1245 "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1246 GetInputMessageTypes(process_));
1247 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1248 INPUT_EVENT_ACK_STATE_CONSUMED);
1250 // Turn off emulation during a scroll.
1251 host_->SetTouchEventEmulationEnabled(
1252 false, ui::GestureProviderConfigType::GENERIC_MOBILE);
1253 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1255 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1256 EXPECT_EQ(0U, process_->sink().message_count());
1259 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1260 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1261 host_->SetupForInputRouterTest(); \
1262 host_->INPUTMSG(); \
1263 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1266 TEST_InputRouterRoutes_NOARGS(Focus);
1267 TEST_InputRouterRoutes_NOARGS(Blur);
1268 TEST_InputRouterRoutes_NOARGS(LostCapture);
1270 #undef TEST_InputRouterRoutes_NOARGS
1272 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1273 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1274 host_->SetupForInputRouterTest(); \
1275 host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1276 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1279 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo);
1280 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo);
1281 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut);
1282 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy);
1283 #if defined(OS_MACOSX)
1284 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard);
1285 #endif
1286 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste);
1287 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle);
1288 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete);
1289 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll);
1290 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect);
1292 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1294 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplace) {
1295 host_->SetupForInputRouterTest();
1296 host_->Send(new InputMsg_Replace(host_->GetRoutingID(), base::string16()));
1297 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1300 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplaceMisspelling) {
1301 host_->SetupForInputRouterTest();
1302 host_->Send(new InputMsg_ReplaceMisspelling(host_->GetRoutingID(),
1303 base::string16()));
1304 EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1307 TEST_F(RenderWidgetHostTest, IgnoreInputEvent) {
1308 host_->SetupForInputRouterTest();
1310 host_->SetIgnoreInputEvents(true);
1312 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1313 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1315 SimulateMouseEvent(WebInputEvent::MouseMove);
1316 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1318 SimulateWheelEvent(0, 100, 0, true);
1319 EXPECT_FALSE(host_->mock_input_router()->sent_wheel_event_);
1321 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1322 blink::WebGestureDeviceTouchpad);
1323 EXPECT_FALSE(host_->mock_input_router()->sent_gesture_event_);
1325 PressTouchPoint(100, 100);
1326 SendTouchEvent();
1327 EXPECT_FALSE(host_->mock_input_router()->send_touch_event_not_cancelled_);
1330 TEST_F(RenderWidgetHostTest, KeyboardListenerIgnoresEvent) {
1331 host_->SetupForInputRouterTest();
1332 host_->AddKeyPressEventCallback(
1333 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1334 base::Unretained(this)));
1335 handle_key_press_event_ = false;
1336 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1338 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1341 TEST_F(RenderWidgetHostTest, KeyboardListenerSuppressFollowingEvents) {
1342 host_->SetupForInputRouterTest();
1344 host_->AddKeyPressEventCallback(
1345 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1346 base::Unretained(this)));
1348 // The callback handles the first event
1349 handle_key_press_event_ = true;
1350 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1352 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1354 // Following Char events should be suppressed
1355 handle_key_press_event_ = false;
1356 SimulateKeyboardEvent(WebInputEvent::Char);
1357 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1358 SimulateKeyboardEvent(WebInputEvent::Char);
1359 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1361 // Sending RawKeyDown event should stop suppression
1362 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1363 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1365 host_->mock_input_router()->sent_keyboard_event_ = false;
1366 SimulateKeyboardEvent(WebInputEvent::Char);
1367 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1370 TEST_F(RenderWidgetHostTest, MouseEventCallbackCanHandleEvent) {
1371 host_->SetupForInputRouterTest();
1373 host_->AddMouseEventCallback(
1374 base::Bind(&RenderWidgetHostTest::MouseEventCallback,
1375 base::Unretained(this)));
1377 handle_mouse_event_ = true;
1378 SimulateMouseEvent(WebInputEvent::MouseDown);
1380 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1382 handle_mouse_event_ = false;
1383 SimulateMouseEvent(WebInputEvent::MouseDown);
1385 EXPECT_TRUE(host_->mock_input_router()->sent_mouse_event_);
1388 TEST_F(RenderWidgetHostTest, InputRouterReceivesHandleInputEvent_ACK) {
1389 host_->SetupForInputRouterTest();
1391 SendInputEventACK(WebInputEvent::RawKeyDown,
1392 INPUT_EVENT_ACK_STATE_CONSUMED);
1394 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1397 TEST_F(RenderWidgetHostTest, InputRouterReceivesMoveCaret_ACK) {
1398 host_->SetupForInputRouterTest();
1400 host_->OnMessageReceived(InputHostMsg_MoveCaret_ACK(0));
1402 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1405 TEST_F(RenderWidgetHostTest, InputRouterReceivesSelectRange_ACK) {
1406 host_->SetupForInputRouterTest();
1408 host_->OnMessageReceived(InputHostMsg_SelectRange_ACK(0));
1410 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1413 TEST_F(RenderWidgetHostTest, InputRouterReceivesHasTouchEventHandlers) {
1414 host_->SetupForInputRouterTest();
1416 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1418 EXPECT_TRUE(host_->mock_input_router()->message_received_);
1421 ui::LatencyInfo GetLatencyInfoFromInputEvent(RenderWidgetHostProcess* process) {
1422 const IPC::Message* message = process->sink().GetUniqueMessageMatching(
1423 InputMsg_HandleInputEvent::ID);
1424 EXPECT_TRUE(message);
1425 InputMsg_HandleInputEvent::Param params;
1426 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1427 process->sink().ClearMessages();
1428 return base::get<1>(params);
1431 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process,
1432 int64 component_id,
1433 WebInputEvent::Type input_type) {
1434 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process);
1435 EXPECT_TRUE(latency_info.FindLatency(
1436 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
1437 component_id,
1438 NULL));
1441 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1442 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1443 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1444 // event's LatencyInfo.
1445 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
1446 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1447 process_->sink().ClearMessages();
1449 // Tests RWHI::ForwardWheelEvent().
1450 SimulateWheelEvent(-5, 0, 0, true);
1451 CheckLatencyInfoComponentInMessage(
1452 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1453 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1455 // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1456 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1457 CheckLatencyInfoComponentInMessage(
1458 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1459 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1461 // Tests RWHI::ForwardMouseEvent().
1462 SimulateMouseEvent(WebInputEvent::MouseMove);
1463 CheckLatencyInfoComponentInMessage(
1464 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1465 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1467 // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1468 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove,
1469 ui::LatencyInfo());
1470 CheckLatencyInfoComponentInMessage(
1471 process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1472 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1474 // Tests RWHI::ForwardGestureEvent().
1475 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1476 blink::WebGestureDeviceTouchscreen);
1477 CheckLatencyInfoComponentInMessage(
1478 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin);
1480 // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1481 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate,
1482 blink::WebGestureDeviceTouchscreen,
1483 ui::LatencyInfo());
1484 CheckLatencyInfoComponentInMessage(
1485 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate);
1486 SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1487 INPUT_EVENT_ACK_STATE_CONSUMED);
1489 // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1490 PressTouchPoint(0, 1);
1491 uint32 touch_event_id = SendTouchEvent();
1492 InputEventAck ack(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED,
1493 touch_event_id);
1494 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
1495 CheckLatencyInfoComponentInMessage(
1496 process_, GetLatencyComponentId(), WebInputEvent::TouchStart);
1499 TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) {
1500 // RendererExited will delete the view.
1501 host_->SetView(new TestView(host_.get()));
1502 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1504 // Make sure the input router is in a fresh state.
1505 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1508 // Regression test for http://crbug.com/401859 and http://crbug.com/522795.
1509 TEST_F(RenderWidgetHostTest, RendererExitedResetsIsHidden) {
1510 // RendererExited will delete the view.
1511 host_->SetView(new TestView(host_.get()));
1512 host_->WasShown(ui::LatencyInfo());
1514 ASSERT_FALSE(host_->is_hidden());
1515 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1516 ASSERT_TRUE(host_->is_hidden());
1518 // Make sure the input router is in a fresh state.
1519 ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1522 TEST_F(RenderWidgetHostTest, ResizeParams) {
1523 gfx::Rect bounds(0, 0, 100, 100);
1524 gfx::Size physical_backing_size(40, 50);
1525 view_->set_bounds(bounds);
1526 view_->SetMockPhysicalBackingSize(physical_backing_size);
1528 ViewMsg_Resize_Params resize_params;
1529 host_->GetResizeParams(&resize_params);
1530 EXPECT_EQ(bounds.size(), resize_params.new_size);
1531 EXPECT_EQ(physical_backing_size, resize_params.physical_backing_size);
1534 class RenderWidgetHostInitialSizeTest : public RenderWidgetHostTest {
1535 public:
1536 RenderWidgetHostInitialSizeTest()
1537 : RenderWidgetHostTest(), initial_size_(200, 100) {}
1539 void ConfigureView(TestView* view) override {
1540 view->set_bounds(gfx::Rect(initial_size_));
1543 protected:
1544 gfx::Size initial_size_;
1547 TEST_F(RenderWidgetHostInitialSizeTest, InitialSize) {
1548 // Having an initial size set means that the size information had been sent
1549 // with the reqiest to new up the RenderView and so subsequent WasResized
1550 // calls should not result in new IPC (unless the size has actually changed).
1551 host_->WasResized();
1552 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
1553 EXPECT_EQ(initial_size_, host_->old_resize_params_->new_size);
1554 EXPECT_TRUE(host_->resize_ack_pending_);
1557 } // namespace content