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