Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / renderer / input / input_handler_proxy.cc
index 951cec1..6970d22 100644 (file)
@@ -5,11 +5,13 @@
 #include "content/renderer/input/input_handler_proxy.h"
 
 #include "base/auto_reset.h"
+#include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
 #include "content/common/input/did_overscroll_params.h"
 #include "content/common/input/web_input_event_traits.h"
+#include "content/public/common/content_switches.h"
 #include "content/renderer/input/input_handler_proxy_client.h"
 #include "third_party/WebKit/public/platform/Platform.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
@@ -157,6 +159,8 @@ InputHandlerProxy::InputHandlerProxy(cc::InputHandler* input_handler,
       has_fling_animation_started_(false) {
   DCHECK(client);
   input_handler_->BindToClient(this);
+  smooth_scroll_enabled_ = CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kEnableSmoothScrolling);
 }
 
 InputHandlerProxy::~InputHandlerProxy() {}
@@ -174,11 +178,10 @@ InputHandlerProxy::HandleInputEventWithLatencyInfo(
 
   SendScrollLatencyUma(event, *latency_info);
 
-  TRACE_EVENT_FLOW_STEP0(
-      "input",
-      "LatencyInfo.Flow",
-      TRACE_ID_DONT_MANGLE(latency_info->trace_id),
-      "HanldeInputEventImpl");
+  TRACE_EVENT_FLOW_STEP0("input",
+                         "LatencyInfo.Flow",
+                         TRACE_ID_DONT_MANGLE(latency_info->trace_id),
+                         "HandleInputEventImpl");
 
   scoped_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor =
       input_handler_->CreateLatencyInfoSwapPromiseMonitor(latency_info);
@@ -208,6 +211,20 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent(
       // event handlers.  Forward to the main thread.
       return DID_NOT_HANDLE;
     }
+    if (smooth_scroll_enabled_) {
+      cc::InputHandler::ScrollStatus scroll_status =
+          input_handler_->ScrollAnimated(
+              gfx::Point(wheel_event.x, wheel_event.y),
+              gfx::Vector2dF(-wheel_event.deltaX, -wheel_event.deltaY));
+      switch (scroll_status) {
+        case cc::InputHandler::ScrollStarted:
+          return DID_HANDLE;
+        case cc::InputHandler::ScrollIgnored:
+          return DROP_EVENT;
+        default:
+          return DID_NOT_HANDLE;
+      }
+    }
     cc::InputHandler::ScrollStatus scroll_status = input_handler_->ScrollBegin(
         gfx::Point(wheel_event.x, wheel_event.y), cc::InputHandler::Wheel);
     switch (scroll_status) {
@@ -319,7 +336,7 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent(
         *static_cast<const WebGestureEvent*>(&event);
     return HandleGestureFling(gesture_event);
   } else if (event.type == WebInputEvent::GestureFlingCancel) {
-    if (CancelCurrentFling(true))
+    if (CancelCurrentFling())
       return DID_HANDLE;
     else if (!fling_may_be_active_on_main_thread_)
       return DROP_EVENT;
@@ -340,7 +357,7 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent(
     // Only call |CancelCurrentFling()| if a fling was active, as it will
     // otherwise disrupt an in-progress touch scroll.
     if (fling_curve_)
-      CancelCurrentFling(true);
+      CancelCurrentFling();
   } else if (event.type == WebInputEvent::MouseMove) {
     const WebMouseEvent& mouse_event =
         *static_cast<const WebMouseEvent*>(&event);
@@ -468,7 +485,7 @@ bool InputHandlerProxy::FilterInputEventForFlingBoosting(
 
   // Gestures from a different source should immediately interrupt the fling.
   if (gesture_event.sourceDevice != fling_parameters_.sourceDevice) {
-    FlingBoostCancelAndResumeScrollingIfNecessary();
+    CancelCurrentFling();
     return false;
   }
 
@@ -483,13 +500,13 @@ bool InputHandlerProxy::FilterInputEventForFlingBoosting(
               fling_parameters_.sourceDevice == blink::WebGestureDeviceTouchpad
                   ? cc::InputHandler::NonBubblingGesture
                   : cc::InputHandler::Gesture)) {
-        CancelCurrentFling(true);
+        CancelCurrentFling();
         return false;
       }
 
       // TODO(jdduke): Use |gesture_event.data.scrollBegin.delta{X,Y}Hint| to
       // determine if the ScrollBegin should immediately cancel the fling.
-      FlingBoostExtend(gesture_event);
+      ExtendBoostedFlingTimeout(gesture_event);
       return true;
 
     case WebInputEvent::GestureScrollUpdate: {
@@ -498,16 +515,19 @@ bool InputHandlerProxy::FilterInputEventForFlingBoosting(
       if (ShouldSuppressScrollForFlingBoosting(current_fling_velocity_,
                                                gesture_event,
                                                time_since_last_boost_event)) {
-        FlingBoostExtend(gesture_event);
+        ExtendBoostedFlingTimeout(gesture_event);
         return true;
       }
 
-      FlingBoostCancelAndResumeScrollingIfNecessary();
+      CancelCurrentFling();
       return false;
     }
 
     case WebInputEvent::GestureScrollEnd:
-      CancelCurrentFling(true);
+      // Clear the last fling boost event *prior* to fling cancellation,
+      // preventing insertion of a synthetic GestureScrollBegin.
+      last_fling_boost_event_ = WebGestureEvent();
+      CancelCurrentFling();
       return true;
 
     case WebInputEvent::GestureFlingStart: {
@@ -559,36 +579,21 @@ bool InputHandlerProxy::FilterInputEventForFlingBoosting(
     default:
       // All other types of gestures (taps, presses, etc...) will complete the
       // deferred fling cancellation.
-      FlingBoostCancelAndResumeScrollingIfNecessary();
+      CancelCurrentFling();
       return false;
   }
 }
 
-void InputHandlerProxy::FlingBoostExtend(const blink::WebGestureEvent& event) {
-  TRACE_EVENT_INSTANT0(
-      "input", "InputHandlerProxy::FlingBoostExtend", TRACE_EVENT_SCOPE_THREAD);
+void InputHandlerProxy::ExtendBoostedFlingTimeout(
+    const blink::WebGestureEvent& event) {
+  TRACE_EVENT_INSTANT0("input",
+                       "InputHandlerProxy::ExtendBoostedFlingTimeout",
+                       TRACE_EVENT_SCOPE_THREAD);
   deferred_fling_cancel_time_seconds_ =
       event.timeStampSeconds + kFlingBoostTimeoutDelaySeconds;
   last_fling_boost_event_ = event;
 }
 
-void InputHandlerProxy::FlingBoostCancelAndResumeScrollingIfNecessary() {
-  TRACE_EVENT_INSTANT0(
-      "input", "InputHandlerProxy::FlingBoostCancel", TRACE_EVENT_SCOPE_THREAD);
-  DCHECK(deferred_fling_cancel_time_seconds_);
-
-  // Note: |last_fling_boost_event_| is cleared by |CancelCurrentFling()|.
-  WebGestureEvent last_fling_boost_event = last_fling_boost_event_;
-
-  CancelCurrentFling(true);
-
-  if (last_fling_boost_event.type == WebInputEvent::GestureScrollBegin ||
-      last_fling_boost_event.type == WebInputEvent::GestureScrollUpdate) {
-    // Synthesize a GestureScrollBegin, as the original was suppressed.
-    HandleInputEvent(ObtainGestureScrollBegin(last_fling_boost_event));
-  }
-}
-
 void InputHandlerProxy::Animate(base::TimeTicks time) {
   if (!fling_curve_)
     return;
@@ -597,7 +602,7 @@ void InputHandlerProxy::Animate(base::TimeTicks time) {
 
   if (deferred_fling_cancel_time_seconds_ &&
       monotonic_time_sec > deferred_fling_cancel_time_seconds_) {
-    FlingBoostCancelAndResumeScrollingIfNecessary();
+    CancelCurrentFling();
     return;
   }
 
@@ -628,7 +633,7 @@ void InputHandlerProxy::Animate(base::TimeTicks time) {
     TRACE_EVENT_INSTANT0("input",
                          "InputHandlerProxy::animate::flingOver",
                          TRACE_EVENT_SCOPE_THREAD);
-    CancelCurrentFling(true);
+    CancelCurrentFling();
   }
 }
 
@@ -638,6 +643,7 @@ void InputHandlerProxy::MainThreadHasStoppedFlinging() {
 }
 
 void InputHandlerProxy::DidOverscroll(
+    const gfx::PointF& causal_event_viewport_point,
     const gfx::Vector2dF& accumulated_overscroll,
     const gfx::Vector2dF& latest_overscroll_delta) {
   DCHECK(client_);
@@ -654,6 +660,7 @@ void InputHandlerProxy::DidOverscroll(
   params.latest_overscroll_delta = latest_overscroll_delta;
   params.current_fling_velocity =
       ToClientScrollIncrement(current_fling_velocity_);
+  params.causal_event_viewport_point = causal_event_viewport_point;
 
   if (fling_curve_) {
     static const int kFlingOverscrollThreshold = 1;
@@ -668,8 +675,15 @@ void InputHandlerProxy::DidOverscroll(
   client_->DidOverscroll(params);
 }
 
-bool InputHandlerProxy::CancelCurrentFling(
-    bool send_fling_stopped_notification) {
+bool InputHandlerProxy::CancelCurrentFling() {
+  if (CancelCurrentFlingWithoutNotifyingClient()) {
+    client_->DidStopFlinging();
+    return true;
+  }
+  return false;
+}
+
+bool InputHandlerProxy::CancelCurrentFlingWithoutNotifyingClient() {
   bool had_fling_animation = fling_curve_;
   if (had_fling_animation &&
       fling_parameters_.sourceDevice == blink::WebGestureDeviceTouchscreen) {
@@ -690,10 +704,19 @@ bool InputHandlerProxy::CancelCurrentFling(
   gesture_scroll_on_impl_thread_ = false;
   current_fling_velocity_ = gfx::Vector2dF();
   fling_parameters_ = blink::WebActiveWheelFlingParameters();
-  deferred_fling_cancel_time_seconds_ = 0;
-  last_fling_boost_event_ = WebGestureEvent();
-  if (send_fling_stopped_notification && had_fling_animation)
-    client_->DidStopFlinging();
+
+  if (deferred_fling_cancel_time_seconds_) {
+    deferred_fling_cancel_time_seconds_ = 0;
+
+    WebGestureEvent last_fling_boost_event = last_fling_boost_event_;
+    last_fling_boost_event_ = WebGestureEvent();
+    if (last_fling_boost_event.type == WebInputEvent::GestureScrollBegin ||
+        last_fling_boost_event.type == WebInputEvent::GestureScrollUpdate) {
+      // Synthesize a GestureScrollBegin, as the original was suppressed.
+      HandleInputEvent(ObtainGestureScrollBegin(last_fling_boost_event));
+    }
+  }
+
   return had_fling_animation;
 }
 
@@ -729,7 +752,7 @@ bool InputHandlerProxy::TouchpadFlingScroll(
       // the subarea but then is flung "under" the pointer.
       client_->TransferActiveWheelFlingAnimation(fling_parameters_);
       fling_may_be_active_on_main_thread_ = true;
-      CancelCurrentFling(false);
+      CancelCurrentFlingWithoutNotifyingClient();
       break;
   }