Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / events / gesture_detection / touch_disposition_gesture_filter.cc
index 5105d6d..323c7aa 100644 (file)
@@ -17,9 +17,11 @@ COMPILE_ASSERT(ET_GESTURE_TYPE_END - ET_GESTURE_TYPE_START < 32,
 
 GestureEventData CreateGesture(EventType type,
                                int motion_event_id,
+                               MotionEvent::ToolType primary_tool_type,
                                const GestureEventDataPacket& packet) {
   return GestureEventData(GestureEventDetails(type, 0, 0),
                           motion_event_id,
+                          primary_tool_type,
                           packet.timestamp(),
                           packet.touch_location().x(),
                           packet.touch_location().y(),
@@ -78,7 +80,7 @@ DispositionHandlingInfo GetDispositionHandlingInfo(EventType type) {
     case ET_GESTURE_DOUBLE_TAP:
       return Info(RT_START | RT_CURRENT, ET_GESTURE_TAP_UNCONFIRMED);
     case ET_GESTURE_SCROLL_BEGIN:
-      return Info(RT_START | RT_CURRENT);
+      return Info(RT_START);
     case ET_GESTURE_SCROLL_UPDATE:
       return Info(RT_CURRENT, ET_GESTURE_SCROLL_BEGIN);
     case ET_GESTURE_SCROLL_END:
@@ -128,16 +130,16 @@ bool IsTouchStartEvent(GestureEventDataPacket::GestureSource gesture_source) {
 TouchDispositionGestureFilter::TouchDispositionGestureFilter(
     TouchDispositionGestureFilterClient* client)
     : client_(client),
+      ending_event_motion_event_id_(0),
+      ending_event_primary_tool_type_(MotionEvent::TOOL_TYPE_UNKNOWN),
       needs_tap_ending_event_(false),
       needs_show_press_event_(false),
       needs_fling_ending_event_(false),
-      needs_scroll_ending_event_(false),
-      packet_being_sent_(NULL) {
+      needs_scroll_ending_event_(false) {
   DCHECK(client_);
 }
 
 TouchDispositionGestureFilter::~TouchDispositionGestureFilter() {
-  DCHECK(!packet_being_sent_);
 }
 
 TouchDispositionGestureFilter::PacketResult
@@ -210,14 +212,12 @@ bool TouchDispositionGestureFilter::IsEmpty() const {
 
 void TouchDispositionGestureFilter::FilterAndSendPacket(
     const GestureEventDataPacket& packet) {
-  base::AutoReset<const GestureEventDataPacket*> packet_being_sent(
-      &packet_being_sent_, &packet);
   if (packet.gesture_source() == GestureEventDataPacket::TOUCH_SEQUENCE_START) {
-    CancelTapIfNecessary();
-    EndScrollIfNecessary();
-    CancelFlingIfNecessary();
+    CancelTapIfNecessary(packet);
+    EndScrollIfNecessary(packet);
+    CancelFlingIfNecessary(packet);
   } else if (packet.gesture_source() == GestureEventDataPacket::TOUCH_START) {
-    CancelTapIfNecessary();
+    CancelTapIfNecessary(packet);
   }
 
   for (size_t i = 0; i < packet.gesture_count(); ++i) {
@@ -225,35 +225,45 @@ void TouchDispositionGestureFilter::FilterAndSendPacket(
     DCHECK_GE(gesture.details.type(), ET_GESTURE_TYPE_START);
     DCHECK_LE(gesture.details.type(), ET_GESTURE_TYPE_END);
     if (state_.Filter(gesture.details.type())) {
-      CancelTapIfNecessary();
+      CancelTapIfNecessary(packet);
       continue;
     }
-    SendGesture(gesture);
+    if (packet.gesture_source() == GestureEventDataPacket::TOUCH_TIMEOUT) {
+      // Sending a timed gesture could delete |this|, so we need to return
+      // directly after the |SendGesture| call.
+      SendGesture(gesture, packet);
+      return;
+    }
+
+    SendGesture(gesture, packet);
   }
 
   if (packet.gesture_source() ==
       GestureEventDataPacket::TOUCH_SEQUENCE_CANCEL) {
-    EndScrollIfNecessary();
-    CancelTapIfNecessary();
+    EndScrollIfNecessary(packet);
+    CancelTapIfNecessary(packet);
   } else if (packet.gesture_source() ==
              GestureEventDataPacket::TOUCH_SEQUENCE_END) {
-    EndScrollIfNecessary();
+    EndScrollIfNecessary(packet);
   }
 }
 
-void TouchDispositionGestureFilter::SendGesture(const GestureEventData& event) {
+void TouchDispositionGestureFilter::SendGesture(
+    const GestureEventData& event,
+    const GestureEventDataPacket& packet_being_sent) {
   // TODO(jdduke): Factor out gesture stream reparation code into a standalone
   // utility class.
   switch (event.type()) {
     case ET_GESTURE_LONG_TAP:
       if (!needs_tap_ending_event_)
         return;
-      CancelTapIfNecessary();
-      CancelFlingIfNecessary();
+      CancelTapIfNecessary(packet_being_sent);
+      CancelFlingIfNecessary(packet_being_sent);
       break;
     case ET_GESTURE_TAP_DOWN:
       DCHECK(!needs_tap_ending_event_);
       ending_event_motion_event_id_ = event.motion_event_id;
+      ending_event_primary_tool_type_ = event.primary_tool_type;
       needs_show_press_event_ = true;
       needs_tap_ending_event_ = true;
       break;
@@ -263,13 +273,14 @@ void TouchDispositionGestureFilter::SendGesture(const GestureEventData& event) {
       needs_show_press_event_ = false;
       break;
     case ET_GESTURE_DOUBLE_TAP:
-      CancelTapIfNecessary();
+      CancelTapIfNecessary(packet_being_sent);
       needs_show_press_event_ = false;
       break;
     case ET_GESTURE_TAP:
       DCHECK(needs_tap_ending_event_);
       if (needs_show_press_event_) {
-        SendGesture(GestureEventData(ET_GESTURE_SHOW_PRESS, event));
+        SendGesture(GestureEventData(ET_GESTURE_SHOW_PRESS, event),
+                    packet_being_sent);
         DCHECK(!needs_show_press_event_);
       }
       needs_tap_ending_event_ = false;
@@ -279,18 +290,20 @@ void TouchDispositionGestureFilter::SendGesture(const GestureEventData& event) {
       needs_tap_ending_event_ = false;
       break;
     case ET_GESTURE_SCROLL_BEGIN:
-      CancelTapIfNecessary();
-      CancelFlingIfNecessary();
-      EndScrollIfNecessary();
+      CancelTapIfNecessary(packet_being_sent);
+      CancelFlingIfNecessary(packet_being_sent);
+      EndScrollIfNecessary(packet_being_sent);
       ending_event_motion_event_id_ = event.motion_event_id;
+      ending_event_primary_tool_type_ = event.primary_tool_type;
       needs_scroll_ending_event_ = true;
       break;
     case ET_GESTURE_SCROLL_END:
       needs_scroll_ending_event_ = false;
       break;
     case ET_SCROLL_FLING_START:
-      CancelFlingIfNecessary();
+      CancelFlingIfNecessary(packet_being_sent);
       ending_event_motion_event_id_ = event.motion_event_id;
+      ending_event_primary_tool_type_ = event.primary_tool_type;
       needs_fling_ending_event_ = true;
       needs_scroll_ending_event_ = false;
       break;
@@ -303,36 +316,42 @@ void TouchDispositionGestureFilter::SendGesture(const GestureEventData& event) {
   client_->ForwardGestureEvent(event);
 }
 
-void TouchDispositionGestureFilter::CancelTapIfNecessary() {
-  DCHECK(packet_being_sent_);
-  if (!needs_tap_ending_event_ || !packet_being_sent_)
+void TouchDispositionGestureFilter::CancelTapIfNecessary(
+    const GestureEventDataPacket& packet_being_sent) {
+  if (!needs_tap_ending_event_)
     return;
 
   SendGesture(CreateGesture(ET_GESTURE_TAP_CANCEL,
                             ending_event_motion_event_id_,
-                            *packet_being_sent_));
+                            ending_event_primary_tool_type_,
+                            packet_being_sent),
+              packet_being_sent);
   DCHECK(!needs_tap_ending_event_);
 }
 
-void TouchDispositionGestureFilter::CancelFlingIfNecessary() {
-  DCHECK(packet_being_sent_);
-  if (!needs_fling_ending_event_ || !packet_being_sent_)
+void TouchDispositionGestureFilter::CancelFlingIfNecessary(
+    const GestureEventDataPacket& packet_being_sent) {
+  if (!needs_fling_ending_event_)
     return;
 
   SendGesture(CreateGesture(ET_SCROLL_FLING_CANCEL,
                             ending_event_motion_event_id_,
-                            *packet_being_sent_));
+                            ending_event_primary_tool_type_,
+                            packet_being_sent),
+              packet_being_sent);
   DCHECK(!needs_fling_ending_event_);
 }
 
-void TouchDispositionGestureFilter::EndScrollIfNecessary() {
-  DCHECK(packet_being_sent_);
-  if (!needs_scroll_ending_event_ || !packet_being_sent_)
+void TouchDispositionGestureFilter::EndScrollIfNecessary(
+    const GestureEventDataPacket& packet_being_sent) {
+  if (!needs_scroll_ending_event_)
     return;
 
   SendGesture(CreateGesture(ET_GESTURE_SCROLL_END,
                             ending_event_motion_event_id_,
-                            *packet_being_sent_));
+                            ending_event_primary_tool_type_,
+                            packet_being_sent),
+              packet_being_sent);
   DCHECK(!needs_scroll_ending_event_);
 }