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

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

Issue 260923003: Revert of Consolidate all touch/gesture related constants in content (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 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
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/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
9 #include "base/stl_util.h" 10 #include "base/stl_util.h"
10 #include "content/browser/renderer_host/input/timeout_monitor.h" 11 #include "content/browser/renderer_host/input/timeout_monitor.h"
11 #include "content/common/input/web_touch_event_traits.h" 12 #include "content/common/input/web_touch_event_traits.h"
13 #include "content/public/common/content_switches.h"
12 #include "ui/gfx/geometry/point_f.h" 14 #include "ui/gfx/geometry/point_f.h"
13 15
14 using blink::WebInputEvent; 16 using blink::WebInputEvent;
15 using blink::WebTouchEvent; 17 using blink::WebTouchEvent;
16 using blink::WebTouchPoint; 18 using blink::WebTouchPoint;
17 using ui::LatencyInfo; 19 using ui::LatencyInfo;
18 20
19 namespace content { 21 namespace content {
20 namespace { 22 namespace {
21 23
22 // Time interval at which touchmove events will be forwarded to the client while 24 // Time interval at which touchmove events will be forwarded to the client while
23 // scrolling is active and possible. 25 // scrolling is active and possible.
24 const double kAsyncTouchMoveIntervalSec = .2; 26 const double kAsyncTouchMoveIntervalSec = .2;
25 27
26 // A slop region just larger than that used by many web applications. When 28 // A slop region just larger than that used by many web applications. When
27 // touchmove's are being sent asynchronously, movement outside this region will 29 // touchmove's are being sent asynchronously, movement outside this region will
28 // trigger an immediate async touchmove to cancel potential tap-related logic. 30 // trigger an immediate async touchmove to cancel potential tap-related logic.
29 const double kApplicationSlopRegionLengthDipsSqared = 15. * 15.; 31 const double kApplicationSlopRegionLengthDipsSqared = 15. * 15.;
30 32
31 // Using a small epsilon when comparing slop distances allows pixel perfect 33 // Using a small epsilon when comparing slop distances allows pixel perfect
32 // slop determination when using fractional DIP coordinates (assuming the slop 34 // slop determination when using fractional DIP coordinates (assuming the slop
33 // region and DPI scale are reasonably proportioned). 35 // region and DPI scale are reasonably proportioned).
34 const float kSlopEpsilon = .05f; 36 const float kSlopEpsilon = .05f;
35 37
38 typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
39
36 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( 40 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent(
37 const TouchEventWithLatencyInfo& event_to_cancel) { 41 const TouchEventWithLatencyInfo& event_to_cancel) {
38 TouchEventWithLatencyInfo event = event_to_cancel; 42 TouchEventWithLatencyInfo event = event_to_cancel;
39 WebTouchEventTraits::ResetTypeAndTouchStates( 43 WebTouchEventTraits::ResetTypeAndTouchStates(
40 WebInputEvent::TouchCancel, 44 WebInputEvent::TouchCancel,
41 // TODO(rbyers): Shouldn't we use a fresh timestamp? 45 // TODO(rbyers): Shouldn't we use a fresh timestamp?
42 event.event.timeStampSeconds, 46 event.event.timeStampSeconds,
43 &event.event); 47 &event.event);
44 return event; 48 return event;
45 } 49 }
(...skipping 16 matching lines...) Expand all
62 // Cancels a touch sequence if a touchstart or touchmove ack response is 66 // Cancels a touch sequence if a touchstart or touchmove ack response is
63 // sufficiently delayed. 67 // sufficiently delayed.
64 class TouchEventQueue::TouchTimeoutHandler { 68 class TouchEventQueue::TouchTimeoutHandler {
65 public: 69 public:
66 TouchTimeoutHandler(TouchEventQueue* touch_queue, 70 TouchTimeoutHandler(TouchEventQueue* touch_queue,
67 base::TimeDelta timeout_delay) 71 base::TimeDelta timeout_delay)
68 : touch_queue_(touch_queue), 72 : touch_queue_(touch_queue),
69 timeout_delay_(timeout_delay), 73 timeout_delay_(timeout_delay),
70 pending_ack_state_(PENDING_ACK_NONE), 74 pending_ack_state_(PENDING_ACK_NONE),
71 timeout_monitor_(base::Bind(&TouchTimeoutHandler::OnTimeOut, 75 timeout_monitor_(base::Bind(&TouchTimeoutHandler::OnTimeOut,
72 base::Unretained(this))) { 76 base::Unretained(this))) {}
73 DCHECK(timeout_delay != base::TimeDelta());
74 }
75 77
76 ~TouchTimeoutHandler() {} 78 ~TouchTimeoutHandler() {}
77 79
78 void Start(const TouchEventWithLatencyInfo& event) { 80 void Start(const TouchEventWithLatencyInfo& event) {
79 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE); 81 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE);
80 DCHECK(ShouldTouchTriggerTimeout(event.event)); 82 DCHECK(ShouldTouchTriggerTimeout(event.event));
81 timeout_event_ = event; 83 timeout_event_ = event;
82 timeout_monitor_.Restart(timeout_delay_); 84 timeout_monitor_.Restart(timeout_delay_);
83 } 85 }
84 86
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 190
189 // Provides touchmove slop suppression for a single touch that remains within 191 // Provides touchmove slop suppression for a single touch that remains within
190 // a given slop region, unless the touchstart is preventDefault'ed. 192 // a given slop region, unless the touchstart is preventDefault'ed.
191 // TODO(jdduke): Use a flag bundled with each TouchEvent declaring whether it 193 // TODO(jdduke): Use a flag bundled with each TouchEvent declaring whether it
192 // has exceeded the slop region, removing duplicated slop determination logic. 194 // has exceeded the slop region, removing duplicated slop determination logic.
193 class TouchEventQueue::TouchMoveSlopSuppressor { 195 class TouchEventQueue::TouchMoveSlopSuppressor {
194 public: 196 public:
195 TouchMoveSlopSuppressor(double slop_suppression_length_dips) 197 TouchMoveSlopSuppressor(double slop_suppression_length_dips)
196 : slop_suppression_length_dips_squared_(slop_suppression_length_dips * 198 : slop_suppression_length_dips_squared_(slop_suppression_length_dips *
197 slop_suppression_length_dips), 199 slop_suppression_length_dips),
198 suppressing_touchmoves_(false) {} 200 suppressing_touch_moves_(false) {}
199 201
200 bool FilterEvent(const WebTouchEvent& event) { 202 bool FilterEvent(const WebTouchEvent& event) {
201 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { 203 if (WebTouchEventTraits::IsTouchSequenceStart(event)) {
202 touch_sequence_start_position_ = 204 touch_sequence_start_position_ =
203 gfx::PointF(event.touches[0].position); 205 gfx::PointF(event.touches[0].position);
204 suppressing_touchmoves_ = slop_suppression_length_dips_squared_ != 0; 206 suppressing_touch_moves_ = slop_suppression_length_dips_squared_ != 0;
205 } 207 }
206 208
207 if (event.type != WebInputEvent::TouchMove) 209 if (event.type != WebInputEvent::TouchMove)
208 return false; 210 return false;
209 211
210 if (suppressing_touchmoves_) { 212 if (suppressing_touch_moves_) {
211 // Movement with a secondary pointer should terminate suppression. 213 // Movement with a secondary pointer should terminate suppression.
212 if (event.touchesLength > 1) { 214 if (event.touchesLength > 1) {
213 suppressing_touchmoves_ = false; 215 suppressing_touch_moves_ = false;
214 } else if (event.touchesLength == 1) { 216 } else if (event.touchesLength == 1) {
215 // Movement outside of the slop region should terminate suppression. 217 // Movement outside of the slop region should terminate suppression.
216 gfx::PointF position(event.touches[0].position); 218 gfx::PointF position(event.touches[0].position);
217 if ((position - touch_sequence_start_position_).LengthSquared() > 219 if ((position - touch_sequence_start_position_).LengthSquared() >
218 slop_suppression_length_dips_squared_) 220 slop_suppression_length_dips_squared_)
219 suppressing_touchmoves_ = false; 221 suppressing_touch_moves_ = false;
220 } 222 }
221 } 223 }
222 return suppressing_touchmoves_; 224 return suppressing_touch_moves_;
223 } 225 }
224 226
225 void ConfirmTouchEvent(InputEventAckState ack_result) { 227 void ConfirmTouchEvent(InputEventAckState ack_result) {
226 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) 228 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
227 suppressing_touchmoves_ = false; 229 suppressing_touch_moves_ = false;
228 } 230 }
229 231
230 private: 232 private:
231 double slop_suppression_length_dips_squared_; 233 double slop_suppression_length_dips_squared_;
232 gfx::PointF touch_sequence_start_position_; 234 gfx::PointF touch_sequence_start_position_;
233 bool suppressing_touchmoves_; 235 bool suppressing_touch_moves_;
234 236
235 DISALLOW_COPY_AND_ASSIGN(TouchMoveSlopSuppressor); 237 DISALLOW_COPY_AND_ASSIGN(TouchMoveSlopSuppressor);
236 }; 238 };
237 239
238 // This class represents a single coalesced touch event. However, it also keeps 240 // This class represents a single coalesced touch event. However, it also keeps
239 // track of all the original touch-events that were coalesced into a single 241 // track of all the original touch-events that were coalesced into a single
240 // event. The coalesced event is forwarded to the renderer, while the original 242 // event. The coalesced event is forwarded to the renderer, while the original
241 // touch-events are sent to the Client (on ACK for the coalesced event) so that 243 // touch-events are sent to the Client (on ACK for the coalesced event) so that
242 // the Client receives the event with their original timestamp. 244 // the Client receives the event with their original timestamp.
243 class CoalescedWebTouchEvent { 245 class CoalescedWebTouchEvent {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 } 309 }
308 310
309 private: 311 private:
310 bool WillDispatchAckToClient() const { return !events_to_ack_.empty(); } 312 bool WillDispatchAckToClient() const { return !events_to_ack_.empty(); }
311 313
312 // This is the event that is forwarded to the renderer. 314 // This is the event that is forwarded to the renderer.
313 TouchEventWithLatencyInfo coalesced_event_; 315 TouchEventWithLatencyInfo coalesced_event_;
314 316
315 // This is the list of the original events that were coalesced, each requiring 317 // This is the list of the original events that were coalesced, each requiring
316 // future ack dispatch to the client. 318 // future ack dispatch to the client.
317 typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
318 WebTouchEventWithLatencyList events_to_ack_; 319 WebTouchEventWithLatencyList events_to_ack_;
319 320
320 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent); 321 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent);
321 }; 322 };
322 323
323 TouchEventQueue::Config::Config()
324 : touchmove_slop_suppression_length_dips(0),
325 touch_scrolling_mode(TOUCH_SCROLLING_MODE_DEFAULT),
326 touch_ack_timeout_delay(base::TimeDelta::FromMilliseconds(200)),
327 touch_ack_timeout_supported(false) {
328 }
329
330 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client, 324 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client,
331 const Config& config) 325 TouchScrollingMode mode,
326 double touchmove_suppression_length_dips)
332 : client_(client), 327 : client_(client),
333 dispatching_touch_ack_(NULL), 328 dispatching_touch_ack_(NULL),
334 dispatching_touch_(false), 329 dispatching_touch_(false),
335 touch_filtering_state_(TOUCH_FILTERING_STATE_DEFAULT), 330 touch_filtering_state_(TOUCH_FILTERING_STATE_DEFAULT),
336 ack_timeout_enabled_(config.touch_ack_timeout_supported), 331 ack_timeout_enabled_(false),
337 touchmove_slop_suppressor_(new TouchMoveSlopSuppressor( 332 touchmove_slop_suppressor_(new TouchMoveSlopSuppressor(
338 config.touchmove_slop_suppression_length_dips + kSlopEpsilon)), 333 touchmove_suppression_length_dips + kSlopEpsilon)),
339 send_touch_events_async_(false), 334 send_touch_events_async_(false),
340 needs_async_touchmove_for_outer_slop_region_(false), 335 needs_async_touch_move_for_outer_slop_region_(false),
341 last_sent_touch_timestamp_sec_(0), 336 last_sent_touch_timestamp_sec_(0),
342 touch_scrolling_mode_(config.touch_scrolling_mode) { 337 touch_scrolling_mode_(mode) {
343 DCHECK(client); 338 DCHECK(client);
344 if (ack_timeout_enabled_) {
345 timeout_handler_.reset(
346 new TouchTimeoutHandler(this, config.touch_ack_timeout_delay));
347 }
348 } 339 }
349 340
350 TouchEventQueue::~TouchEventQueue() { 341 TouchEventQueue::~TouchEventQueue() {
351 if (!touch_queue_.empty()) 342 if (!touch_queue_.empty())
352 STLDeleteElements(&touch_queue_); 343 STLDeleteElements(&touch_queue_);
353 } 344 }
354 345
355 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { 346 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
356 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent"); 347 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent");
357 348
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 gfx::PointF(touch.event.touches[0].position); 440 gfx::PointF(touch.event.touches[0].position);
450 } 441 }
451 442
452 if (send_touch_events_async_ && 443 if (send_touch_events_async_ &&
453 touch.event.type == WebInputEvent::TouchMove) { 444 touch.event.type == WebInputEvent::TouchMove) {
454 // Throttling touchmove's in a continuous touchmove stream while scrolling 445 // Throttling touchmove's in a continuous touchmove stream while scrolling
455 // reduces the risk of jank. However, it's still important that the web 446 // reduces the risk of jank. However, it's still important that the web
456 // application be sent touches at key points in the gesture stream, 447 // application be sent touches at key points in the gesture stream,
457 // e.g., when the application slop region is exceeded or touchmove 448 // e.g., when the application slop region is exceeded or touchmove
458 // coalescing fails because of different modifiers. 449 // coalescing fails because of different modifiers.
459 const bool send_touchmove_now = 450 const bool send_touch_move_now =
460 size() > 1 || 451 size() > 1 ||
461 (touch.event.timeStampSeconds >= 452 (touch.event.timeStampSeconds >=
462 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec) || 453 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec) ||
463 (needs_async_touchmove_for_outer_slop_region_ && 454 (needs_async_touch_move_for_outer_slop_region_ &&
464 OutsideApplicationSlopRegion(touch.event, 455 OutsideApplicationSlopRegion(touch.event,
465 touch_sequence_start_position_)) || 456 touch_sequence_start_position_)) ||
466 (pending_async_touchmove_ && 457 (pending_async_touch_move_ &&
467 !pending_async_touchmove_->CanCoalesceWith(touch)); 458 !pending_async_touch_move_->CanCoalesceWith(touch));
468 459
469 if (!send_touchmove_now) { 460 if (!send_touch_move_now) {
470 if (!pending_async_touchmove_) { 461 if (!pending_async_touch_move_) {
471 pending_async_touchmove_.reset(new TouchEventWithLatencyInfo(touch)); 462 pending_async_touch_move_.reset(new TouchEventWithLatencyInfo(touch));
472 } else { 463 } else {
473 DCHECK(pending_async_touchmove_->CanCoalesceWith(touch)); 464 DCHECK(pending_async_touch_move_->CanCoalesceWith(touch));
474 pending_async_touchmove_->CoalesceWith(touch); 465 pending_async_touch_move_->CoalesceWith(touch);
475 } 466 }
476 DCHECK_EQ(1U, size()); 467 DCHECK_EQ(1U, size());
477 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 468 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
478 // It's possible (though unlikely) that ack'ing the current touch will 469 // It's possible (though unlikely) that ack'ing the current touch will
479 // trigger the queueing of another touch event (e.g., a touchcancel). As 470 // trigger the queueing of another touch event (e.g., a touchcancel). As
480 // forwarding of the queued event will be deferred while the ack is being 471 // forwarding of the queued event will be deferred while the ack is being
481 // dispatched (see |OnTouchEvent()|), try forwarding it now. 472 // dispatched (see |OnTouchEvent()|), try forwarding it now.
482 TryForwardNextEventToRenderer(); 473 TryForwardNextEventToRenderer();
483 return; 474 return;
484 } 475 }
485 } 476 }
486 477
487 last_sent_touch_timestamp_sec_ = touch.event.timeStampSeconds; 478 last_sent_touch_timestamp_sec_ = touch.event.timeStampSeconds;
488 479
489 // Flush any pending async touch move. If it can be combined with the current 480 // Flush any pending async touch move. If it can be combined with the current
490 // (touchmove) event, great, otherwise send it immediately but separately. Its 481 // (touchmove) event, great, otherwise send it immediately but separately. Its
491 // ack will trigger forwarding of the original |touch| event. 482 // ack will trigger forwarding of the original |touch| event.
492 if (pending_async_touchmove_) { 483 if (pending_async_touch_move_) {
493 if (pending_async_touchmove_->CanCoalesceWith(touch)) { 484 if (pending_async_touch_move_->CanCoalesceWith(touch)) {
494 pending_async_touchmove_->CoalesceWith(touch); 485 pending_async_touch_move_->CoalesceWith(touch);
495 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; 486 pending_async_touch_move_->event.cancelable = !send_touch_events_async_;
496 touch = *pending_async_touchmove_.Pass(); 487 touch = *pending_async_touch_move_.Pass();
497 } else { 488 } else {
498 scoped_ptr<TouchEventWithLatencyInfo> async_move = 489 scoped_ptr<TouchEventWithLatencyInfo> async_move =
499 pending_async_touchmove_.Pass(); 490 pending_async_touch_move_.Pass();
500 async_move->event.cancelable = false; 491 async_move->event.cancelable = false;
501 touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true)); 492 touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true));
502 SendTouchEventImmediately(*async_move); 493 SendTouchEventImmediately(*async_move);
503 return; 494 return;
504 } 495 }
505 } 496 }
506 497
507 // Note: Marking touchstart events as not-cancelable prevents them from 498 // Note: Marking touchstart events as not-cancelable prevents them from
508 // blocking subsequent gestures, but it may not be the best long term solution 499 // blocking subsequent gestures, but it may not be the best long term solution
509 // for tracking touch point dispatch. 500 // for tracking touch point dispatch.
(...skipping 26 matching lines...) Expand all
536 // always be preventDefault'ed (cancelable == true). 527 // always be preventDefault'ed (cancelable == true).
537 // TODO(jdduke): Revisit if touchstarts during scroll are made cancelable. 528 // TODO(jdduke): Revisit if touchstarts during scroll are made cancelable.
538 if (touch_ack_states_.empty() || 529 if (touch_ack_states_.empty() ||
539 AllTouchAckStatesHaveState( 530 AllTouchAckStatesHaveState(
540 INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS)) { 531 INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS)) {
541 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE; 532 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
542 return; 533 return;
543 } 534 }
544 } 535 }
545 536
546 pending_async_touchmove_.reset(); 537 pending_async_touch_move_.reset();
547 send_touch_events_async_ = true; 538 send_touch_events_async_ = true;
548 needs_async_touchmove_for_outer_slop_region_ = true; 539 needs_async_touch_move_for_outer_slop_region_ = true;
549 return; 540 return;
550 } 541 }
551 542
552 if (touch_scrolling_mode_ != TOUCH_SCROLLING_MODE_TOUCHCANCEL) 543 if (touch_scrolling_mode_ != TOUCH_SCROLLING_MODE_TOUCHCANCEL)
553 return; 544 return;
554 545
555 // We assume that scroll events are generated synchronously from 546 // We assume that scroll events are generated synchronously from
556 // dispatching a touch event ack. This allows us to generate a synthetic 547 // dispatching a touch event ack. This allows us to generate a synthetic
557 // cancel event that has the same touch ids as the touch event that 548 // cancel event that has the same touch ids as the touch event that
558 // is being acked. Otherwise, we don't perform the touch-cancel optimization. 549 // is being acked. Otherwise, we don't perform the touch-cancel optimization.
(...skipping 22 matching lines...) Expand all
581 if (touch_scrolling_mode_ != TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE) 572 if (touch_scrolling_mode_ != TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE)
582 return; 573 return;
583 574
584 if (event.event.type != blink::WebInputEvent::GestureScrollUpdate) 575 if (event.event.type != blink::WebInputEvent::GestureScrollUpdate)
585 return; 576 return;
586 577
587 // Throttle sending touchmove events as long as the scroll events are handled. 578 // Throttle sending touchmove events as long as the scroll events are handled.
588 // Note that there's no guarantee that this ACK is for the most recent 579 // Note that there's no guarantee that this ACK is for the most recent
589 // gesture event (or even part of the current sequence). Worst case, the 580 // gesture event (or even part of the current sequence). Worst case, the
590 // delay in updating the absorption state will result in minor UI glitches. 581 // delay in updating the absorption state will result in minor UI glitches.
591 // A valid |pending_async_touchmove_| will be flushed when the next event is 582 // A valid |pending_async_touch_move_| will be flushed when the next event is
592 // forwarded. 583 // forwarded.
593 send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED); 584 send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
594 if (!send_touch_events_async_) 585 if (!send_touch_events_async_)
595 needs_async_touchmove_for_outer_slop_region_ = false; 586 needs_async_touch_move_for_outer_slop_region_ = false;
596 } 587 }
597 588
598 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { 589 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) {
599 DCHECK(!dispatching_touch_ack_); 590 DCHECK(!dispatching_touch_ack_);
600 DCHECK(!dispatching_touch_); 591 DCHECK(!dispatching_touch_);
601 592
602 if (has_handlers) { 593 if (has_handlers) {
603 if (touch_filtering_state_ == DROP_ALL_TOUCHES) { 594 if (touch_filtering_state_ == DROP_ALL_TOUCHES) {
604 // If no touch handler was previously registered, ensure that we don't 595 // If no touch handler was previously registered, ensure that we don't
605 // send a partial touch sequence to the renderer. 596 // send a partial touch sequence to the renderer.
606 DCHECK(touch_queue_.empty()); 597 DCHECK(touch_queue_.empty());
607 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE; 598 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
608 } 599 }
609 } else { 600 } else {
610 // TODO(jdduke): Synthesize a TouchCancel if necessary to update Blink touch 601 // TODO(jdduke): Synthesize a TouchCancel if necessary to update Blink touch
611 // state tracking (e.g., if the touch handler was removed mid-sequence). 602 // state tracking (e.g., if the touch handler was removed mid-sequence).
612 touch_filtering_state_ = DROP_ALL_TOUCHES; 603 touch_filtering_state_ = DROP_ALL_TOUCHES;
613 pending_async_touchmove_.reset(); 604 pending_async_touch_move_.reset();
614 if (timeout_handler_) 605 if (timeout_handler_)
615 timeout_handler_->Reset(); 606 timeout_handler_->Reset();
616 if (!touch_queue_.empty()) 607 if (!touch_queue_.empty())
617 ProcessTouchAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, LatencyInfo()); 608 ProcessTouchAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, LatencyInfo());
618 // As there is no touch handler, ack'ing the event should flush the queue. 609 // As there is no touch handler, ack'ing the event should flush the queue.
619 DCHECK(touch_queue_.empty()); 610 DCHECK(touch_queue_.empty());
620 } 611 }
621 } 612 }
622 613
623 bool TouchEventQueue::IsPendingAckTouchStart() const { 614 bool TouchEventQueue::IsPendingAckTouchStart() const {
624 DCHECK(!dispatching_touch_ack_); 615 DCHECK(!dispatching_touch_ack_);
625 if (touch_queue_.empty()) 616 if (touch_queue_.empty())
626 return false; 617 return false;
627 618
628 const blink::WebTouchEvent& event = 619 const blink::WebTouchEvent& event =
629 touch_queue_.front()->coalesced_event().event; 620 touch_queue_.front()->coalesced_event().event;
630 return (event.type == WebInputEvent::TouchStart); 621 return (event.type == WebInputEvent::TouchStart);
631 } 622 }
632 623
633 void TouchEventQueue::SetAckTimeoutEnabled(bool enabled) { 624 void TouchEventQueue::SetAckTimeoutEnabled(bool enabled,
634 // The timeout handler is valid only if explicitly supported in the config. 625 base::TimeDelta ack_timeout_delay) {
626 if (!enabled) {
627 ack_timeout_enabled_ = false;
628 if (touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT)
629 touch_filtering_state_ = FORWARD_ALL_TOUCHES;
630 // Only reset the |timeout_handler_| if the timer is running and has not yet
631 // timed out. This ensures that an already timed out sequence is properly
632 // flushed by the handler.
633 if (timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning())
634 timeout_handler_->Reset();
635 return;
636 }
637
638 ack_timeout_enabled_ = true;
635 if (!timeout_handler_) 639 if (!timeout_handler_)
636 return; 640 timeout_handler_.reset(new TouchTimeoutHandler(this, ack_timeout_delay));
637 641 else
638 if (ack_timeout_enabled_ == enabled) 642 timeout_handler_->set_timeout_delay(ack_timeout_delay);
639 return;
640
641 ack_timeout_enabled_ = enabled;
642
643 if (enabled)
644 return;
645
646 if (touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT)
647 touch_filtering_state_ = FORWARD_ALL_TOUCHES;
648 // Only reset the |timeout_handler_| if the timer is running and has not yet
649 // timed out. This ensures that an already timed out sequence is properly
650 // flushed by the handler.
651 if (timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning())
652 timeout_handler_->Reset();
653 } 643 }
654 644
655 bool TouchEventQueue::HasPendingAsyncTouchMoveForTesting() const { 645 bool TouchEventQueue::HasPendingAsyncTouchMoveForTesting() const {
656 return pending_async_touchmove_; 646 return pending_async_touch_move_;
657 } 647 }
658 648
659 bool TouchEventQueue::IsTimeoutRunningForTesting() const { 649 bool TouchEventQueue::IsTimeoutRunningForTesting() const {
660 return timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning(); 650 return timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning();
661 } 651 }
662 652
663 const TouchEventWithLatencyInfo& 653 const TouchEventWithLatencyInfo&
664 TouchEventQueue::GetLatestEventForTesting() const { 654 TouchEventQueue::GetLatestEventForTesting() const {
665 return touch_queue_.back()->coalesced_event(); 655 return touch_queue_.back()->coalesced_event();
666 } 656 }
667 657
668 void TouchEventQueue::FlushQueue() { 658 void TouchEventQueue::FlushQueue() {
669 DCHECK(!dispatching_touch_ack_); 659 DCHECK(!dispatching_touch_ack_);
670 DCHECK(!dispatching_touch_); 660 DCHECK(!dispatching_touch_);
671 pending_async_touchmove_.reset(); 661 pending_async_touch_move_.reset();
672 if (touch_filtering_state_ != DROP_ALL_TOUCHES) 662 if (touch_filtering_state_ != DROP_ALL_TOUCHES)
673 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE; 663 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
674 while (!touch_queue_.empty()) 664 while (!touch_queue_.empty())
675 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); 665 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
676 } 666 }
677 667
678 void TouchEventQueue::PopTouchEventToClient(InputEventAckState ack_result) { 668 void TouchEventQueue::PopTouchEventToClient(InputEventAckState ack_result) {
679 AckTouchEventToClient(ack_result, PopTouchEvent()); 669 AckTouchEventToClient(ack_result, PopTouchEvent());
680 } 670 }
681 671
(...skipping 21 matching lines...) Expand all
703 693
704 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { 694 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() {
705 DCHECK(!touch_queue_.empty()); 695 DCHECK(!touch_queue_.empty());
706 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); 696 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front());
707 touch_queue_.pop_front(); 697 touch_queue_.pop_front();
708 return event.Pass(); 698 return event.Pass();
709 } 699 }
710 700
711 void TouchEventQueue::SendTouchEventImmediately( 701 void TouchEventQueue::SendTouchEventImmediately(
712 const TouchEventWithLatencyInfo& touch) { 702 const TouchEventWithLatencyInfo& touch) {
713 if (needs_async_touchmove_for_outer_slop_region_) { 703 if (needs_async_touch_move_for_outer_slop_region_) {
714 // Any event other than a touchmove (e.g., touchcancel or secondary 704 // Any event other than a touchmove (e.g., touchcancel or secondary
715 // touchstart) after a scroll has started will interrupt the need to send a 705 // touchstart) after a scroll has started will interrupt the need to send a
716 // an outer slop-region exceeding touchmove. 706 // an outer slop-region exceeding touchmove.
717 if (touch.event.type != WebInputEvent::TouchMove || 707 if (touch.event.type != WebInputEvent::TouchMove ||
718 OutsideApplicationSlopRegion(touch.event, 708 OutsideApplicationSlopRegion(touch.event,
719 touch_sequence_start_position_)) 709 touch_sequence_start_position_))
720 needs_async_touchmove_for_outer_slop_region_ = false; 710 needs_async_touch_move_for_outer_slop_region_ = false;
721 } 711 }
722 712
723 client_->SendTouchEventImmediately(touch); 713 client_->SendTouchEventImmediately(touch);
724 } 714 }
725 715
726 TouchEventQueue::PreFilterResult 716 TouchEventQueue::PreFilterResult
727 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { 717 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) {
728 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) 718 if (timeout_handler_ && timeout_handler_->FilterEvent(event))
729 return ACK_WITH_NO_CONSUMER_EXISTS; 719 return ACK_WITH_NO_CONSUMER_EXISTS;
730 720
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 iter != end; 786 iter != end;
797 ++iter) { 787 ++iter) {
798 if (iter->second != ack_state) 788 if (iter->second != ack_state)
799 return false; 789 return false;
800 } 790 }
801 791
802 return true; 792 return true;
803 } 793 }
804 794
805 } // namespace content 795 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698