Upstream version 7.35.139.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / input / touch_event_queue.h
index aa2eb11..03d3210 100644 (file)
@@ -9,10 +9,12 @@
 #include <map>
 
 #include "base/basictypes.h"
+#include "base/time/time.h"
 #include "content/common/content_export.h"
 #include "content/port/browser/event_with_latency_info.h"
 #include "content/port/common/input_event_ack_state.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/gfx/geometry/point_f.h"
 
 namespace content {
 
@@ -35,9 +37,31 @@ class CONTENT_EXPORT TouchEventQueueClient {
 // A queue for throttling and coalescing touch-events.
 class CONTENT_EXPORT TouchEventQueue {
  public:
+  // Different ways of dealing with touch events during scrolling.
+  // TODO(rbyers): Remove this once we're confident that touch move absorption
+  // is OK. http://crbug.com/350430
+  enum TouchScrollingMode {
+    // Send a touchcancel on scroll start and no further touch events for the
+    // duration of the scroll.  Chrome Android's traditional behavior.
+    TOUCH_SCROLLING_MODE_TOUCHCANCEL,
+    // Send touchmove events throughout a scroll, blocking on each ACK and
+    // using the disposition to determine whether a scroll update should be
+    // sent.  Mobile Safari's default overflow scroll behavior.
+    TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE,
+    // Like sync, except that consumed scroll events cause subsequent touchmove
+    // events to be suppressed.  Unconsumed scroll events return touchmove
+    // events to being dispatched synchronously (so scrolling may be hijacked
+    // when a scroll limit is reached, and later resumed). http://goo.gl/RShsdN
+    TOUCH_SCROLLING_MODE_ABSORB_TOUCHMOVE,
+    TOUCH_SCROLLING_MODE_DEFAULT = TOUCH_SCROLLING_MODE_TOUCHCANCEL
+  };
 
-  // The |client| must outlive the TouchEventQueue.
-  explicit TouchEventQueue(TouchEventQueueClient* client);
+  // The |client| must outlive the TouchEventQueue. If
+  // |touchmove_suppression_length_dips| <= 0, touch move suppression is
+  // disabled.
+  TouchEventQueue(TouchEventQueueClient* client,
+                  TouchScrollingMode mode,
+                  double touchmove_suppression_length_dips);
   ~TouchEventQueue();
 
   // Adds an event to the queue. The event may be coalesced with previously
@@ -58,6 +82,10 @@ class CONTENT_EXPORT TouchEventQueue {
   // resume the normal flow of sending touch events to the renderer.
   void OnGestureScrollEvent(const GestureEventWithLatencyInfo& gesture_event);
 
+  void OnGestureEventAck(
+      const GestureEventWithLatencyInfo& event,
+      InputEventAckState ack_result);
+
   // Notifies the queue whether the renderer has at least one touch handler.
   void OnHasTouchEventHandlers(bool has_handlers);
 
@@ -66,8 +94,9 @@ class CONTENT_EXPORT TouchEventQueue {
   bool IsPendingAckTouchStart() const;
 
   // Sets whether a delayed touch ack will cancel and flush the current
-  // touch sequence.
-  void SetAckTimeoutEnabled(bool enabled, size_t ack_timeout_delay_ms);
+  // touch sequence. Note that, if the timeout was previously disabled, enabling
+  // it will take effect only for the following touch sequence.
+  void SetAckTimeoutEnabled(bool enabled, base::TimeDelta ack_timeout_delay);
 
   bool empty() const WARN_UNUSED_RESULT {
     return touch_queue_.empty();
@@ -87,6 +116,7 @@ class CONTENT_EXPORT TouchEventQueue {
 
  private:
   class TouchTimeoutHandler;
+  class TouchMoveSlopSuppressor;
   friend class TouchTimeoutHandler;
   friend class TouchEventQueueTest;
 
@@ -108,7 +138,14 @@ class CONTENT_EXPORT TouchEventQueue {
   void PopTouchEventToClient(InputEventAckState ack_result,
                              const ui::LatencyInfo& renderer_latency_info);
 
-  bool ShouldForwardToRenderer(const blink::WebTouchEvent& event) const;
+  enum PreFilterResult {
+    ACK_WITH_NO_CONSUMER_EXISTS,
+    ACK_WITH_NOT_CONSUMED,
+    FORWARD_TO_RENDERER,
+  };
+  // Filter touches prior to forwarding to the renderer, e.g., if the renderer
+  // has no touch handler.
+  PreFilterResult FilterBeforeForwarding(const blink::WebTouchEvent& event);
   void ForwardToRenderer(const TouchEventWithLatencyInfo& event);
   void UpdateTouchAckStates(const blink::WebTouchEvent& event,
                             InputEventAckState ack_result);
@@ -147,6 +184,22 @@ class CONTENT_EXPORT TouchEventQueue {
   bool ack_timeout_enabled_;
   scoped_ptr<TouchTimeoutHandler> timeout_handler_;
 
+  // Suppression of TouchMove's within a slop region when a sequence has not yet
+  // been preventDefaulted.
+  scoped_ptr<TouchMoveSlopSuppressor> touchmove_slop_suppressor_;
+
+  // Whether touchmove events should be dropped due to the
+  // TOUCH_SCROLLING_MODE_ABSORB_TOUCHMOVE mode.  Note that we can't use
+  // touch_filtering_state_ for this (without adding a few new states and
+  // complicating the code significantly) because it can occur with and without
+  // timeout, and shouldn't cause touchend to be dropped.
+  bool absorbing_touch_moves_;
+
+  // How touch events are handled during scrolling.  For now this is a global
+  // setting for experimentation, but we may evolve it into an app-controlled
+  // mode.
+  const TouchScrollingMode touch_scrolling_mode_;
+
   DISALLOW_COPY_AND_ASSIGN(TouchEventQueue);
 };