Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / render_widget_host_unittest.cc
index 5494470..78505f1 100644 (file)
@@ -9,19 +9,16 @@
 #include "base/memory/shared_memory.h"
 #include "base/timer/timer.h"
 #include "content/browser/browser_thread_impl.h"
-#include "content/browser/renderer_host/backing_store.h"
 #include "content/browser/renderer_host/input/gesture_event_queue.h"
 #include "content/browser/renderer_host/input/input_router_impl.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
 #include "content/browser/renderer_host/input/touch_event_queue.h"
 #include "content/browser/renderer_host/overscroll_controller.h"
 #include "content/browser/renderer_host/overscroll_controller_delegate.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/common/input/synthetic_web_input_event_builders.h"
 #include "content/common/input_messages.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/public/test/test_browser_context.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/screen.h"
 
+#if defined(OS_ANDROID)
+#include "content/browser/renderer_host/render_widget_host_view_android.h"
+#endif
+
 #if defined(USE_AURA)
 #include "content/browser/compositor/image_transport_factory.h"
 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
+#include "content/browser/renderer_host/ui_events_helper.h"
 #include "ui/aura/env.h"
 #include "ui/aura/test/test_screen.h"
 #include "ui/compositor/test/in_process_context_factory.h"
-#endif
-
-#if defined(OS_WIN) || defined(USE_AURA)
-#include "content/browser/renderer_host/ui_events_helper.h"
 #include "ui/events/event.h"
 #endif
 
@@ -48,6 +46,7 @@ using base::TimeDelta;
 using blink::WebGestureEvent;
 using blink::WebInputEvent;
 using blink::WebKeyboardEvent;
+using blink::WebMouseEvent;
 using blink::WebMouseWheelEvent;
 using blink::WebTouchEvent;
 using blink::WebTouchPoint;
@@ -198,7 +197,7 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
       int routing_id)
       : RenderWidgetHostImpl(delegate, process, routing_id, false),
         unresponsive_timer_fired_(false) {
-    input_router_impl_ = static_cast<InputRouterImpl*>(input_router_.get());
+    acked_touch_event_type_ = blink::WebInputEvent::Undefined;
   }
 
   // Allow poking at a few private members.
@@ -218,36 +217,28 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
   }
 
   unsigned GestureEventLastQueueEventSize() const {
-    return gesture_event_queue()->coalesced_gesture_events_.size();
+    return gesture_event_queue().coalesced_gesture_events_.size();
   }
 
   WebGestureEvent GestureEventSecondFromLastQueueEvent() const {
-    return gesture_event_queue()->coalesced_gesture_events_.at(
+    return gesture_event_queue().coalesced_gesture_events_.at(
       GestureEventLastQueueEventSize() - 2).event;
   }
 
   WebGestureEvent GestureEventLastQueueEvent() const {
-    return gesture_event_queue()->coalesced_gesture_events_.back().event;
+    return gesture_event_queue().coalesced_gesture_events_.back().event;
   }
 
   unsigned GestureEventDebouncingQueueSize() const {
-    return gesture_event_queue()->debouncing_deferral_queue_.size();
+    return gesture_event_queue().debouncing_deferral_queue_.size();
   }
 
   WebGestureEvent GestureEventQueueEventAt(int i) const {
-    return gesture_event_queue()->coalesced_gesture_events_.at(i).event;
+    return gesture_event_queue().coalesced_gesture_events_.at(i).event;
   }
 
   bool ScrollingInProgress() const {
-    return gesture_event_queue()->scrolling_in_progress_;
-  }
-
-  bool FlingInProgress() const {
-    return gesture_event_queue()->fling_in_progress_;
-  }
-
-  bool WillIgnoreNextACK() const {
-    return gesture_event_queue()->ignore_next_ack_;
+    return gesture_event_queue().scrolling_in_progress_;
   }
 
   void SetupForOverscrollControllerTest() {
@@ -256,17 +247,26 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
     overscroll_controller_->set_delegate(overscroll_delegate_.get());
   }
 
-  void DisableGestureDebounce() {
-    gesture_event_queue()->set_debounce_enabled_for_testing(false);
-  }
+  void DisableGestureDebounce() { set_debounce_interval_time_ms(0); }
 
   void set_debounce_interval_time_ms(int delay_ms) {
-    gesture_event_queue()->
-        set_debounce_interval_time_ms_for_testing(delay_ms);
+    gesture_event_queue().set_debounce_interval_time_ms_for_testing(delay_ms);
   }
 
   bool TouchEventQueueEmpty() const {
-    return touch_event_queue()->empty();
+    return touch_event_queue().empty();
+  }
+
+  virtual void OnTouchEventAck(
+      const TouchEventWithLatencyInfo& event,
+      InputEventAckState ack_result) OVERRIDE {
+    // Sniff touch acks.
+    acked_touch_event_type_ = event.event.type;
+    RenderWidgetHostImpl::OnTouchEventAck(event, ack_result);
+  }
+
+  WebInputEvent::Type acked_touch_event_type() const {
+    return acked_touch_event_type_;
   }
 
   bool ScrollStateIsContentScrolling() const {
@@ -302,12 +302,11 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
   }
 
   void SetupForInputRouterTest() {
-    mock_input_router_ = new MockInputRouter(this);
-    input_router_.reset(mock_input_router_);
+    input_router_.reset(new MockInputRouter(this));
   }
 
   MockInputRouter* mock_input_router() {
-    return mock_input_router_;
+    return static_cast<MockInputRouter*>(input_router_.get());
   }
 
  protected:
@@ -315,26 +314,29 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
     unresponsive_timer_fired_ = true;
   }
 
