Index: content/browser/renderer_host/input/touch_event_queue.cc |
diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc |
index 35b1657048ba5635cf1ffbba8c353f8687b94359..0ef95f9f391543ea239359ea7d84d8535189f4c0 100644 |
--- a/content/browser/renderer_host/input/touch_event_queue.cc |
+++ b/content/browser/renderer_host/input/touch_event_queue.cc |
@@ -29,6 +29,21 @@ const double kAsyncTouchMoveIntervalSec = .2; |
// |causesScrollingIfUncanceled| bit. |
const double kMaxConceivablePlatformSlopRegionLengthDipsSquared = 60. * 60.; |
+// These values should be synchronized with those in histograms.xml. |
+enum TouchSequenceHandlerType { |
+ HAS_HANDLER, |
+ HAS_HANDLER_BUT_NO_MOVE_HANDLERS_FOR_PAGE, |
+ NO_HANDLERS_FOR_PAGE, |
+ NO_HANDLER_FOR_SEQUENCE, |
+ UNKNOWN_BECAUSE_TIMEOUT, |
+ TOUCH_SEQUENCE_HANDLER_TYPE_COUNT |
+}; |
+ |
+void LogSequenceHandlerType(TouchSequenceHandlerType type) { |
+ UMA_HISTOGRAM_ENUMERATION("Event.TouchSequence.HandlerType", type, |
+ TOUCH_SEQUENCE_HANDLER_TYPE_COUNT); |
+} |
+ |
TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( |
const TouchEventWithLatencyInfo& event_to_cancel) { |
TouchEventWithLatencyInfo event = event_to_cancel; |
@@ -131,8 +146,6 @@ class TouchEventQueue::TouchTimeoutHandler { |
touch_queue_->SendTouchEventImmediately(&cancel_event); |
} else { |
SetPendingAckState(PENDING_ACK_NONE); |
- touch_queue_->UpdateTouchConsumerStates(timeout_event_.event, |
- ack_result); |
} |
return true; |
case PENDING_ACK_CANCEL_EVENT: |
@@ -181,6 +194,10 @@ class TouchEventQueue::TouchTimeoutHandler { |
bool IsTimeoutTimerRunning() const { return timeout_monitor_.IsRunning(); } |
+ bool HasTimeoutEvent() const { |
+ return pending_ack_state_ != PENDING_ACK_NONE; |
+ } |
+ |
bool IsEnabled() const { |
return enabled_ && !GetTimeoutDelay().is_zero(); |
} |
@@ -254,10 +271,6 @@ class TouchEventQueue::TouchTimeoutHandler { |
return use_mobile_timeout_ ? mobile_timeout_delay_ : desktop_timeout_delay_; |
} |
- bool HasTimeoutEvent() const { |
- return pending_ack_state_ != PENDING_ACK_NONE; |
- } |
- |
TouchEventQueue* touch_queue_; |
@@ -433,6 +446,7 @@ TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client, |
dispatching_touch_ack_(false), |
dispatching_touch_(false), |
has_handlers_(true), |
+ has_move_handlers_(true), |
has_handler_for_current_sequence_(false), |
drop_remaining_touches_in_sequence_(false), |
touchmove_slop_suppressor_(new TouchMoveSlopSuppressor), |
@@ -462,10 +476,12 @@ void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { |
// yields identical results, but this avoids unnecessary allocations. |
PreFilterResult filter_result = FilterBeforeForwarding(event.event); |
if (filter_result != FORWARD_TO_RENDERER) { |
- client_->OnTouchEventAck(event, |
- filter_result == ACK_WITH_NO_CONSUMER_EXISTS |
- ? INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS |
- : INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
+ InputEventAckState ack_result = |
+ filter_result == ACK_WITH_NO_CONSUMER_EXISTS |
+ ? INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS |
+ : INPUT_EVENT_ACK_STATE_NOT_CONSUMED; |
+ UpdateTouchConsumerStates(event.event, ack_result); |
+ client_->OnTouchEventAck(event, ack_result); |
return; |
} |
@@ -659,6 +675,12 @@ void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { |
has_handlers_ = has_handlers; |
} |
+void TouchEventQueue::OnHasTouchMoveEventHandlers(bool has_handlers) { |
+ DCHECK(!dispatching_touch_ack_); |
+ DCHECK(!dispatching_touch_); |
+ has_move_handlers_ = has_handlers; |
+} |
+ |
bool TouchEventQueue::IsPendingAckTouchStart() const { |
DCHECK(!dispatching_touch_ack_); |
if (touch_queue_.empty()) |
@@ -823,6 +845,9 @@ TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { |
: ACK_WITH_NO_CONSUMER_EXISTS; |
} |
+ if (event.type == WebInputEvent::TouchMove && !has_move_handlers_) |
+ return ACK_WITH_NO_CONSUMER_EXISTS; |
+ |
if (has_handler_for_current_sequence_) { |
// Only forward a touch if it has a non-stationary pointer that is active |
// in the current touch sequence. |
@@ -868,6 +893,19 @@ void TouchEventQueue::UpdateTouchConsumerStates(const WebTouchEvent& event, |
send_touch_events_async_ = false; |
has_handler_for_current_sequence_ |= |
ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; |
+ |
+ if (WebTouchEventTraits::IsTouchSequenceStart(event)) { |
+ if (timeout_handler_ && timeout_handler_->HasTimeoutEvent()) |
+ LogSequenceHandlerType(UNKNOWN_BECAUSE_TIMEOUT); |
+ else if (!has_handlers_) |
+ LogSequenceHandlerType(NO_HANDLERS_FOR_PAGE); |
+ else if (!has_handler_for_current_sequence_) |
+ LogSequenceHandlerType(NO_HANDLER_FOR_SEQUENCE); |
+ else if (!has_move_handlers_) |
+ LogSequenceHandlerType(HAS_HANDLER_BUT_NO_MOVE_HANDLERS_FOR_PAGE); |
+ else |
+ LogSequenceHandlerType(HAS_HANDLER); |
+ } |
} else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { |
has_handler_for_current_sequence_ = false; |
} |