Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / render_widget_host_unittest.cc
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.
4
5 #include "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/command_line.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/shared_memory.h"
10 #include "base/timer/timer.h"
11 #include "content/browser/browser_thread_impl.h"
12 #include "content/browser/gpu/compositor_util.h"
13 #include "content/browser/renderer_host/input/input_router_impl.h"
14 #include "content/browser/renderer_host/render_widget_host_delegate.h"
15 #include "content/browser/renderer_host/render_widget_host_view_base.h"
16 #include "content/common/input/synthetic_web_input_event_builders.h"
17 #include "content/common/input_messages.h"
18 #include "content/common/view_messages.h"
19 #include "content/public/common/content_switches.h"
20 #include "content/public/test/mock_render_process_host.h"
21 #include "content/public/test/test_browser_context.h"
22 #include "content/test/test_render_view_host.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/events/keycodes/keyboard_codes.h"
25 #include "ui/gfx/canvas.h"
26 #include "ui/gfx/screen.h"
27
28 #if defined(OS_ANDROID)
29 #include "content/browser/renderer_host/render_widget_host_view_android.h"
30 #endif
31
32 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
33 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
34 #endif
35
36 #if defined(USE_AURA)
37 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
38 #include "content/browser/renderer_host/ui_events_helper.h"
39 #include "ui/aura/env.h"
40 #include "ui/aura/test/test_screen.h"
41 #include "ui/events/event.h"
42 #endif
43
44 using base::TimeDelta;
45 using blink::WebGestureDevice;
46 using blink::WebGestureEvent;
47 using blink::WebInputEvent;
48 using blink::WebKeyboardEvent;
49 using blink::WebMouseEvent;
50 using blink::WebMouseWheelEvent;
51 using blink::WebTouchEvent;
52 using blink::WebTouchPoint;
53
54 namespace content {
55
56 // MockInputRouter -------------------------------------------------------------
57
58 class MockInputRouter : public InputRouter {
59  public:
60   explicit MockInputRouter(InputRouterClient* client)
61       : send_event_called_(false),
62         sent_mouse_event_(false),
63         sent_wheel_event_(false),
64         sent_keyboard_event_(false),
65         sent_gesture_event_(false),
66         send_touch_event_not_cancelled_(false),
67         message_received_(false),
68         client_(client) {
69   }
70   virtual ~MockInputRouter() {}
71
72   // InputRouter
73   virtual void Flush() OVERRIDE {
74     flush_called_ = true;
75   }
76   virtual bool SendInput(scoped_ptr<IPC::Message> message) OVERRIDE {
77     send_event_called_ = true;
78     return true;
79   }
80   virtual void SendMouseEvent(
81       const MouseEventWithLatencyInfo& mouse_event) OVERRIDE {
82     sent_mouse_event_ = true;
83   }
84   virtual void SendWheelEvent(
85       const MouseWheelEventWithLatencyInfo& wheel_event) OVERRIDE {
86     sent_wheel_event_ = true;
87   }
88   virtual void SendKeyboardEvent(
89       const NativeWebKeyboardEvent& key_event,
90       const ui::LatencyInfo& latency_info,
91       bool is_shortcut) OVERRIDE {
92     sent_keyboard_event_ = true;
93   }
94   virtual void SendGestureEvent(
95       const GestureEventWithLatencyInfo& gesture_event) OVERRIDE {
96     sent_gesture_event_ = true;
97   }
98   virtual void SendTouchEvent(
99       const TouchEventWithLatencyInfo& touch_event) OVERRIDE {
100     send_touch_event_not_cancelled_ =
101         client_->FilterInputEvent(touch_event.event, touch_event.latency) ==
102         INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
103   }
104   virtual const NativeWebKeyboardEvent* GetLastKeyboardEvent() const OVERRIDE {
105     NOTREACHED();
106     return NULL;
107   }
108   virtual bool ShouldForwardTouchEvent() const OVERRIDE { return true; }
109   virtual void OnViewUpdated(int view_flags) OVERRIDE {}
110   virtual bool HasPendingEvents() const OVERRIDE { return false; }
111
112   // IPC::Listener
113   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
114     message_received_ = true;
115     return false;
116   }
117
118   bool flush_called_;
119   bool send_event_called_;
120   bool sent_mouse_event_;
121   bool sent_wheel_event_;
122   bool sent_keyboard_event_;
123   bool sent_gesture_event_;
124   bool send_touch_event_not_cancelled_;
125   bool message_received_;
126
127  private:
128   InputRouterClient* client_;
129
130   DISALLOW_COPY_AND_ASSIGN(MockInputRouter);
131 };
132
133 // MockRenderWidgetHost ----------------------------------------------------
134
135 class MockRenderWidgetHost : public RenderWidgetHostImpl {
136  public:
137   MockRenderWidgetHost(
138       RenderWidgetHostDelegate* delegate,
139       RenderProcessHost* process,
140       int routing_id)
141       : RenderWidgetHostImpl(delegate, process, routing_id, false),
142         unresponsive_timer_fired_(false) {
143     acked_touch_event_type_ = blink::WebInputEvent::Undefined;
144   }
145
146   // Allow poking at a few private members.
147   using RenderWidgetHostImpl::OnUpdateRect;
148   using RenderWidgetHostImpl::RendererExited;
149   using RenderWidgetHostImpl::last_requested_size_;
150   using RenderWidgetHostImpl::is_hidden_;
151   using RenderWidgetHostImpl::resize_ack_pending_;
152   using RenderWidgetHostImpl::input_router_;
153
154   virtual void OnTouchEventAck(
155       const TouchEventWithLatencyInfo& event,
156       InputEventAckState ack_result) OVERRIDE {
157     // Sniff touch acks.
158     acked_touch_event_type_ = event.event.type;
159     RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
160   }
161
162   bool unresponsive_timer_fired() const {
163     return unresponsive_timer_fired_;
164   }
165
166   void set_hung_renderer_delay_ms(int delay_ms) {
167     hung_renderer_delay_ms_ = delay_ms;
168   }
169
170   void DisableGestureDebounce() {
171     input_router_.reset(new InputRouterImpl(
172         process_, this, this, routing_id_, InputRouterImpl::Config()));
173   }
174
175   WebInputEvent::Type acked_touch_event_type() const {
176     return acked_touch_event_type_;
177   }
178
179   void SetupForInputRouterTest() {
180     input_router_.reset(new MockInputRouter(this));
181   }
182
183   MockInputRouter* mock_input_router() {
184     return static_cast<MockInputRouter*>(input_router_.get());
185   }
186
187  protected:
188   virtual void NotifyRendererUnresponsive() OVERRIDE {
189     unresponsive_timer_fired_ = true;
190   }
191
192   bool unresponsive_timer_fired_;
193   WebInputEvent::Type acked_touch_event_type_;
194
195   DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
196 };
197
198 namespace  {
199
200 // RenderWidgetHostProcess -----------------------------------------------------
201
202 class RenderWidgetHostProcess : public MockRenderProcessHost {
203  public:
204   explicit RenderWidgetHostProcess(BrowserContext* browser_context)
205       : MockRenderProcessHost(browser_context),
206         update_msg_reply_flags_(0) {
207   }
208   virtual ~RenderWidgetHostProcess() {
209   }
210
211   void set_update_msg_reply_flags(int flags) {
212     update_msg_reply_flags_ = flags;
213   }
214
215   // Fills the given update parameters with resonable default values.
216   void InitUpdateRectParams(ViewHostMsg_UpdateRect_Params* params);
217
218   virtual bool HasConnection() const OVERRIDE { return true; }
219
220  protected:
221   // Indicates the flags that should be sent with a repaint request. This
222   // only has an effect when update_msg_should_reply_ is true.
223   int update_msg_reply_flags_;
224
225   DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess);
226 };
227
228 void RenderWidgetHostProcess::InitUpdateRectParams(
229     ViewHostMsg_UpdateRect_Params* params) {
230   const int w = 100, h = 100;
231
232   params->view_size = gfx::Size(w, h);
233   params->flags = update_msg_reply_flags_;
234 }
235
236 // TestView --------------------------------------------------------------------
237
238 // This test view allows us to specify the size, and keep track of acked
239 // touch-events.
240 class TestView : public TestRenderWidgetHostView {
241  public:
242   explicit TestView(RenderWidgetHostImpl* rwh)
243       : TestRenderWidgetHostView(rwh),
244         unhandled_wheel_event_count_(0),
245         acked_event_count_(0),
246         gesture_event_type_(-1),
247         use_fake_physical_backing_size_(false),
248         ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
249   }
250
251   // Sets the bounds returned by GetViewBounds.
252   void set_bounds(const gfx::Rect& bounds) {
253     bounds_ = bounds;
254   }
255
256   const WebTouchEvent& acked_event() const { return acked_event_; }
257   int acked_event_count() const { return acked_event_count_; }
258   void ClearAckedEvent() {
259     acked_event_.type = blink::WebInputEvent::Undefined;
260     acked_event_count_ = 0;
261   }
262
263   const WebMouseWheelEvent& unhandled_wheel_event() const {
264     return unhandled_wheel_event_;
265   }
266   int unhandled_wheel_event_count() const {
267     return unhandled_wheel_event_count_;
268   }
269   int gesture_event_type() const { return gesture_event_type_; }
270   InputEventAckState ack_result() const { return ack_result_; }
271
272   void SetMockPhysicalBackingSize(const gfx::Size& mock_physical_backing_size) {
273     use_fake_physical_backing_size_ = true;
274     mock_physical_backing_size_ = mock_physical_backing_size;
275   }
276   void ClearMockPhysicalBackingSize() {
277     use_fake_physical_backing_size_ = false;
278   }
279
280   // RenderWidgetHostView override.
281   virtual gfx::Rect GetViewBounds() const OVERRIDE {
282     return bounds_;
283   }
284   virtual void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
285                                       InputEventAckState ack_result) OVERRIDE {
286     acked_event_ = touch.event;
287     ++acked_event_count_;
288   }
289   virtual void WheelEventAck(const WebMouseWheelEvent& event,
290                              InputEventAckState ack_result) OVERRIDE {
291     if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
292       return;
293     unhandled_wheel_event_count_++;
294     unhandled_wheel_event_ = event;
295   }
296   virtual void GestureEventAck(const WebGestureEvent& event,
297                                InputEventAckState ack_result) OVERRIDE {
298     gesture_event_type_ = event.type;
299     ack_result_ = ack_result;
300   }
301   virtual gfx::Size GetPhysicalBackingSize() const OVERRIDE {
302     if (use_fake_physical_backing_size_)
303       return mock_physical_backing_size_;
304     return TestRenderWidgetHostView::GetPhysicalBackingSize();
305   }
306 #if defined(USE_AURA)
307   virtual ~TestView() {
308     // Simulate the mouse exit event dispatched when an aura window is
309     // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED
310     // into WebInputEvent::MouseMove.)
311     rwh_->input_router()->SendMouseEvent(
312         MouseEventWithLatencyInfo(
313             SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove),
314             ui::LatencyInfo()));
315   }
316 #endif
317
318  protected:
319   WebMouseWheelEvent unhandled_wheel_event_;
320   int unhandled_wheel_event_count_;
321   WebTouchEvent acked_event_;
322   int acked_event_count_;
323   int gesture_event_type_;
324   gfx::Rect bounds_;
325   bool use_fake_physical_backing_size_;
326   gfx::Size mock_physical_backing_size_;
327   InputEventAckState ack_result_;
328
329   DISALLOW_COPY_AND_ASSIGN(TestView);
330 };
331
332 // MockRenderWidgetHostDelegate --------------------------------------------
333
334 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
335  public:
336   MockRenderWidgetHostDelegate()
337       : prehandle_keyboard_event_(false),
338         prehandle_keyboard_event_called_(false),
339         prehandle_keyboard_event_type_(WebInputEvent::Undefined),
340         unhandled_keyboard_event_called_(false),
341         unhandled_keyboard_event_type_(WebInputEvent::Undefined),
342         handle_wheel_event_(false),
343         handle_wheel_event_called_(false) {
344   }
345   virtual ~MockRenderWidgetHostDelegate() {}
346
347   // Tests that make sure we ignore keyboard event acknowledgments to events we
348   // didn't send work by making sure we didn't call UnhandledKeyboardEvent().
349   bool unhandled_keyboard_event_called() const {
350     return unhandled_keyboard_event_called_;
351   }
352
353   WebInputEvent::Type unhandled_keyboard_event_type() const {
354     return unhandled_keyboard_event_type_;
355   }
356
357   bool prehandle_keyboard_event_called() const {
358     return prehandle_keyboard_event_called_;
359   }
360
361   WebInputEvent::Type prehandle_keyboard_event_type() const {
362     return prehandle_keyboard_event_type_;
363   }
364
365   void set_prehandle_keyboard_event(bool handle) {
366     prehandle_keyboard_event_ = handle;
367   }
368
369   void set_handle_wheel_event(bool handle) {
370     handle_wheel_event_ = handle;
371   }
372
373   bool handle_wheel_event_called() {
374     return handle_wheel_event_called_;
375   }
376
377  protected:
378   virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
379                                       bool* is_keyboard_shortcut) OVERRIDE {
380     prehandle_keyboard_event_type_ = event.type;
381     prehandle_keyboard_event_called_ = true;
382     return prehandle_keyboard_event_;
383   }
384
385   virtual void HandleKeyboardEvent(
386       const NativeWebKeyboardEvent& event) OVERRIDE {
387     unhandled_keyboard_event_type_ = event.type;
388     unhandled_keyboard_event_called_ = true;
389   }
390
391   virtual bool HandleWheelEvent(
392       const blink::WebMouseWheelEvent& event) OVERRIDE {
393     handle_wheel_event_called_ = true;
394     return handle_wheel_event_;
395   }
396
397  private:
398   bool prehandle_keyboard_event_;
399   bool prehandle_keyboard_event_called_;
400   WebInputEvent::Type prehandle_keyboard_event_type_;
401
402   bool unhandled_keyboard_event_called_;
403   WebInputEvent::Type unhandled_keyboard_event_type_;
404
405   bool handle_wheel_event_;
406   bool handle_wheel_event_called_;
407 };
408
409 // RenderWidgetHostTest --------------------------------------------------------
410
411 class RenderWidgetHostTest : public testing::Test {
412  public:
413   RenderWidgetHostTest()
414       : process_(NULL),
415         handle_key_press_event_(false),
416         handle_mouse_event_(false),
417         simulated_event_time_delta_seconds_(0) {
418     last_simulated_event_time_seconds_ =
419         (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
420   }
421   virtual ~RenderWidgetHostTest() {
422   }
423
424   bool KeyPressEventCallback(const NativeWebKeyboardEvent& /* event */) {
425     return handle_key_press_event_;
426   }
427   bool MouseEventCallback(const blink::WebMouseEvent& /* event */) {
428     return handle_mouse_event_;
429   }
430
431  protected:
432   // testing::Test
433   virtual void SetUp() {
434     base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
435     command_line->AppendSwitch(switches::kValidateInputEventStream);
436
437     browser_context_.reset(new TestBrowserContext());
438     delegate_.reset(new MockRenderWidgetHostDelegate());
439     process_ = new RenderWidgetHostProcess(browser_context_.get());
440 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
441     if (IsDelegatedRendererEnabled()) {
442       ImageTransportFactory::InitializeForUnitTests(
443           scoped_ptr<ImageTransportFactory>(
444               new NoTransportImageTransportFactory));
445     }
446 #endif
447 #if defined(USE_AURA)
448     aura::Env::CreateInstance(true);
449     screen_.reset(aura::TestScreen::Create(gfx::Size()));
450     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
451 #endif
452     host_.reset(
453         new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
454     view_.reset(new TestView(host_.get()));
455     host_->SetView(view_.get());
456     host_->Init();
457     host_->DisableGestureDebounce();
458   }
459   virtual void TearDown() {
460     view_.reset();
461     host_.reset();
462     delegate_.reset();
463     process_ = NULL;
464     browser_context_.reset();
465
466 #if defined(USE_AURA)
467     aura::Env::DeleteInstance();
468     screen_.reset();
469 #endif
470 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
471     if (IsDelegatedRendererEnabled())
472       ImageTransportFactory::Terminate();
473 #endif
474
475     // Process all pending tasks to avoid leaks.
476     base::MessageLoop::current()->RunUntilIdle();
477   }
478
479   int64 GetLatencyComponentId() {
480     return host_->GetLatencyComponentId();
481   }
482
483   void SendInputEventACK(WebInputEvent::Type type,
484                          InputEventAckState ack_result) {
485     InputHostMsg_HandleInputEvent_ACK_Params ack;
486     ack.type = type;
487     ack.state = ack_result;
488     host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
489   }
490
491   double GetNextSimulatedEventTimeSeconds() {
492     last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_;
493     return last_simulated_event_time_seconds_;
494   }
495
496   void SimulateKeyboardEvent(WebInputEvent::Type type) {
497     SimulateKeyboardEvent(type, 0);
498   }
499
500   void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) {
501     WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
502     event.modifiers = modifiers;
503     NativeWebKeyboardEvent native_event;
504     memcpy(&native_event, &event, sizeof(event));
505     host_->ForwardKeyboardEvent(native_event);
506   }
507
508   void SimulateMouseEvent(WebInputEvent::Type type) {
509     host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type));
510   }
511
512   void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type,
513                                          const ui::LatencyInfo& ui_latency) {
514     host_->ForwardMouseEventWithLatencyInfo(
515         SyntheticWebMouseEventBuilder::Build(type),
516         ui_latency);
517   }
518
519   void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) {
520     host_->ForwardWheelEvent(
521         SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise));
522   }
523
524   void SimulateWheelEventWithLatencyInfo(float dX,
525                                          float dY,
526                                          int modifiers,
527                                          bool precise,
528                                          const ui::LatencyInfo& ui_latency) {
529     host_->ForwardWheelEventWithLatencyInfo(
530         SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise),
531         ui_latency);
532   }
533
534   void SimulateMouseMove(int x, int y, int modifiers) {
535     SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false);
536   }
537
538   void SimulateMouseEvent(
539       WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) {
540     WebMouseEvent event =
541         SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers);
542     if (pressed)
543       event.button = WebMouseEvent::ButtonLeft;
544     event.timeStampSeconds = GetNextSimulatedEventTimeSeconds();
545     host_->ForwardMouseEvent(event);
546   }
547
548   // Inject simple synthetic WebGestureEvent instances.
549   void SimulateGestureEvent(WebInputEvent::Type type,
550                             WebGestureDevice sourceDevice) {
551     host_->ForwardGestureEvent(
552         SyntheticWebGestureEventBuilder::Build(type, sourceDevice));
553   }
554
555   void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type,
556                                            WebGestureDevice sourceDevice,
557                                            const ui::LatencyInfo& ui_latency) {
558     host_->ForwardGestureEventWithLatencyInfo(
559         SyntheticWebGestureEventBuilder::Build(type, sourceDevice),
560         ui_latency);
561   }
562
563   // Set the timestamp for the touch-event.
564   void SetTouchTimestamp(base::TimeDelta timestamp) {
565     touch_event_.SetTimestamp(timestamp);
566   }
567
568   // Sends a touch event (irrespective of whether the page has a touch-event
569   // handler or not).
570   void SendTouchEvent() {
571     host_->ForwardTouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo());
572
573     touch_event_.ResetPoints();
574   }
575
576   int PressTouchPoint(int x, int y) {
577     return touch_event_.PressPoint(x, y);
578   }
579
580   void MoveTouchPoint(int index, int x, int y) {
581     touch_event_.MovePoint(index, x, y);
582   }
583
584   void ReleaseTouchPoint(int index) {
585     touch_event_.ReleasePoint(index);
586   }
587
588   const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
589     PickleIterator iter(message);
590     const char* data;
591     int data_length;
592     if (!message.ReadData(&iter, &data, &data_length))
593       return NULL;
594     return reinterpret_cast<const WebInputEvent*>(data);
595   }
596
597   base::MessageLoopForUI message_loop_;
598
599   scoped_ptr<TestBrowserContext> browser_context_;
600   RenderWidgetHostProcess* process_;  // Deleted automatically by the widget.
601   scoped_ptr<MockRenderWidgetHostDelegate> delegate_;
602   scoped_ptr<MockRenderWidgetHost> host_;
603   scoped_ptr<TestView> view_;
604   scoped_ptr<gfx::Screen> screen_;
605   bool handle_key_press_event_;
606   bool handle_mouse_event_;
607   double last_simulated_event_time_seconds_;
608   double simulated_event_time_delta_seconds_;
609
610  private:
611   SyntheticWebTouchEvent touch_event_;
612
613   DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest);
614 };
615
616 #if GTEST_HAS_PARAM_TEST
617 // RenderWidgetHostWithSourceTest ----------------------------------------------
618
619 // This is for tests that are to be run for all source devices.
620 class RenderWidgetHostWithSourceTest
621     : public RenderWidgetHostTest,
622       public testing::WithParamInterface<WebGestureDevice> {};
623 #endif  // GTEST_HAS_PARAM_TEST
624
625 }  // namespace
626
627 // -----------------------------------------------------------------------------
628
629 TEST_F(RenderWidgetHostTest, Resize) {
630   // The initial bounds is the empty rect, and the screen info hasn't been sent
631   // yet, so setting it to the same thing shouldn't send the resize message.
632   view_->set_bounds(gfx::Rect());
633   host_->WasResized();
634   EXPECT_FALSE(host_->resize_ack_pending_);
635   EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
636
637   // Setting the bounds to a "real" rect should send out the notification.
638   // but should not expect ack for empty physical backing size.
639   gfx::Rect original_size(0, 0, 100, 100);
640   process_->sink().ClearMessages();
641   view_->set_bounds(original_size);
642   view_->SetMockPhysicalBackingSize(gfx::Size());
643   host_->WasResized();
644   EXPECT_FALSE(host_->resize_ack_pending_);
645   EXPECT_EQ(original_size.size(), host_->last_requested_size_);
646   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
647
648   // Setting the bounds to a "real" rect should send out the notification.
649   // but should not expect ack for only physical backing size change.
650   process_->sink().ClearMessages();
651   view_->ClearMockPhysicalBackingSize();
652   host_->WasResized();
653   EXPECT_FALSE(host_->resize_ack_pending_);
654   EXPECT_EQ(original_size.size(), host_->last_requested_size_);
655   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
656
657   // Send out a update that's not a resize ack after setting resize ack pending
658   // flag. This should not clean the resize ack pending flag.
659   process_->sink().ClearMessages();
660   gfx::Rect second_size(0, 0, 110, 110);
661   EXPECT_FALSE(host_->resize_ack_pending_);
662   view_->set_bounds(second_size);
663   host_->WasResized();
664   EXPECT_TRUE(host_->resize_ack_pending_);
665   ViewHostMsg_UpdateRect_Params params;
666   process_->InitUpdateRectParams(&params);
667   host_->OnUpdateRect(params);
668   EXPECT_TRUE(host_->resize_ack_pending_);
669   EXPECT_EQ(second_size.size(), host_->last_requested_size_);
670
671   // Sending out a new notification should NOT send out a new IPC message since
672   // a resize ACK is pending.
673   gfx::Rect third_size(0, 0, 120, 120);
674   process_->sink().ClearMessages();
675   view_->set_bounds(third_size);
676   host_->WasResized();
677   EXPECT_TRUE(host_->resize_ack_pending_);
678   EXPECT_EQ(second_size.size(), host_->last_requested_size_);
679   EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
680
681   // Send a update that's a resize ack, but for the original_size we sent. Since
682   // this isn't the second_size, the message handler should immediately send
683   // a new resize message for the new size to the renderer.
684   process_->sink().ClearMessages();
685   params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
686   params.view_size = original_size.size();
687   host_->OnUpdateRect(params);
688   EXPECT_TRUE(host_->resize_ack_pending_);
689   EXPECT_EQ(third_size.size(), host_->last_requested_size_);
690   ASSERT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
691
692   // Send the resize ack for the latest size.
693   process_->sink().ClearMessages();
694   params.view_size = third_size.size();
695   host_->OnUpdateRect(params);
696   EXPECT_FALSE(host_->resize_ack_pending_);
697   EXPECT_EQ(third_size.size(), host_->last_requested_size_);
698   ASSERT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
699
700   // Now clearing the bounds should send out a notification but we shouldn't
701   // expect a resize ack (since the renderer won't ack empty sizes). The message
702   // should contain the new size (0x0) and not the previous one that we skipped
703   process_->sink().ClearMessages();
704   view_->set_bounds(gfx::Rect());
705   host_->WasResized();
706   EXPECT_FALSE(host_->resize_ack_pending_);
707   EXPECT_EQ(gfx::Size(), host_->last_requested_size_);
708   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
709
710   // Send a rect that has no area but has either width or height set.
711   process_->sink().ClearMessages();
712   view_->set_bounds(gfx::Rect(0, 0, 0, 30));
713   host_->WasResized();
714   EXPECT_FALSE(host_->resize_ack_pending_);
715   EXPECT_EQ(gfx::Size(0, 30), host_->last_requested_size_);
716   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
717
718   // Set the same size again. It should not be sent again.
719   process_->sink().ClearMessages();
720   host_->WasResized();
721   EXPECT_FALSE(host_->resize_ack_pending_);
722   EXPECT_EQ(gfx::Size(0, 30), host_->last_requested_size_);
723   EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
724
725   // A different size should be sent again, however.
726   view_->set_bounds(gfx::Rect(0, 0, 0, 31));
727   host_->WasResized();
728   EXPECT_FALSE(host_->resize_ack_pending_);
729   EXPECT_EQ(gfx::Size(0, 31), host_->last_requested_size_);
730   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
731 }
732
733 // Test for crbug.com/25097.  If a renderer crashes between a resize and the
734 // corresponding update message, we must be sure to clear the resize ack logic.
735 TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
736   // Clear the first Resize message that carried screen info.
737   process_->sink().ClearMessages();
738
739   // Setting the bounds to a "real" rect should send out the notification.
740   gfx::Rect original_size(0, 0, 100, 100);
741   view_->set_bounds(original_size);
742   host_->WasResized();
743   EXPECT_TRUE(host_->resize_ack_pending_);
744   EXPECT_EQ(original_size.size(), host_->last_requested_size_);
745   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
746
747   // Simulate a renderer crash before the update message.  Ensure all the
748   // resize ack logic is cleared.  Must clear the view first so it doesn't get
749   // deleted.
750   host_->SetView(NULL);
751   host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
752   EXPECT_FALSE(host_->resize_ack_pending_);
753   EXPECT_EQ(gfx::Size(), host_->last_requested_size_);
754
755   // Reset the view so we can exit the test cleanly.
756   host_->SetView(view_.get());
757 }
758
759 // Unable to include render_widget_host_view_mac.h and compile.
760 #if !defined(OS_MACOSX)
761 // Tests setting background transparency.
762 TEST_F(RenderWidgetHostTest, Background) {
763   scoped_ptr<RenderWidgetHostViewBase> view;
764 #if defined(USE_AURA)
765   view.reset(new RenderWidgetHostViewAura(host_.get()));
766   // TODO(derat): Call this on all platforms: http://crbug.com/102450.
767   view->InitAsChild(NULL);
768 #elif defined(OS_ANDROID)
769   view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
770 #endif
771   host_->SetView(view.get());
772
773   EXPECT_TRUE(view->GetBackgroundOpaque());
774   view->SetBackgroundOpaque(false);
775   EXPECT_FALSE(view->GetBackgroundOpaque());
776
777   const IPC::Message* set_background =
778       process_->sink().GetUniqueMessageMatching(
779           ViewMsg_SetBackgroundOpaque::ID);
780   ASSERT_TRUE(set_background);
781   Tuple1<bool> sent_background;
782   ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
783   EXPECT_FALSE(sent_background.a);
784
785 #if defined(USE_AURA)
786   // See the comment above |InitAsChild(NULL)|.
787   host_->SetView(NULL);
788   static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
789 #endif
790 }
791 #endif
792
793 // Test that we don't paint when we're hidden, but we still send the ACK. Most
794 // of the rest of the painting is tested in the GetBackingStore* ones.
795 TEST_F(RenderWidgetHostTest, HiddenPaint) {
796   BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current());
797   // Hide the widget, it should have sent out a message to the renderer.
798   EXPECT_FALSE(host_->is_hidden_);
799   host_->WasHidden();
800   EXPECT_TRUE(host_->is_hidden_);
801   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID));
802
803   // Send it an update as from the renderer.
804   process_->sink().ClearMessages();
805   ViewHostMsg_UpdateRect_Params params;
806   process_->InitUpdateRectParams(&params);
807   host_->OnUpdateRect(params);
808
809   // Now unhide.
810   process_->sink().ClearMessages();
811   host_->WasShown(ui::LatencyInfo());
812   EXPECT_FALSE(host_->is_hidden_);
813
814   // It should have sent out a restored message with a request to paint.
815   const IPC::Message* restored = process_->sink().GetUniqueMessageMatching(
816       ViewMsg_WasShown::ID);
817   ASSERT_TRUE(restored);
818   Tuple2<bool, ui::LatencyInfo> needs_repaint;
819   ViewMsg_WasShown::Read(restored, &needs_repaint);
820   EXPECT_TRUE(needs_repaint.a);
821 }
822
823 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
824   // Simulate a keyboard event.
825   SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
826
827   // Make sure we sent the input event to the renderer.
828   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
829                   InputMsg_HandleInputEvent::ID));
830   process_->sink().ClearMessages();
831
832   // Send the simulated response from the renderer back.
833   SendInputEventACK(WebInputEvent::RawKeyDown,
834                     INPUT_EVENT_ACK_STATE_CONSUMED);
835   EXPECT_FALSE(delegate_->unhandled_keyboard_event_called());
836 }
837
838 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) {
839   // Simluate the situation that the browser handled the key down event during
840   // pre-handle phrase.
841   delegate_->set_prehandle_keyboard_event(true);
842   process_->sink().ClearMessages();
843
844   // Simulate a keyboard event.
845   SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
846
847   EXPECT_TRUE(delegate_->prehandle_keyboard_event_called());
848   EXPECT_EQ(WebInputEvent::RawKeyDown,
849             delegate_->prehandle_keyboard_event_type());
850
851   // Make sure the RawKeyDown event is not sent to the renderer.
852   EXPECT_EQ(0U, process_->sink().message_count());
853
854   // The browser won't pre-handle a Char event.
855   delegate_->set_prehandle_keyboard_event(false);
856
857   // Forward the Char event.
858   SimulateKeyboardEvent(WebInputEvent::Char);
859
860   // Make sure the Char event is suppressed.
861   EXPECT_EQ(0U, process_->sink().message_count());
862
863   // Forward the KeyUp event.
864   SimulateKeyboardEvent(WebInputEvent::KeyUp);
865
866   // Make sure only KeyUp was sent to the renderer.
867   EXPECT_EQ(1U, process_->sink().message_count());
868   EXPECT_EQ(InputMsg_HandleInputEvent::ID,
869             process_->sink().GetMessageAt(0)->type());
870   process_->sink().ClearMessages();
871
872   // Send the simulated response from the renderer back.
873   SendInputEventACK(WebInputEvent::KeyUp,
874                     INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
875
876   EXPECT_TRUE(delegate_->unhandled_keyboard_event_called());
877   EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type());
878 }
879
880 TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
881   SimulateWheelEvent(-5, 0, 0, true);
882
883   // Make sure we sent the input event to the renderer.
884   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
885                   InputMsg_HandleInputEvent::ID));
886   process_->sink().ClearMessages();
887
888   // Send the simulated response from the renderer back.
889   SendInputEventACK(WebInputEvent::MouseWheel,
890                     INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
891   EXPECT_TRUE(delegate_->handle_wheel_event_called());
892   EXPECT_EQ(1, view_->unhandled_wheel_event_count());
893   EXPECT_EQ(-5, view_->unhandled_wheel_event().deltaX);
894 }
895
896 TEST_F(RenderWidgetHostTest, HandleWheelEvent) {
897   // Indicate that we're going to handle this wheel event
898   delegate_->set_handle_wheel_event(true);
899
900   SimulateWheelEvent(-5, 0, 0, true);
901
902   // Make sure we sent the input event to the renderer.
903   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
904                   InputMsg_HandleInputEvent::ID));
905   process_->sink().ClearMessages();
906
907   // Send the simulated response from the renderer back.
908   SendInputEventACK(WebInputEvent::MouseWheel,
909                     INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
910
911   // ensure the wheel event handler was invoked
912   EXPECT_TRUE(delegate_->handle_wheel_event_called());
913
914   // and that it suppressed the unhandled wheel event handler.
915   EXPECT_EQ(0, view_->unhandled_wheel_event_count());
916 }
917
918 TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
919   SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap,
920                        blink::WebGestureDeviceTouchscreen);
921
922   // Make sure we sent the input event to the renderer.
923   EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
924                   InputMsg_HandleInputEvent::ID));
925   process_->sink().ClearMessages();
926
927   // Send the simulated response from the renderer back.
928   SendInputEventACK(WebInputEvent::GestureTwoFingerTap,
929                     INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
930   EXPECT_EQ(WebInputEvent::GestureTwoFingerTap, view_->gesture_event_type());
931   EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, view_->ack_result());
932 }
933
934 // Test that the hang monitor timer expires properly if a new timer is started
935 // while one is in progress (see crbug.com/11007).
936 TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) {
937   // Start with a short timeout.
938   host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
939
940   // Immediately try to add a long 30 second timeout.
941   EXPECT_FALSE(host_->unresponsive_timer_fired());
942   host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
943
944   // Wait long enough for first timeout and see if it fired.
945   base::MessageLoop::current()->PostDelayedTask(
946       FROM_HERE,
947       base::MessageLoop::QuitClosure(),
948       TimeDelta::FromMilliseconds(10));
949   base::MessageLoop::current()->Run();
950   EXPECT_TRUE(host_->unresponsive_timer_fired());
951 }
952
953 // Test that the hang monitor timer expires properly if it is started, stopped,
954 // and then started again.
955 TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
956   // Start with a short timeout, then stop it.
957   host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
958   host_->StopHangMonitorTimeout();
959
960   // Start it again to ensure it still works.
961   EXPECT_FALSE(host_->unresponsive_timer_fired());
962   host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
963
964   // Wait long enough for first timeout and see if it fired.
965   base::MessageLoop::current()->PostDelayedTask(
966       FROM_HERE,
967       base::MessageLoop::QuitClosure(),
968       TimeDelta::FromMilliseconds(40));
969   base::MessageLoop::current()->Run();
970   EXPECT_TRUE(host_->unresponsive_timer_fired());
971 }
972
973 // Test that the hang monitor timer expires properly if it is started, then
974 // updated to a shorter duration.
975 TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) {
976   // Start with a timeout.
977   host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
978
979   // Start it again with shorter delay.
980   EXPECT_FALSE(host_->unresponsive_timer_fired());
981   host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
982
983   // Wait long enough for the second timeout and see if it fired.
984   base::MessageLoop::current()->PostDelayedTask(
985       FROM_HERE,
986       base::MessageLoop::QuitClosure(),
987       TimeDelta::FromMilliseconds(25));
988   base::MessageLoop::current()->Run();
989   EXPECT_TRUE(host_->unresponsive_timer_fired());
990 }
991
992 // Test that the hang monitor catches two input events but only one ack.
993 // This can happen if the second input event causes the renderer to hang.
994 // This test will catch a regression of crbug.com/111185.
995 TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
996   // Configure the host to wait 10ms before considering
997   // the renderer hung.
998   host_->set_hung_renderer_delay_ms(10);
999
1000   // Send two events but only one ack.
1001   SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1002   SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1003   SendInputEventACK(WebInputEvent::RawKeyDown,
1004                     INPUT_EVENT_ACK_STATE_CONSUMED);
1005
1006   // Wait long enough for first timeout and see if it fired.
1007   base::MessageLoop::current()->PostDelayedTask(
1008       FROM_HERE,
1009       base::MessageLoop::QuitClosure(),
1010       TimeDelta::FromMilliseconds(40));
1011   base::MessageLoop::current()->Run();
1012   EXPECT_TRUE(host_->unresponsive_timer_fired());
1013 }
1014
1015 std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
1016   std::string result;
1017   for (size_t i = 0; i < process->sink().message_count(); ++i) {
1018     const IPC::Message *message = process->sink().GetMessageAt(i);
1019     EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
1020     InputMsg_HandleInputEvent::Param params;
1021     EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1022     const WebInputEvent* event = params.a;
1023     if (i != 0)
1024       result += " ";
1025     result += WebInputEventTraits::GetName(event->type);
1026   }
1027   process->sink().ClearMessages();
1028   return result;
1029 }
1030
1031 TEST_F(RenderWidgetHostTest, TouchEmulator) {
1032   simulated_event_time_delta_seconds_ = 0.1;
1033   // Immediately ack all touches instead of sending them to the renderer.
1034   host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
1035   host_->SetTouchEventEmulationEnabled(true);
1036   process_->sink().ClearMessages();
1037   view_->set_bounds(gfx::Rect(0, 0, 400, 200));
1038   view_->Show();
1039
1040   SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
1041   EXPECT_EQ(0U, process_->sink().message_count());
1042
1043   // Mouse press becomes touch start which in turn becomes tap.
1044   SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1045   EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1046   EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1047
1048   // Mouse drag generates touch move, cancels tap and starts scroll.
1049   SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1050   EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1051   EXPECT_EQ(
1052       "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1053       GetInputMessageTypes(process_));
1054   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1055                     INPUT_EVENT_ACK_STATE_CONSUMED);
1056   EXPECT_EQ(0U, process_->sink().message_count());
1057
1058   // Mouse drag with shift becomes pinch.
1059   SimulateMouseEvent(
1060       WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true);
1061   EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1062   EXPECT_EQ("GesturePinchBegin",
1063             GetInputMessageTypes(process_));
1064   EXPECT_EQ(0U, process_->sink().message_count());
1065
1066   SimulateMouseEvent(
1067       WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true);
1068   EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1069   EXPECT_EQ("GesturePinchUpdate",
1070             GetInputMessageTypes(process_));
1071   SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1072                     INPUT_EVENT_ACK_STATE_CONSUMED);
1073   EXPECT_EQ(0U, process_->sink().message_count());
1074
1075   // Mouse drag without shift becomes scroll again.
1076   SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true);
1077   EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1078   EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
1079             GetInputMessageTypes(process_));
1080   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1081                     INPUT_EVENT_ACK_STATE_CONSUMED);
1082   EXPECT_EQ(0U, process_->sink().message_count());
1083
1084   SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true);
1085   EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1086   EXPECT_EQ("GestureScrollUpdate",
1087             GetInputMessageTypes(process_));
1088   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1089                     INPUT_EVENT_ACK_STATE_CONSUMED);
1090   EXPECT_EQ(0U, process_->sink().message_count());
1091
1092   SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true);
1093   EXPECT_EQ(WebInputEvent::TouchEnd, host_->acked_touch_event_type());
1094   EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1095   EXPECT_EQ(0U, process_->sink().message_count());
1096
1097   // Mouse move does nothing.
1098   SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false);
1099   EXPECT_EQ(0U, process_->sink().message_count());
1100
1101   // Another mouse down continues scroll.
1102   SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true);
1103   EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1104   EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1105   EXPECT_EQ(0U, process_->sink().message_count());
1106
1107   SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true);
1108   EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1109   EXPECT_EQ(
1110       "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1111       GetInputMessageTypes(process_));
1112   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1113                     INPUT_EVENT_ACK_STATE_CONSUMED);
1114   EXPECT_EQ(0U, process_->sink().message_count());
1115
1116   // Another pinch.
1117   SimulateMouseEvent(
1118       WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true);
1119   EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1120   EXPECT_EQ("GesturePinchBegin",
1121             GetInputMessageTypes(process_));
1122   EXPECT_EQ(0U, process_->sink().message_count());
1123
1124   SimulateMouseEvent(
1125       WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true);
1126   EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1127   EXPECT_EQ("GesturePinchUpdate",
1128             GetInputMessageTypes(process_));
1129   SendInputEventACK(WebInputEvent::GesturePinchUpdate,
1130                     INPUT_EVENT_ACK_STATE_CONSUMED);
1131   EXPECT_EQ(0U, process_->sink().message_count());
1132
1133   // Turn off emulation during a pinch.
1134   host_->SetTouchEventEmulationEnabled(false);
1135   EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1136   EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
1137             GetInputMessageTypes(process_));
1138   EXPECT_EQ(0U, process_->sink().message_count());
1139
1140   // Mouse event should pass untouched.
1141   SimulateMouseEvent(
1142       WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true);
1143   EXPECT_EQ("MouseMove", GetInputMessageTypes(process_));
1144   SendInputEventACK(WebInputEvent::MouseMove,
1145                     INPUT_EVENT_ACK_STATE_CONSUMED);
1146   EXPECT_EQ(0U, process_->sink().message_count());
1147
1148   // Turn on emulation.
1149   host_->SetTouchEventEmulationEnabled(true);
1150   EXPECT_EQ(0U, process_->sink().message_count());
1151
1152   // Another touch.
1153   SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
1154   EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
1155   EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
1156   EXPECT_EQ(0U, process_->sink().message_count());
1157
1158   // Scroll.
1159   SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
1160   EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
1161   EXPECT_EQ(
1162       "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
1163       GetInputMessageTypes(process_));
1164   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1165                     INPUT_EVENT_ACK_STATE_CONSUMED);
1166
1167   // Turn off emulation during a scroll.
1168   host_->SetTouchEventEmulationEnabled(false);
1169   EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
1170
1171   EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
1172   EXPECT_EQ(0U, process_->sink().message_count());
1173 }
1174
1175 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
1176   TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1177     host_->SetupForInputRouterTest(); \
1178     host_->INPUTMSG(); \
1179     EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1180   }
1181
1182 TEST_InputRouterRoutes_NOARGS(Focus);
1183 TEST_InputRouterRoutes_NOARGS(Blur);
1184 TEST_InputRouterRoutes_NOARGS(LostCapture);
1185
1186 #undef TEST_InputRouterRoutes_NOARGS
1187
1188 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \
1189   TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \
1190     host_->SetupForInputRouterTest(); \
1191     host_->Send(new INPUTMSG(host_->GetRoutingID())); \
1192     EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \
1193   }
1194
1195 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo);
1196 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo);
1197 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut);
1198 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy);
1199 #if defined(OS_MACOSX)
1200 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard);
1201 #endif
1202 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste);
1203 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle);
1204 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete);
1205 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll);
1206 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect);
1207
1208 #undef TEST_InputRouterRoutes_NOARGS_FromRFH
1209
1210 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplace) {
1211   host_->SetupForInputRouterTest();
1212   host_->Send(new InputMsg_Replace(host_->GetRoutingID(), base::string16()));
1213   EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1214 }
1215
1216 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplaceMisspelling) {
1217   host_->SetupForInputRouterTest();
1218   host_->Send(new InputMsg_ReplaceMisspelling(host_->GetRoutingID(),
1219                                               base::string16()));
1220   EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
1221 }
1222
1223 TEST_F(RenderWidgetHostTest, IgnoreInputEvent) {
1224   host_->SetupForInputRouterTest();
1225
1226   host_->SetIgnoreInputEvents(true);
1227
1228   SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1229   EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1230
1231   SimulateMouseEvent(WebInputEvent::MouseMove);
1232   EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1233
1234   SimulateWheelEvent(0, 100, 0, true);
1235   EXPECT_FALSE(host_->mock_input_router()->sent_wheel_event_);
1236
1237   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1238                        blink::WebGestureDeviceTouchpad);
1239   EXPECT_FALSE(host_->mock_input_router()->sent_gesture_event_);
1240
1241   PressTouchPoint(100, 100);
1242   SendTouchEvent();
1243   EXPECT_FALSE(host_->mock_input_router()->send_touch_event_not_cancelled_);
1244 }
1245
1246 TEST_F(RenderWidgetHostTest, KeyboardListenerIgnoresEvent) {
1247   host_->SetupForInputRouterTest();
1248   host_->AddKeyPressEventCallback(
1249       base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1250                  base::Unretained(this)));
1251   handle_key_press_event_ = false;
1252   SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1253
1254   EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1255 }
1256
1257 TEST_F(RenderWidgetHostTest, KeyboardListenerSuppressFollowingEvents) {
1258   host_->SetupForInputRouterTest();
1259
1260   host_->AddKeyPressEventCallback(
1261       base::Bind(&RenderWidgetHostTest::KeyPressEventCallback,
1262                  base::Unretained(this)));
1263
1264   // The callback handles the first event
1265   handle_key_press_event_ = true;
1266   SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1267
1268   EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1269
1270   // Following Char events should be suppressed
1271   handle_key_press_event_ = false;
1272   SimulateKeyboardEvent(WebInputEvent::Char);
1273   EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1274   SimulateKeyboardEvent(WebInputEvent::Char);
1275   EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_);
1276
1277   // Sending RawKeyDown event should stop suppression
1278   SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
1279   EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1280
1281   host_->mock_input_router()->sent_keyboard_event_ = false;
1282   SimulateKeyboardEvent(WebInputEvent::Char);
1283   EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_);
1284 }
1285
1286 TEST_F(RenderWidgetHostTest, MouseEventCallbackCanHandleEvent) {
1287   host_->SetupForInputRouterTest();
1288
1289   host_->AddMouseEventCallback(
1290       base::Bind(&RenderWidgetHostTest::MouseEventCallback,
1291                  base::Unretained(this)));
1292
1293   handle_mouse_event_ = true;
1294   SimulateMouseEvent(WebInputEvent::MouseDown);
1295
1296   EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_);
1297
1298   handle_mouse_event_ = false;
1299   SimulateMouseEvent(WebInputEvent::MouseDown);
1300
1301   EXPECT_TRUE(host_->mock_input_router()->sent_mouse_event_);
1302 }
1303
1304 TEST_F(RenderWidgetHostTest, InputRouterReceivesHandleInputEvent_ACK) {
1305   host_->SetupForInputRouterTest();
1306
1307   SendInputEventACK(WebInputEvent::RawKeyDown,
1308                     INPUT_EVENT_ACK_STATE_CONSUMED);
1309
1310   EXPECT_TRUE(host_->mock_input_router()->message_received_);
1311 }
1312
1313 TEST_F(RenderWidgetHostTest, InputRouterReceivesMoveCaret_ACK) {
1314   host_->SetupForInputRouterTest();
1315
1316   host_->OnMessageReceived(ViewHostMsg_MoveCaret_ACK(0));
1317
1318   EXPECT_TRUE(host_->mock_input_router()->message_received_);
1319 }
1320
1321 TEST_F(RenderWidgetHostTest, InputRouterReceivesSelectRange_ACK) {
1322   host_->SetupForInputRouterTest();
1323
1324   host_->OnMessageReceived(ViewHostMsg_SelectRange_ACK(0));
1325
1326   EXPECT_TRUE(host_->mock_input_router()->message_received_);
1327 }
1328
1329 TEST_F(RenderWidgetHostTest, InputRouterReceivesHasTouchEventHandlers) {
1330   host_->SetupForInputRouterTest();
1331
1332   host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1333
1334   EXPECT_TRUE(host_->mock_input_router()->message_received_);
1335 }
1336
1337 ui::LatencyInfo GetLatencyInfoFromInputEvent(RenderWidgetHostProcess* process) {
1338   const IPC::Message* message = process->sink().GetUniqueMessageMatching(
1339       InputMsg_HandleInputEvent::ID);
1340   EXPECT_TRUE(message);
1341   InputMsg_HandleInputEvent::Param params;
1342   EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, &params));
1343   process->sink().ClearMessages();
1344   return params.b;
1345 }
1346
1347 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process,
1348                                         int64 component_id,
1349                                         WebInputEvent::Type input_type) {
1350   ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process);
1351   EXPECT_TRUE(latency_info.FindLatency(
1352       ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
1353       component_id,
1354       NULL));
1355 }
1356
1357 // Tests that after input event passes through RWHI through ForwardXXXEvent()
1358 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
1359 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
1360 // event's LatencyInfo.
1361 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
1362   host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1363   process_->sink().ClearMessages();
1364
1365   // Tests RWHI::ForwardWheelEvent().
1366   SimulateWheelEvent(-5, 0, 0, true);
1367   CheckLatencyInfoComponentInMessage(
1368       process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1369   SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1370
1371   // Tests RWHI::ForwardWheelEventWithLatencyInfo().
1372   SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo());
1373   CheckLatencyInfoComponentInMessage(
1374       process_, GetLatencyComponentId(), WebInputEvent::MouseWheel);
1375   SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED);
1376
1377   // Tests RWHI::ForwardMouseEvent().
1378   SimulateMouseEvent(WebInputEvent::MouseMove);
1379   CheckLatencyInfoComponentInMessage(
1380       process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1381   SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1382
1383   // Tests RWHI::ForwardMouseEventWithLatencyInfo().
1384   SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove,
1385                                     ui::LatencyInfo());
1386   CheckLatencyInfoComponentInMessage(
1387       process_, GetLatencyComponentId(), WebInputEvent::MouseMove);
1388   SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1389
1390   // Tests RWHI::ForwardGestureEvent().
1391   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
1392                        blink::WebGestureDeviceTouchscreen);
1393   CheckLatencyInfoComponentInMessage(
1394       process_, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin);
1395
1396   // Tests RWHI::ForwardGestureEventWithLatencyInfo().
1397   SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate,
1398                                       blink::WebGestureDeviceTouchscreen,
1399                                       ui::LatencyInfo());
1400   CheckLatencyInfoComponentInMessage(
1401       process_, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate);
1402   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
1403                     INPUT_EVENT_ACK_STATE_CONSUMED);
1404
1405   // Tests RWHI::ForwardTouchEventWithLatencyInfo().
1406   PressTouchPoint(0, 1);
1407   SendTouchEvent();
1408   CheckLatencyInfoComponentInMessage(
1409       process_, GetLatencyComponentId(), WebInputEvent::TouchStart);
1410   SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
1411 }
1412
1413 // Tests that after input event passes through RWHI through
1414 // ForwardXXXEventWithLatencyInfo(), input event coordinates will be present in
1415 // the latency info.
1416 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyInfoCoordinates) {
1417   host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
1418   process_->sink().ClearMessages();
1419
1420   {
1421     WebMouseWheelEvent event =
1422         SyntheticWebMouseWheelEventBuilder::Build(-5, 0, 0, true);
1423     event.x = 100;
1424     event.y = 200;
1425     host_->ForwardWheelEvent(event);
1426     ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_);
1427     EXPECT_EQ(1u, latency_info.input_coordinates_size);
1428     EXPECT_EQ(100, latency_info.input_coordinates[0].x);
1429     EXPECT_EQ(200, latency_info.input_coordinates[0].y);
1430     SendInputEventACK(WebInputEvent::MouseWheel,
1431                       INPUT_EVENT_ACK_STATE_CONSUMED);
1432   }
1433
1434   {
1435     WebMouseEvent event =
1436         SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove);
1437     event.x = 300;
1438     event.y = 400;
1439     host_->ForwardMouseEvent(event);
1440     ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_);
1441     EXPECT_EQ(1u, latency_info.input_coordinates_size);
1442     EXPECT_EQ(300, latency_info.input_coordinates[0].x);
1443     EXPECT_EQ(400, latency_info.input_coordinates[0].y);
1444     SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED);
1445   }
1446
1447   {
1448     WebGestureEvent event = SyntheticWebGestureEventBuilder::Build(
1449         WebInputEvent::GestureScrollBegin, blink::WebGestureDeviceTouchscreen);
1450     event.x = 500;
1451     event.y = 600;
1452     host_->ForwardGestureEvent(event);
1453     ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_);
1454     EXPECT_EQ(1u, latency_info.input_coordinates_size);
1455     EXPECT_EQ(500, latency_info.input_coordinates[0].x);
1456     EXPECT_EQ(600, latency_info.input_coordinates[0].y);
1457     SendInputEventACK(WebInputEvent::GestureScrollBegin,
1458                       INPUT_EVENT_ACK_STATE_CONSUMED);
1459   }
1460
1461   {
1462     PressTouchPoint(700, 800);
1463     PressTouchPoint(900, 1000);
1464     PressTouchPoint(1100, 1200);  // LatencyInfo only holds two coordinates.
1465     SendTouchEvent();
1466     ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_);
1467     EXPECT_EQ(2u, latency_info.input_coordinates_size);
1468     EXPECT_EQ(700, latency_info.input_coordinates[0].x);
1469     EXPECT_EQ(800, latency_info.input_coordinates[0].y);
1470     EXPECT_EQ(900, latency_info.input_coordinates[1].x);
1471     EXPECT_EQ(1000, latency_info.input_coordinates[1].y);
1472     SendInputEventACK(WebInputEvent::TouchStart,
1473                       INPUT_EVENT_ACK_STATE_CONSUMED);
1474   }
1475
1476   {
1477     NativeWebKeyboardEvent event;
1478     event.type = WebKeyboardEvent::KeyDown;
1479     host_->ForwardKeyboardEvent(event);
1480     ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_);
1481     EXPECT_EQ(0u, latency_info.input_coordinates_size);
1482     SendInputEventACK(WebInputEvent::KeyDown, INPUT_EVENT_ACK_STATE_CONSUMED);
1483   }
1484 }
1485
1486 TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) {
1487   // RendererExited will delete the view.
1488   host_->SetView(new TestView(host_.get()));
1489   host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1490
1491   // Make sure the input router is in a fresh state.
1492   ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1493 }
1494
1495 // Regression test for http://crbug.com/401859.
1496 TEST_F(RenderWidgetHostTest, RendererExitedResetsIsHidden) {
1497   // RendererExited will delete the view.
1498   host_->SetView(new TestView(host_.get()));
1499   host_->WasHidden();
1500
1501   ASSERT_TRUE(host_->is_hidden());
1502   host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
1503   ASSERT_FALSE(host_->is_hidden());
1504
1505   // Make sure the input router is in a fresh state.
1506   ASSERT_FALSE(host_->input_router()->HasPendingEvents());
1507 }
1508
1509 }  // namespace content