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(),
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:
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
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) {
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;
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;
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;
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_);
}