Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Side by Side Diff: content/browser/renderer_host/input/touch_event_queue.cc

Issue 171283002: Always reset touch action at the beginning of a new gesture sequence (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix test name. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/input/touch_event_queue.h" 5 #include "content/browser/renderer_host/input/touch_event_queue.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "content/browser/renderer_host/input/timeout_monitor.h" 11 #include "content/browser/renderer_host/input/timeout_monitor.h"
12 #include "content/common/input/web_input_event_traits.h" 12 #include "content/browser/renderer_host/input/web_touch_event_traits.h"
13 #include "content/public/common/content_switches.h" 13 #include "content/public/common/content_switches.h"
14 #include "ui/gfx/geometry/point_f.h" 14 #include "ui/gfx/geometry/point_f.h"
15 15
16 using blink::WebInputEvent; 16 using blink::WebInputEvent;
17 using blink::WebTouchEvent; 17 using blink::WebTouchEvent;
18 using blink::WebTouchPoint; 18 using blink::WebTouchPoint;
19 using ui::LatencyInfo; 19 using ui::LatencyInfo;
20 20
21 namespace content { 21 namespace content {
22 namespace { 22 namespace {
23 23
24 typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList; 24 typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
25 25
26 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( 26 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent(
27 const TouchEventWithLatencyInfo& event_to_cancel) { 27 const TouchEventWithLatencyInfo& event_to_cancel) {
28 TouchEventWithLatencyInfo event = event_to_cancel; 28 TouchEventWithLatencyInfo event = event_to_cancel;
29 event.event.type = WebInputEvent::TouchCancel; 29 event.event.type = WebInputEvent::TouchCancel;
30 for (size_t i = 0; i < event.event.touchesLength; i++) 30 for (size_t i = 0; i < event.event.touchesLength; i++)
31 event.event.touches[i].state = WebTouchPoint::StateCancelled; 31 event.event.touches[i].state = WebTouchPoint::StateCancelled;
32 return event; 32 return event;
33 } 33 }
34 34
35 bool IsNewTouchSequence(const WebTouchEvent& event) {
36 if (event.type != WebInputEvent::TouchStart)
37 return false;
38 if (!event.touchesLength)
39 return false;
40 for (size_t i = 0; i < event.touchesLength; i++) {
41 if (event.touches[i].state != WebTouchPoint::StatePressed)
42 return false;
43 }
44 return true;
45 }
46
47 bool ShouldTouchTypeTriggerTimeout(WebInputEvent::Type type) { 35 bool ShouldTouchTypeTriggerTimeout(WebInputEvent::Type type) {
48 return type == WebInputEvent::TouchStart || 36 return type == WebInputEvent::TouchStart ||
49 type == WebInputEvent::TouchMove; 37 type == WebInputEvent::TouchMove;
50 } 38 }
51 39
52 } // namespace 40 } // namespace
53 41
54 42
55 // Cancels a touch sequence if a touchstart or touchmove ack response is 43 // Cancels a touch sequence if a touchstart or touchmove ack response is
56 // sufficiently delayed. 44 // sufficiently delayed.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 SetPendingAckState(PENDING_ACK_ORIGINAL_EVENT); 107 SetPendingAckState(PENDING_ACK_ORIGINAL_EVENT);
120 touch_queue_->FlushQueue(); 108 touch_queue_->FlushQueue();
121 } 109 }
122 110
123 // Skip a cancel event if the timed-out event had no consumer and was the 111 // Skip a cancel event if the timed-out event had no consumer and was the
124 // initial event in the gesture. 112 // initial event in the gesture.
125 bool AckedTimeoutEventRequiresCancel(InputEventAckState ack_result) const { 113 bool AckedTimeoutEventRequiresCancel(InputEventAckState ack_result) const {
126 DCHECK(HasTimeoutEvent()); 114 DCHECK(HasTimeoutEvent());
127 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) 115 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS)
128 return true; 116 return true;
129 return !IsNewTouchSequence(timeout_event_.event); 117 return !WebTouchEventTraits::IsTouchSequenceStart(timeout_event_.event);
130 } 118 }
131 119
132 void SetPendingAckState(PendingAckState new_pending_ack_state) { 120 void SetPendingAckState(PendingAckState new_pending_ack_state) {
133 DCHECK_NE(pending_ack_state_, new_pending_ack_state); 121 DCHECK_NE(pending_ack_state_, new_pending_ack_state);
134 switch (new_pending_ack_state) { 122 switch (new_pending_ack_state) {
135 case PENDING_ACK_ORIGINAL_EVENT: 123 case PENDING_ACK_ORIGINAL_EVENT:
136 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE); 124 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE);
137 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this); 125 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this);
138 break; 126 break;
139 case PENDING_ACK_CANCEL_EVENT: 127 case PENDING_ACK_CANCEL_EVENT:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 class TouchEventQueue::TouchMoveSlopSuppressor { 165 class TouchEventQueue::TouchMoveSlopSuppressor {
178 public: 166 public:
179 // TODO(jdduke): Remove int cast on suppression length, crbug.com/336807. 167 // TODO(jdduke): Remove int cast on suppression length, crbug.com/336807.
180 TouchMoveSlopSuppressor(double slop_suppression_length_dips) 168 TouchMoveSlopSuppressor(double slop_suppression_length_dips)
181 : slop_suppression_length_dips_squared_( 169 : slop_suppression_length_dips_squared_(
182 static_cast<int>(slop_suppression_length_dips) * 170 static_cast<int>(slop_suppression_length_dips) *
183 static_cast<int>(slop_suppression_length_dips)), 171 static_cast<int>(slop_suppression_length_dips)),
184 suppressing_touch_moves_(false) {} 172 suppressing_touch_moves_(false) {}
185 173
186 bool FilterEvent(const WebTouchEvent& event) { 174 bool FilterEvent(const WebTouchEvent& event) {
187 if (IsNewTouchSequence(event)) { 175 if (WebTouchEventTraits::IsTouchSequenceStart(event)) {
188 touch_sequence_start_position_ = 176 touch_sequence_start_position_ =
189 gfx::Point(event.touches[0].position); 177 gfx::Point(event.touches[0].position);
190 suppressing_touch_moves_ = slop_suppression_length_dips_squared_ != 0; 178 suppressing_touch_moves_ = slop_suppression_length_dips_squared_ != 0;
191 } 179 }
192 180
193 if (event.type != WebInputEvent::TouchMove) 181 if (event.type != WebInputEvent::TouchMove)
194 return false; 182 return false;
195 183
196 if (suppressing_touch_moves_) { 184 if (suppressing_touch_moves_) {
197 // Movement with a secondary pointer should terminate suppression. 185 // Movement with a secondary pointer should terminate suppression.
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { 302 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
315 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent"); 303 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent");
316 304
317 // If the queueing of |event| was triggered by an ack dispatch, defer 305 // If the queueing of |event| was triggered by an ack dispatch, defer
318 // processing the event until the dispatch has finished. 306 // processing the event until the dispatch has finished.
319 if (touch_queue_.empty() && !dispatching_touch_ack_) { 307 if (touch_queue_.empty() && !dispatching_touch_ack_) {
320 // Optimization of the case without touch handlers. Removing this path 308 // Optimization of the case without touch handlers. Removing this path
321 // yields identical results, but this avoids unnecessary allocations. 309 // yields identical results, but this avoids unnecessary allocations.
322 if (touch_filtering_state_ == DROP_ALL_TOUCHES || 310 if (touch_filtering_state_ == DROP_ALL_TOUCHES ||
323 (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE && 311 (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE &&
324 !IsNewTouchSequence(event.event))) { 312 !WebTouchEventTraits::IsTouchSequenceStart(event.event))) {
325 client_->OnTouchEventAck(event, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); 313 client_->OnTouchEventAck(event, INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
326 return; 314 return;
327 } 315 }
328 316
329 // There is no touch event in the queue. Forward it to the renderer 317 // There is no touch event in the queue. Forward it to the renderer
330 // immediately. 318 // immediately.
331 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); 319 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false));
332 TryForwardNextEventToRenderer(); 320 TryForwardNextEventToRenderer();
333 return; 321 return;
334 } 322 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 } 381 }
394 } 382 }
395 383
396 void TouchEventQueue::ForwardToRenderer( 384 void TouchEventQueue::ForwardToRenderer(
397 const TouchEventWithLatencyInfo& touch) { 385 const TouchEventWithLatencyInfo& touch) {
398 TRACE_EVENT0("input", "TouchEventQueue::ForwardToRenderer"); 386 TRACE_EVENT0("input", "TouchEventQueue::ForwardToRenderer");
399 387
400 DCHECK(!dispatching_touch_); 388 DCHECK(!dispatching_touch_);
401 DCHECK_NE(touch_filtering_state_, DROP_ALL_TOUCHES); 389 DCHECK_NE(touch_filtering_state_, DROP_ALL_TOUCHES);
402 390
403 if (IsNewTouchSequence(touch.event)) { 391 if (WebTouchEventTraits::IsTouchSequenceStart(touch.event)) {
404 touch_filtering_state_ = 392 touch_filtering_state_ =
405 ack_timeout_enabled_ ? FORWARD_TOUCHES_UNTIL_TIMEOUT 393 ack_timeout_enabled_ ? FORWARD_TOUCHES_UNTIL_TIMEOUT
406 : FORWARD_ALL_TOUCHES; 394 : FORWARD_ALL_TOUCHES;
407 touch_ack_states_.clear(); 395 touch_ack_states_.clear();
408 absorbing_touch_moves_ = false; 396 absorbing_touch_moves_ = false;
409 } 397 }
410 398
411 // A synchronous ack will reset |dispatching_touch_|, in which case 399 // A synchronous ack will reset |dispatching_touch_|, in which case
412 // the touch timeout should not be started. 400 // the touch timeout should not be started.
413 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); 401 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 return ACK_WITH_NO_CONSUMER_EXISTS; 555 return ACK_WITH_NO_CONSUMER_EXISTS;
568 556
569 if (touchmove_slop_suppressor_->FilterEvent(event)) 557 if (touchmove_slop_suppressor_->FilterEvent(event))
570 return ACK_WITH_NOT_CONSUMED; 558 return ACK_WITH_NOT_CONSUMED;
571 559
572 if (touch_filtering_state_ == DROP_ALL_TOUCHES) 560 if (touch_filtering_state_ == DROP_ALL_TOUCHES)
573 return ACK_WITH_NO_CONSUMER_EXISTS; 561 return ACK_WITH_NO_CONSUMER_EXISTS;
574 562
575 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE && 563 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE &&
576 event.type != WebInputEvent::TouchCancel) { 564 event.type != WebInputEvent::TouchCancel) {
577 if (IsNewTouchSequence(event)) 565 if (WebTouchEventTraits::IsTouchSequenceStart(event))
578 return FORWARD_TO_RENDERER; 566 return FORWARD_TO_RENDERER;
579 return ACK_WITH_NOT_CONSUMED; 567 return ACK_WITH_NOT_CONSUMED;
580 } 568 }
581 569
582 if (absorbing_touch_moves_ && event.type == WebInputEvent::TouchMove) 570 if (absorbing_touch_moves_ && event.type == WebInputEvent::TouchMove)
583 return ACK_WITH_NOT_CONSUMED; 571 return ACK_WITH_NOT_CONSUMED;
584 572
585 // Touch press events should always be forwarded to the renderer. 573 // Touch press events should always be forwarded to the renderer.
586 if (event.type == WebInputEvent::TouchStart) 574 if (event.type == WebInputEvent::TouchStart)
587 return FORWARD_TO_RENDERER; 575 return FORWARD_TO_RENDERER;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 } else if (event.type == WebInputEvent::TouchStart) { 609 } else if (event.type == WebInputEvent::TouchStart) {
622 for (unsigned i = 0; i < event.touchesLength; ++i) { 610 for (unsigned i = 0; i < event.touchesLength; ++i) {
623 const WebTouchPoint& point = event.touches[i]; 611 const WebTouchPoint& point = event.touches[i];
624 if (point.state == WebTouchPoint::StatePressed) 612 if (point.state == WebTouchPoint::StatePressed)
625 touch_ack_states_[point.id] = ack_result; 613 touch_ack_states_[point.id] = ack_result;
626 } 614 }
627 } 615 }
628 } 616 }
629 617
630 } // namespace content 618 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698