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

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

Issue 788923002: Touch Events - changedTouches list includes non-changed touch points on Android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 5 years, 10 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/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
10 #include "content/browser/renderer_host/input/timeout_monitor.h" 10 #include "content/browser/renderer_host/input/timeout_monitor.h"
(...skipping 27 matching lines...) Expand all
38 &event.event); 38 &event.event);
39 return event; 39 return event;
40 } 40 }
41 41
42 bool ShouldTouchTriggerTimeout(const WebTouchEvent& event) { 42 bool ShouldTouchTriggerTimeout(const WebTouchEvent& event) {
43 return (event.type == WebInputEvent::TouchStart || 43 return (event.type == WebInputEvent::TouchStart ||
44 event.type == WebInputEvent::TouchMove) && 44 event.type == WebInputEvent::TouchMove) &&
45 !WebInputEventTraits::IgnoresAckDisposition(event); 45 !WebInputEventTraits::IgnoresAckDisposition(event);
46 } 46 }
47 47
48 // Compare all properties of touch points to determine the state.
49 bool HasPointChanged(const WebTouchPoint& last_point,
50 const WebTouchPoint& current_point) {
51 if (last_point.screenPosition != current_point.screenPosition ||
52 last_point.position != current_point.position ||
53 last_point.radiusX != current_point.radiusX ||
54 last_point.radiusY != current_point.radiusY ||
55 last_point.rotationAngle != current_point.rotationAngle ||
56 last_point.force != current_point.force) {
57 return true;
58 }
59 return false;
60 }
61
48 } // namespace 62 } // namespace
49 63
50 64
51 // Cancels a touch sequence if a touchstart or touchmove ack response is 65 // Cancels a touch sequence if a touchstart or touchmove ack response is
52 // sufficiently delayed. 66 // sufficiently delayed.
53 class TouchEventQueue::TouchTimeoutHandler { 67 class TouchEventQueue::TouchTimeoutHandler {
54 public: 68 public:
55 TouchTimeoutHandler(TouchEventQueue* touch_queue, 69 TouchTimeoutHandler(TouchEventQueue* touch_queue,
56 base::TimeDelta timeout_delay) 70 base::TimeDelta timeout_delay)
57 : touch_queue_(touch_queue), 71 : touch_queue_(touch_queue),
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 case PENDING_ACK_NONE: 103 case PENDING_ACK_NONE:
90 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) 104 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
91 enabled_for_current_sequence_ = false; 105 enabled_for_current_sequence_ = false;
92 timeout_monitor_.Stop(); 106 timeout_monitor_.Stop();
93 return false; 107 return false;
94 case PENDING_ACK_ORIGINAL_EVENT: 108 case PENDING_ACK_ORIGINAL_EVENT:
95 if (AckedTimeoutEventRequiresCancel(ack_result)) { 109 if (AckedTimeoutEventRequiresCancel(ack_result)) {
96 SetPendingAckState(PENDING_ACK_CANCEL_EVENT); 110 SetPendingAckState(PENDING_ACK_CANCEL_EVENT);
97 TouchEventWithLatencyInfo cancel_event = 111 TouchEventWithLatencyInfo cancel_event =
98 ObtainCancelEventForTouchEvent(timeout_event_); 112 ObtainCancelEventForTouchEvent(timeout_event_);
99 touch_queue_->SendTouchEventImmediately(cancel_event); 113 touch_queue_->SendTouchEventImmediately(&cancel_event);
100 } else { 114 } else {
101 SetPendingAckState(PENDING_ACK_NONE); 115 SetPendingAckState(PENDING_ACK_NONE);
102 touch_queue_->UpdateTouchConsumerStates(timeout_event_.event, 116 touch_queue_->UpdateTouchConsumerStates(timeout_event_.event,
103 ack_result); 117 ack_result);
104 } 118 }
105 return true; 119 return true;
106 case PENDING_ACK_CANCEL_EVENT: 120 case PENDING_ACK_CANCEL_EVENT:
107 SetPendingAckState(PENDING_ACK_NONE); 121 SetPendingAckState(PENDING_ACK_NONE);
108 return true; 122 return true;
109 } 123 }
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 if (pending_async_touchmove_->CanCoalesceWith(touch)) { 507 if (pending_async_touchmove_->CanCoalesceWith(touch)) {
494 pending_async_touchmove_->CoalesceWith(touch); 508 pending_async_touchmove_->CoalesceWith(touch);
495 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; 509 pending_async_touchmove_->event.cancelable = !send_touch_events_async_;
496 touch = *pending_async_touchmove_; 510 touch = *pending_async_touchmove_;
497 pending_async_touchmove_.reset(); 511 pending_async_touchmove_.reset();
498 } else { 512 } else {
499 scoped_ptr<TouchEventWithLatencyInfo> async_move = 513 scoped_ptr<TouchEventWithLatencyInfo> async_move =
500 pending_async_touchmove_.Pass(); 514 pending_async_touchmove_.Pass();
501 async_move->event.cancelable = false; 515 async_move->event.cancelable = false;
502 touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true)); 516 touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true));
503 SendTouchEventImmediately(*async_move); 517 SendTouchEventImmediately(async_move.get());
504 return; 518 return;
505 } 519 }
506 } 520 }
507 521
508 // Note: Touchstart events are marked cancelable to allow transitions between 522 // Note: Touchstart events are marked cancelable to allow transitions between
509 // platform scrolling and JS pinching. Touchend events, however, remain 523 // platform scrolling and JS pinching. Touchend events, however, remain
510 // uncancelable, mitigating the risk of jank when transitioning to a fling. 524 // uncancelable, mitigating the risk of jank when transitioning to a fling.
511 if (send_touch_events_async_ && touch.event.type != WebInputEvent::TouchStart) 525 if (send_touch_events_async_ && touch.event.type != WebInputEvent::TouchStart)
512 touch.event.cancelable = false; 526 touch.event.cancelable = false;
513 527
514 // A synchronous ack will reset |dispatching_touch_|, in which case 528 // A synchronous ack will reset |dispatching_touch_|, in which case
515 // the touch timeout should not be started. 529 // the touch timeout should not be started.
516 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); 530 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true);
517 SendTouchEventImmediately(touch); 531 SendTouchEventImmediately(&touch);
518 if (dispatching_touch_ && timeout_handler_) 532 if (dispatching_touch_ && timeout_handler_)
519 timeout_handler_->StartIfNecessary(touch); 533 timeout_handler_->StartIfNecessary(touch);
520 } 534 }
521 535
522 void TouchEventQueue::OnGestureScrollEvent( 536 void TouchEventQueue::OnGestureScrollEvent(
523 const GestureEventWithLatencyInfo& gesture_event) { 537 const GestureEventWithLatencyInfo& gesture_event) {
524 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) { 538 if (gesture_event.event.type == blink::WebInputEvent::GestureScrollBegin) {
525 if (!touch_consumer_states_.is_empty() && 539 if (!touch_consumer_states_.is_empty() &&
526 !drop_remaining_touches_in_sequence_) { 540 !drop_remaining_touches_in_sequence_) {
527 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) 541 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves())
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 } 681 }
668 682
669 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() { 683 scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() {
670 DCHECK(!touch_queue_.empty()); 684 DCHECK(!touch_queue_.empty());
671 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front()); 685 scoped_ptr<CoalescedWebTouchEvent> event(touch_queue_.front());
672 touch_queue_.pop_front(); 686 touch_queue_.pop_front();
673 return event.Pass(); 687 return event.Pass();
674 } 688 }
675 689
676 void TouchEventQueue::SendTouchEventImmediately( 690 void TouchEventQueue::SendTouchEventImmediately(
677 const TouchEventWithLatencyInfo& touch) { 691 TouchEventWithLatencyInfo* touch) {
678 client_->SendTouchEventImmediately(touch); 692 // For touchmove events, compare touch points position from current event
693 // to last sent event and update touch points state.
694 if (touch->event.type == WebInputEvent::TouchMove) {
695 CHECK(last_sent_touchevent_);
696 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) {
697 const WebTouchPoint& last_touch_point =
698 last_sent_touchevent_->touches[i];
699 // Touches with same id may not have same index in Touches array.
700 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) {
701 const WebTouchPoint& current_touchmove_point = touch->event.touches[j];
702 if (current_touchmove_point.id != last_touch_point.id)
703 continue;
704
705 if (!HasPointChanged(last_touch_point, current_touchmove_point))
706 touch->event.touches[j].state = WebTouchPoint::StateStationary;
707
708 break;
709 }
710 }
711 }
712
713 if (last_sent_touchevent_)
714 *last_sent_touchevent_ = touch->event;
715 else
716 last_sent_touchevent_.reset(new WebTouchEvent(touch->event));
717
718 client_->SendTouchEventImmediately(*touch);
679 } 719 }
680 720
681 TouchEventQueue::PreFilterResult 721 TouchEventQueue::PreFilterResult
682 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { 722 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) {
683 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) 723 if (timeout_handler_ && timeout_handler_->FilterEvent(event))
684 return ACK_WITH_NO_CONSUMER_EXISTS; 724 return ACK_WITH_NO_CONSUMER_EXISTS;
685 725
686 if (touchmove_slop_suppressor_->FilterEvent(event)) 726 if (touchmove_slop_suppressor_->FilterEvent(event))
687 return ACK_WITH_NOT_CONSUMED; 727 return ACK_WITH_NOT_CONSUMED;
688 728
689 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { 729 if (WebTouchEventTraits::IsTouchSequenceStart(event)) {
690 touch_consumer_states_.clear(); 730 touch_consumer_states_.clear();
691 send_touch_events_async_ = false; 731 send_touch_events_async_ = false;
692 pending_async_touchmove_.reset(); 732 pending_async_touchmove_.reset();
733 last_sent_touchevent_.reset();
734
693 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); 735 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position);
694 drop_remaining_touches_in_sequence_ = false; 736 drop_remaining_touches_in_sequence_ = false;
695 if (!has_handlers_) { 737 if (!has_handlers_) {
696 drop_remaining_touches_in_sequence_ = true; 738 drop_remaining_touches_in_sequence_ = true;
697 return ACK_WITH_NO_CONSUMER_EXISTS; 739 return ACK_WITH_NO_CONSUMER_EXISTS;
698 } 740 }
699 } 741 }
700 742
701 if (drop_remaining_touches_in_sequence_ && 743 if (drop_remaining_touches_in_sequence_ &&
702 event.type != WebInputEvent::TouchCancel) { 744 event.type != WebInputEvent::TouchCancel) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) 784 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS)
743 touch_consumer_states_.mark_bit(point.id); 785 touch_consumer_states_.mark_bit(point.id);
744 else 786 else
745 touch_consumer_states_.clear_bit(point.id); 787 touch_consumer_states_.clear_bit(point.id);
746 } 788 }
747 } 789 }
748 } 790 }
749 } 791 }
750 792
751 } // namespace content 793 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698