-  const TouchEventQueue* touch_event_queue() const {
-    return input_router_impl_->touch_event_queue_.get();
+  const TouchEventQueue& touch_event_queue() const {
+    return input_router_impl()->touch_event_queue_;
   }
 
-  const GestureEventQueue* gesture_event_queue() const {
-    return input_router_impl_->gesture_event_queue_.get();
+  const GestureEventQueue& gesture_event_queue() const {
+    return input_router_impl()->gesture_event_queue_;
   }
 
-  GestureEventQueue* gesture_event_queue() {
-    return input_router_impl_->gesture_event_queue_.get();
+  GestureEventQueue& gesture_event_queue() {
+    return input_router_impl()->gesture_event_queue_;
   }
 
  private:
-  bool unresponsive_timer_fired_;
+  const InputRouterImpl* input_router_impl() const {
+    return static_cast<InputRouterImpl*>(input_router_.get());
+  }
 
-  // |input_router_impl_| and |mock_input_router_| are owned by
-  // RenderWidgetHostImpl.  The handles below are provided for convenience so
-  // that we don't have to reinterpret_cast it all the time.
-  InputRouterImpl* input_router_impl_;
-  MockInputRouter* mock_input_router_;
+  InputRouterImpl* input_router_impl() {
+    return static_cast<InputRouterImpl*>(input_router_.get());
+  }
+
+  bool unresponsive_timer_fired_;
+  WebInputEvent::Type acked_touch_event_type_;
 
   scoped_ptr<TestOverscrollDelegate> overscroll_delegate_;
 
@@ -349,12 +351,10 @@ class RenderWidgetHostProcess : public MockRenderProcessHost {
  public:
   explicit RenderWidgetHostProcess(BrowserContext* browser_context)
       : MockRenderProcessHost(browser_context),
-        current_update_buf_(NULL),
         update_msg_should_reply_(false),
         update_msg_reply_flags_(0) {
   }
   virtual ~RenderWidgetHostProcess() {
-    delete current_update_buf_;
   }
 
   void set_update_msg_should_reply(bool reply) {
@@ -374,8 +374,6 @@ class RenderWidgetHostProcess : public MockRenderProcessHost {
                                       const base::TimeDelta& max_delay,
                                       IPC::Message* msg) OVERRIDE;
 
-  TransportDIB* current_update_buf_;
-
   // Set to true when WaitForBackingStoreMsg should return a successful update
   // message reply. False implies timeout.
   bool update_msg_should_reply_;
@@ -389,20 +387,10 @@ class RenderWidgetHostProcess : public MockRenderProcessHost {
 
 void RenderWidgetHostProcess::InitUpdateRectParams(
     ViewHostMsg_UpdateRect_Params* params) {
-  // Create the shared backing store.
   const int w = 100, h = 100;
-  const size_t pixel_size = w * h * 4;
-
-  if (!current_update_buf_)
-    current_update_buf_ = TransportDIB::Create(pixel_size, 0);
-  params->bitmap = current_update_buf_->id();
-  params->bitmap_rect = gfx::Rect(0, 0, w, h);
-  params->scroll_delta = gfx::Vector2d();
-  params->copy_rects.push_back(params->bitmap_rect);
+
   params->view_size = gfx::Size(w, h);
   params->flags = update_msg_reply_flags_;
-  params->needs_ack = true;
-  params->scale_factor = 1;
 }
 
 bool RenderWidgetHostProcess::WaitForBackingStoreMsg(
@@ -587,7 +575,10 @@ class RenderWidgetHostTest : public testing::Test {
   RenderWidgetHostTest()
       : process_(NULL),
         handle_key_press_event_(false),
-        handle_mouse_event_(false) {
+        handle_mouse_event_(false),
+        simulated_event_time_delta_seconds_(0) {
+    last_simulated_event_time_seconds_ =
+        (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
   }
   virtual ~RenderWidgetHostTest() {
   }
@@ -611,7 +602,7 @@ class RenderWidgetHostTest : public testing::Test {
 #if defined(USE_AURA)
     ImageTransportFactory::InitializeForUnitTests(
         scoped_ptr<ui::ContextFactory>(new ui::InProcessContextFactory));
-    aura::Env::CreateInstance();
+    aura::Env::CreateInstance(true);
     screen_.reset(aura::TestScreen::Create());
     gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get());
 #endif
@@ -620,6 +611,9 @@ class RenderWidgetHostTest : public testing::Test {
     view_.reset(new TestView(host_.get()));
     host_->SetView(view_.get());
     host_->Init();
+
+    // Tests for debounce-related behavior will explicitly enable debouncing.
+    host_->DisableGestureDebounce();
   }
   virtual void TearDown() {
     view_.reset();
@@ -650,10 +644,20 @@ class RenderWidgetHostTest : public testing::Test {
     host_->OnMessageReceived(*response);
   }
 
+  double GetNextSimulatedEventTimeSeconds() {
+    last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_;
+    return last_simulated_event_time_seconds_;
+  }
+
   void SimulateKeyboardEvent(WebInputEvent::Type type) {
-  WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
-  NativeWebKeyboardEvent native_event;
-  memcpy(&native_event, &event, sizeof(event));
+    SimulateKeyboardEvent(type, 0);
+  }
+
+  void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) {
+    WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
+    event.modifiers = modifiers;
+    NativeWebKeyboardEvent native_event;
+    memcpy(&native_event, &event, sizeof(event));
     host_->ForwardKeyboardEvent(native_event);
   }
 
@@ -684,11 +688,17 @@ class RenderWidgetHostTest : public testing::Test {
   }
 
   void SimulateMouseMove(int x, int y, int modifiers) {
-    host_->ForwardMouseEvent(
-        SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove,
-                                             x,
-                                             y,
-                                             modifiers));
+    SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false);
+  }
+
+  void SimulateMouseEvent(
+      WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) {
+    WebMouseEvent event =
+        SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers);
+    if (pressed)
+      event.button = WebMouseEvent::ButtonLeft;
+    event.timeStampSeconds = GetNextSimulatedEventTimeSeconds();
+    host_->ForwardMouseEvent(event);
   }
 
   void SimulateWheelEventWithPhase(WebMouseWheelEvent::Phase phase) {
@@ -731,11 +741,8 @@ class RenderWidgetHostTest : public testing::Test {
                                        float anchorX,
                                        float anchorY,
                                        int modifiers) {
-    SimulateGestureEventCore(
-        SyntheticWebGestureEventBuilder::BuildPinchUpdate(scale,
-                                                          anchorX,
-                                                          anchorY,
-                                                          modifiers));
+    SimulateGestureEventCore(SyntheticWebGestureEventBuilder::BuildPinchUpdate(
+        scale, anchorX, anchorY, modifiers, WebGestureEvent::Touchscreen));
   }
 
   // Inject synthetic GestureFlingStart events.
@@ -793,6 +800,8 @@ class RenderWidgetHostTest : public testing::Test {
   scoped_ptr<gfx::Screen> screen_;
   bool handle_key_press_event_;
   bool handle_mouse_event_;
+  double last_simulated_event_time_seconds_;
+  double simulated_event_time_delta_seconds_;
 
  private:
   SyntheticWebTouchEvent touch_event_;
@@ -947,15 +956,13 @@ TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
 // Tests setting custom background
 TEST_F(RenderWidgetHostTest, Background) {
 #if !defined(OS_MACOSX)
-  scoped_ptr<RenderWidgetHostView> view(
-      RenderWidgetHostView::CreateViewForWidget(host_.get()));
-#if defined(OS_LINUX) || defined(USE_AURA)
+  scoped_ptr<RenderWidgetHostViewBase> view;
+#if defined(USE_AURA)
+  view.reset(new RenderWidgetHostViewAura(host_.get()));
   // TODO(derat): Call this on all platforms: http://crbug.com/102450.
-  // InitAsChild doesn't seem to work if NULL parent is passed on Windows,
-  // which leads to DCHECK failure in RenderWidgetHostView::Destroy.
-  // When you enable this for OS_WIN, enable |view.release()->Destroy()|
-  // below.
   view->InitAsChild(NULL);
+#elif defined(OS_ANDROID)
+  view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL));
 #endif
   host_->SetView(view.get());
 
@@ -995,10 +1002,10 @@ TEST_F(RenderWidgetHostTest, Background) {
   sent_background.a.unlockPixels();
   background.unlockPixels();
 
-#if defined(OS_LINUX) || defined(USE_AURA)
+#if defined(USE_AURA)
   // See the comment above |InitAsChild(NULL)|.
   host_->SetView(NULL);
-  static_cast<RenderWidgetHostViewPort*>(view.release())->Destroy();
+  static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy();
 #endif
 
 #else
@@ -1011,68 +1018,6 @@ TEST_F(RenderWidgetHostTest, Background) {
   // since windows HDC structures are opaque.
 }
 
-// Tests getting the backing store with the renderer not setting repaint ack
-// flags.
-TEST_F(RenderWidgetHostTest, GetBackingStore_NoRepaintAck) {
-  // First set the view size to match what the renderer is rendering.
-  ViewHostMsg_UpdateRect_Params params;
-  process_->InitUpdateRectParams(&params);
-  view_->set_bounds(gfx::Rect(params.view_size));
-
-  // We don't currently have a backing store, and if the renderer doesn't send
-  // one in time, we should get nothing.
-  process_->set_update_msg_should_reply(false);
-  BackingStore* backing = host_->GetBackingStore(true);
-  EXPECT_FALSE(backing);
-  // The widget host should have sent a request for a repaint, and there should
-  // be no paint ACK.
-  EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Repaint::ID));
-  EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
-      ViewMsg_UpdateRect_ACK::ID));
-
-  // Allowing the renderer to reply in time should give is a backing store.
-  process_->sink().ClearMessages();
-  process_->set_update_msg_should_reply(true);
-  process_->set_update_msg_reply_flags(0);
-  backing = host_->GetBackingStore(true);
-  EXPECT_TRUE(backing);
-  // The widget host should NOT have sent a request for a repaint, since there
-  // was an ACK already pending.
-  EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Repaint::ID));
-  EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
-      ViewMsg_UpdateRect_ACK::ID));
-}
-
-// Tests getting the backing store with the renderer sending a repaint ack.
-TEST_F(RenderWidgetHostTest, GetBackingStore_RepaintAck) {
-  // First set the view size to match what the renderer is rendering.
-  ViewHostMsg_UpdateRect_Params params;
-  process_->InitUpdateRectParams(&params);
-  view_->set_bounds(gfx::Rect(params.view_size));
-
-  // Doing a request request with the update message allowed should work and
-  // the repaint ack should work.
-  process_->set_update_msg_should_reply(true);
-  process_->set_update_msg_reply_flags(
-      ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK);
-  BackingStore* backing = host_->GetBackingStore(true);
-  EXPECT_TRUE(backing);
-  // We still should not have sent out a repaint request since the last flags
-  // didn't have the repaint ack set, and the pending flag will still be set.
-  EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Repaint::ID));
-  EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
-      ViewMsg_UpdateRect_ACK::ID));
-
-  // Asking again for the backing store should just re-use the existing one
-  // and not send any messagse.
-  process_->sink().ClearMessages();
-  backing = host_->GetBackingStore(true);
-  EXPECT_TRUE(backing);
-  EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Repaint::ID));
-  EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
-      ViewMsg_UpdateRect_ACK::ID));
-}
-
 // Test that we don't paint when we're hidden, but we still send the ACK. Most
 // of the rest of the painting is tested in the GetBackingStore* ones.
 TEST_F(RenderWidgetHostTest, HiddenPaint) {
@@ -1089,10 +1034,6 @@ TEST_F(RenderWidgetHostTest, HiddenPaint) {
   process_->InitUpdateRectParams(&params);
   host_->OnUpdateRect(params);
 
-  // It should have sent out the ACK.
-  EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
-      ViewMsg_UpdateRect_ACK::ID));
-
   // Now unhide.
   process_->sink().ClearMessages();
   host_->WasShown();
