| Index: content/browser/renderer_host/render_widget_host_input_event_router.cc
|
| diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
| index 703868a9a5f623478512244bd427d31074ca77a8..3710a90df7f9d578833047c019537275a9ee9b4b 100644
|
| --- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
| +++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
|
|
|
| +#include "base/metrics/histogram_macros.h"
|
| #include "cc/quads/surface_draw_quad.h"
|
| #include "cc/surfaces/surface_id_allocator.h"
|
| #include "cc/surfaces/surface_manager.h"
|
| @@ -188,13 +189,47 @@ void RenderWidgetHostInputEventRouter::RouteGestureEvent(
|
| };
|
| }
|
|
|
| +namespace {
|
| +
|
| +unsigned CountChangedTouchPoints(const blink::WebTouchEvent& event) {
|
| + unsigned changed_count = 0;
|
| +
|
| + blink::WebTouchPoint::State required_state =
|
| + blink::WebTouchPoint::StateUndefined;
|
| + switch (event.type) {
|
| + case blink::WebInputEvent::TouchStart:
|
| + required_state = blink::WebTouchPoint::StatePressed;
|
| + break;
|
| + case blink::WebInputEvent::TouchEnd:
|
| + required_state = blink::WebTouchPoint::StateReleased;
|
| + break;
|
| + case blink::WebInputEvent::TouchCancel:
|
| + required_state = blink::WebTouchPoint::StateCancelled;
|
| + break;
|
| + default:
|
| + // We'll only ever call this method for TouchStart, TouchEnd
|
| + // and TounchCancel events, so mark the rest as not-reached.
|
| + NOTREACHED();
|
| + }
|
| + for (unsigned i = 0; i < event.touchesLength; ++i) {
|
| + if (event.touches[i].state == required_state)
|
| + ++changed_count;
|
| + }
|
| +
|
| + DCHECK(event.type == blink::WebInputEvent::TouchCancel || changed_count == 1);
|
| + return changed_count;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| void RenderWidgetHostInputEventRouter::RouteTouchEvent(
|
| RenderWidgetHostViewBase* root_view,
|
| blink::WebTouchEvent* event,
|
| const ui::LatencyInfo& latency) {
|
| switch (event->type) {
|
| case blink::WebInputEvent::TouchStart: {
|
| - if (!active_touches_) {
|
| + active_touches_ += CountChangedTouchPoints(*event);
|
| + if (active_touches_ == 1) {
|
| // Since this is the first touch, it defines the target for the rest
|
| // of this sequence.
|
| DCHECK(!touch_target_.target);
|
| @@ -212,17 +247,16 @@ void RenderWidgetHostInputEventRouter::RouteTouchEvent(
|
| touch_target_.delta = transformed_point - original_point;
|
| touchscreen_gesture_target_queue_.push_back(touch_target_);
|
|
|
| - if (!touch_target_.target) {
|
| + if (!touch_target_.target)
|
| return;
|
| - } else if (touch_target_.target ==
|
| - bubbling_gesture_scroll_target_.target) {
|
| +
|
| + if (touch_target_.target == bubbling_gesture_scroll_target_.target) {
|
| SendGestureScrollEnd(bubbling_gesture_scroll_target_.target,
|
| blink::WebGestureEvent());
|
| CancelScrollBubbling(bubbling_gesture_scroll_target_.target);
|
| }
|
| }
|
|
|
| - ++active_touches_;
|
| if (touch_target_.target) {
|
| TransformEventTouchPositions(event, touch_target_.delta);
|
| touch_target_.target->ProcessTouchEvent(*event, latency);
|
| @@ -237,13 +271,13 @@ void RenderWidgetHostInputEventRouter::RouteTouchEvent(
|
| break;
|
| case blink::WebInputEvent::TouchEnd:
|
| case blink::WebInputEvent::TouchCancel:
|
| + DCHECK(active_touches_);
|
| + active_touches_ -= CountChangedTouchPoints(*event);
|
| if (!touch_target_.target)
|
| - break;
|
| + return;
|
|
|
| - DCHECK(active_touches_);
|
| TransformEventTouchPositions(event, touch_target_.delta);
|
| touch_target_.target->ProcessTouchEvent(*event, latency);
|
| - --active_touches_;
|
| if (!active_touches_)
|
| touch_target_.target = nullptr;
|
| break;
|
| @@ -441,7 +475,12 @@ void RenderWidgetHostInputEventRouter::RouteTouchscreenGestureEvent(
|
| // GestureTapDown is sent to the previous target, in case it is still in a
|
| // fling.
|
| if (event->type == blink::WebInputEvent::GestureTapDown) {
|
| - if (touchscreen_gesture_target_queue_.empty()) {
|
| + bool no_target = touchscreen_gesture_target_queue_.empty();
|
| + // This UMA metric is temporary, and will be removed once it has fulfilled
|
| + // it's purpose, namely telling us when the incidents of empty
|
| + // gesture-queues has dropped to zero. https://crbug.com/642008
|
| + UMA_HISTOGRAM_BOOLEAN("Event.FrameEventRouting.NoGestureTarget", no_target);
|
| + if (no_target) {
|
| LOG(ERROR) << "Gesture sequence start detected with no target available.";
|
| // Ignore this gesture sequence as no target is available.
|
| // TODO(wjmaclean): this only happens on Windows, and should not happen.
|
|
|