@@ -1299,20 +1240,6 @@ TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
   EXPECT_TRUE(host_->unresponsive_timer_fired());
 }
 
-// This test is not valid for Windows because getting the shared memory
-// size doesn't work.
-#if !defined(OS_WIN)
-TEST_F(RenderWidgetHostTest, IncorrectBitmapScaleFactor) {
-  ViewHostMsg_UpdateRect_Params params;
-  process_->InitUpdateRectParams(&params);
-  params.scale_factor = params.scale_factor * 2;
-
-  EXPECT_EQ(0, process_->bad_msg_count());
-  host_->OnUpdateRect(params);
-  EXPECT_EQ(1, process_->bad_msg_count());
-}
-#endif
-
 // Tests that scroll ACKs are correctly handled by the overscroll-navigation
 // controller.
 TEST_F(RenderWidgetHostTest, WheelScrollEventOverscrolls) {
@@ -1589,7 +1516,6 @@ TEST_F(RenderWidgetHostTest, ScrollEventsOverscrollWithZeroFling) {
 // overscroll nav instead of completing it.
 TEST_F(RenderWidgetHostTest, ReverseFlingCancelsOverscroll) {
   host_->SetupForOverscrollControllerTest();
-  host_->DisableGestureDebounce();
   process_->sink().ClearMessages();
   view_->set_bounds(gfx::Rect(0, 0, 400, 200));
   view_->Show();
@@ -1601,8 +1527,6 @@ TEST_F(RenderWidgetHostTest, ReverseFlingCancelsOverscroll) {
     SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
                          WebGestureEvent::Touchscreen);
     SimulateGestureScrollUpdateEvent(300, -5, 0);
-    SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                      INPUT_EVENT_ACK_STATE_CONSUMED);
     SendInputEventACK(WebInputEvent::GestureScrollUpdate,
                       INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
     EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_mode());
@@ -1614,8 +1538,6 @@ TEST_F(RenderWidgetHostTest, ReverseFlingCancelsOverscroll) {
     EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_delegate()->completed_mode());
     EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode());
     EXPECT_EQ(1U, process_->sink().message_count());
-    SendInputEventACK(WebInputEvent::GestureScrollEnd,
-                      INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
   }
 
   {
@@ -1627,8 +1549,6 @@ TEST_F(RenderWidgetHostTest, ReverseFlingCancelsOverscroll) {
     SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
                          WebGestureEvent::Touchscreen);
     SimulateGestureScrollUpdateEvent(-300, -5, 0);
-    SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                      INPUT_EVENT_ACK_STATE_CONSUMED);
     SendInputEventACK(WebInputEvent::GestureScrollUpdate,
                       INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
     EXPECT_EQ(OVERSCROLL_WEST, host_->overscroll_mode());
@@ -1648,13 +1568,10 @@ TEST_F(RenderWidgetHostTest, ReverseFlingCancelsOverscroll) {
 TEST_F(RenderWidgetHostTest, GestureScrollOverscrolls) {
   // Turn off debounce handling for test isolation.
   host_->SetupForOverscrollControllerTest();
-  host_->DisableGestureDebounce();
   process_->sink().ClearMessages();
 
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
                        WebGestureEvent::Touchscreen);
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode());
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode());
 
@@ -1704,7 +1621,6 @@ TEST_F(RenderWidgetHostTest, GestureScrollOverscrolls) {
 TEST_F(RenderWidgetHostTest, GestureScrollConsumedHorizontal) {
   // Turn off debounce handling for test isolation.
   host_->SetupForOverscrollControllerTest();
-  host_->DisableGestureDebounce();
   process_->sink().ClearMessages();
 
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
@@ -1712,8 +1628,6 @@ TEST_F(RenderWidgetHostTest, GestureScrollConsumedHorizontal) {
   SimulateGestureScrollUpdateEvent(10, 0, 0);
 
   // Start scrolling on content. ACK both events as being processed.
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_CONSUMED);
   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
                     INPUT_EVENT_ACK_STATE_CONSUMED);
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode());
@@ -1743,8 +1657,6 @@ TEST_F(RenderWidgetHostTest, GestureScrollDebounceOverscrolls) {
                        WebGestureEvent::Touchscreen);
   EXPECT_EQ(1U, process_->sink().message_count());
   process_->sink().ClearMessages();
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_CONSUMED);
 
   // Send update events.
   SimulateGestureScrollUpdateEvent(25, 0, 0);
@@ -1823,8 +1735,6 @@ TEST_F(RenderWidgetHostTest, GestureScrollDebounceTimerOverscroll) {
                        WebGestureEvent::Touchscreen);
   EXPECT_EQ(1U, process_->sink().message_count());
   process_->sink().ClearMessages();
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_CONSUMED);
 
   // Send update events.
   SimulateGestureScrollUpdateEvent(55, 0, 0);
@@ -1905,8 +1815,6 @@ TEST_F(RenderWidgetHostTest, OverscrollWithTouchEvents) {
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
                        WebGestureEvent::Touchscreen);
   SimulateGestureScrollUpdateEvent(20, 0, 0);
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
                     INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode());
@@ -2021,8 +1929,6 @@ TEST_F(RenderWidgetHostTest, TouchGestureEndDispatchedAfterOverscrollComplete) {
   // router.
   EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
   process_->sink().ClearMessages();
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_CONSUMED);
   EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
   EXPECT_EQ(0U, process_->sink().message_count());
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode());
@@ -2068,12 +1974,7 @@ TEST_F(RenderWidgetHostTest, TouchGestureEndDispatchedAfterOverscrollComplete) {
   // router.
   EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
   EXPECT_EQ(0U, host_->GestureEventDebouncingQueueSize());
-
-  SendInputEventACK(blink::WebInputEvent::GestureScrollEnd,
-                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
   EXPECT_EQ(0U, process_->sink().message_count());
-  EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
-  EXPECT_EQ(0U, host_->GestureEventDebouncingQueueSize());
 
   // Start scrolling. Receive ACK as it being processed.
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
@@ -2083,8 +1984,6 @@ TEST_F(RenderWidgetHostTest, TouchGestureEndDispatchedAfterOverscrollComplete) {
   // router.
   EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
   process_->sink().ClearMessages();
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_CONSUMED);
   EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
   EXPECT_EQ(0U, process_->sink().message_count());
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode());
@@ -2131,12 +2030,7 @@ TEST_F(RenderWidgetHostTest, TouchGestureEndDispatchedAfterOverscrollComplete) {
   // router.
   EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
   EXPECT_EQ(0U, host_->GestureEventDebouncingQueueSize());
-
-  SendInputEventACK(blink::WebInputEvent::GestureScrollEnd,
-                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
   EXPECT_EQ(0U, process_->sink().message_count());
-  EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize());
-  EXPECT_EQ(0U, host_->GestureEventDebouncingQueueSize());
 }
 
 TEST_F(RenderWidgetHostTest, OverscrollDirectionChange) {
@@ -2149,8 +2043,6 @@ TEST_F(RenderWidgetHostTest, OverscrollDirectionChange) {
                        WebGestureEvent::Touchscreen);
   EXPECT_EQ(1U, process_->sink().message_count());
   process_->sink().ClearMessages();
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_CONSUMED);
 
   // Send update events and receive ack as not consumed.
   SimulateGestureScrollUpdateEvent(125, -5, 0);
@@ -2183,7 +2075,6 @@ TEST_F(RenderWidgetHostTest, OverscrollDirectionChange) {
 // move events do reach the renderer.
 TEST_F(RenderWidgetHostTest, OverscrollMouseMoveCompletion) {
   host_->SetupForOverscrollControllerTest();
-  host_->DisableGestureDebounce();
   process_->sink().ClearMessages();
   view_->set_bounds(gfx::Rect(0, 0, 400, 200));
   view_->Show();
@@ -2237,8 +2128,6 @@ TEST_F(RenderWidgetHostTest, OverscrollMouseMoveCompletion) {
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
                        WebGestureEvent::Touchscreen);
   SimulateGestureScrollUpdateEvent(300, -5, 0);
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_CONSUMED);
   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
                     INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
   EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_mode());
@@ -2262,8 +2151,6 @@ TEST_F(RenderWidgetHostTest, OverscrollMouseMoveCompletion) {
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode());
   EXPECT_EQ(1U, process_->sink().message_count());
   process_->sink().ClearMessages();
-  SendInputEventACK(WebInputEvent::GestureScrollEnd,
-                    INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
 
   // Move mouse some more. The mouse-move events should reach the renderer.
   SimulateMouseMove(5, 10, 0);
@@ -2278,7 +2165,6 @@ TEST_F(RenderWidgetHostTest, OverscrollMouseMoveCompletion) {
 // reset after the end of the scroll.
 TEST_F(RenderWidgetHostTest, OverscrollStateResetsAfterScroll) {
   host_->SetupForOverscrollControllerTest();
-  host_->DisableGestureDebounce();
   process_->sink().ClearMessages();
   view_->set_bounds(gfx::Rect(0, 0, 400, 200));
   view_->Show();
@@ -2349,12 +2235,11 @@ TEST_F(RenderWidgetHostTest, OverscrollResetsOnBlur) {
   SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
                        WebGestureEvent::Touchscreen);
   SimulateGestureScrollUpdateEvent(300, -5, 0);
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_CONSUMED);
   SendInputEventACK(WebInputEvent::GestureScrollUpdate,
                     INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
   EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_mode());
   EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_delegate()->current_mode());
+  EXPECT_EQ(2U, process_->sink().message_count());
 
   host_->Blur();
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode());
@@ -2366,7 +2251,8 @@ TEST_F(RenderWidgetHostTest, OverscrollResetsOnBlur) {
 
   SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
                        WebGestureEvent::Touchscreen);
-  EXPECT_EQ(0U, process_->sink().message_count());
+  EXPECT_EQ(1U, process_->sink().message_count());
+  process_->sink().ClearMessages();
 
   // Start a scroll gesture again. This should correctly start the overscroll
   // after the threshold.
@@ -2383,7 +2269,173 @@ TEST_F(RenderWidgetHostTest, OverscrollResetsOnBlur) {
                        WebGestureEvent::Touchscreen);
   EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode());
   EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_delegate()->completed_mode());
+  EXPECT_EQ(3U, process_->sink().message_count());
+}
+
+std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
+  const WebInputEvent* event = NULL;
+  ui::LatencyInfo latency_info;
+  bool is_keyboard_shortcut;
+  std::string result;
+  for (size_t i = 0; i < process->sink().message_count(); ++i) {
+    const IPC::Message *message = process->sink().GetMessageAt(i);
+    EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type());
+    EXPECT_TRUE(InputMsg_HandleInputEvent::Read(
+        message, &event, &latency_info, &is_keyboard_shortcut));
+    if (i != 0)
+      result += " ";
+    result += WebInputEventTraits::GetName(event->type);
+  }
+  process->sink().ClearMessages();
+  return result;
+}
+
+TEST_F(RenderWidgetHostTest, TouchEmulator) {
+  simulated_event_time_delta_seconds_ = 0.1;
+  // Immediately ack all touches instead of sending them to the renderer.
+  host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
+  host_->OnMessageReceived(
+      ViewHostMsg_SetTouchEventEmulationEnabled(0, true, true));
   process_->sink().ClearMessages();
+  view_->set_bounds(gfx::Rect(0, 0, 400, 200));
+  view_->Show();
+
+  SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false);
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Mouse press becomes touch start which in turn becomes tap.
+  SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
+  EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
+  EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
+
+  // Mouse drag generates touch move, cancels tap and starts scroll.
+  SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
+  EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
+  EXPECT_EQ(
+      "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
+      GetInputMessageTypes(process_));
+  SendInputEventACK(WebInputEvent::GestureScrollUpdate,
+                    INPUT_EVENT_ACK_STATE_CONSUMED);
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Mouse drag with shift becomes pinch.
+  SimulateMouseEvent(
+      WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true);
+  EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
+  EXPECT_EQ("GesturePinchBegin",
+            GetInputMessageTypes(process_));
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  SimulateMouseEvent(
+      WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true);
+  EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
+  EXPECT_EQ("GesturePinchUpdate",
+            GetInputMessageTypes(process_));
+  SendInputEventACK(WebInputEvent::GesturePinchUpdate,
+                    INPUT_EVENT_ACK_STATE_CONSUMED);
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Mouse drag without shift becomes scroll again.
+  SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true);
+  EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
+  EXPECT_EQ("GesturePinchEnd GestureScrollUpdate",
+            GetInputMessageTypes(process_));
+  SendInputEventACK(WebInputEvent::GestureScrollUpdate,
+                    INPUT_EVENT_ACK_STATE_CONSUMED);
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true);
+  EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
+  EXPECT_EQ("GestureScrollUpdate",
+            GetInputMessageTypes(process_));
+  SendInputEventACK(WebInputEvent::GestureScrollUpdate,
+                    INPUT_EVENT_ACK_STATE_CONSUMED);
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true);
+  EXPECT_EQ(WebInputEvent::TouchEnd, host_->acked_touch_event_type());
+  EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Mouse move does nothing.
+  SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false);
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Another mouse down continues scroll.
+  SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true);
+  EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
+  EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true);
+  EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
+  EXPECT_EQ(
+      "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
+      GetInputMessageTypes(process_));
+  SendInputEventACK(WebInputEvent::GestureScrollUpdate,
+                    INPUT_EVENT_ACK_STATE_CONSUMED);
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Another pinch.
+  SimulateMouseEvent(
+      WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true);
+  EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
+  EXPECT_EQ("GesturePinchBegin",
+            GetInputMessageTypes(process_));
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  SimulateMouseEvent(
+      WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true);
+  EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
+  EXPECT_EQ("GesturePinchUpdate",
+            GetInputMessageTypes(process_));
+  SendInputEventACK(WebInputEvent::GesturePinchUpdate,
+                    INPUT_EVENT_ACK_STATE_CONSUMED);
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Turn off emulation during a pinch.
+  host_->OnMessageReceived(
+      ViewHostMsg_SetTouchEventEmulationEnabled(0, false, false));
+  EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
+  EXPECT_EQ("GesturePinchEnd GestureScrollEnd",
+            GetInputMessageTypes(process_));
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Mouse event should pass untouched.
+  SimulateMouseEvent(
+      WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true);
+  EXPECT_EQ("MouseMove", GetInputMessageTypes(process_));
+  SendInputEventACK(WebInputEvent::MouseMove,
+                    INPUT_EVENT_ACK_STATE_CONSUMED);
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Turn on emulation.
+  host_->OnMessageReceived(
+      ViewHostMsg_SetTouchEventEmulationEnabled(0, true, true));
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Another touch.
+  SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true);
+  EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type());
+  EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_));
+  EXPECT_EQ(0U, process_->sink().message_count());
+
+  // Scroll.
+  SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true);
+  EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type());
+  EXPECT_EQ(
+      "GestureTapCancel GestureScrollBegin GestureScrollUpdate",
+      GetInputMessageTypes(process_));
+  SendInputEventACK(WebInputEvent::GestureScrollUpdate,
+                    INPUT_EVENT_ACK_STATE_CONSUMED);
+
+  // Turn off emulation during a scroll.
+  host_->OnMessageReceived(
+      ViewHostMsg_SetTouchEventEmulationEnabled(0, false, false));
+  EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type());
+
+  EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_));
+  EXPECT_EQ(0U, process_->sink().message_count());
 }
 
 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \
@@ -2423,13 +2475,14 @@ TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect);
 
 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplace) {
   host_->SetupForInputRouterTest();
-  host_->Replace(base::string16());
+  host_->Send(new InputMsg_Replace(host_->GetRoutingID(), base::string16()));
   EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
 }
 
 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplaceMisspelling) {
   host_->SetupForInputRouterTest();
-  host_->ReplaceMisspelling(base::string16());
+  host_->Send(new InputMsg_ReplaceMisspelling(host_->GetRoutingID(),
+                                              base::string16()));
   EXPECT_TRUE(host_->mock_input_router()->send_event_called_);
 }
 
@@ -2604,8 +2657,6 @@ TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
                        WebGestureEvent::Touchscreen);
   CheckLatencyInfoComponentInMessage(
       process_, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin);
-  SendInputEventACK(WebInputEvent::GestureScrollBegin,
-                    INPUT_EVENT_ACK_STATE_CONSUMED);
 
   // Tests RWHI::ForwardGestureEventWithLatencyInfo().
   SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate,