1558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/renderer_host/input/touch_event_queue.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/auto_reset.h" 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/command_line.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/debug/trace_event.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/renderer_host/input/timeout_monitor.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/common/input/web_input_event_traits.h" 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/common/content_switches.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using blink::WebInputEvent; 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using blink::WebTouchEvent; 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using blink::WebTouchPoint; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace { 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const InputEventAckState kDefaultNotForwardedAck = 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const TouchEventWithLatencyInfo& event_to_cancel) { 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TouchEventWithLatencyInfo event = event_to_cancel; 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) event.event.type = WebInputEvent::TouchCancel; 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < event.event.touchesLength; i++) 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) event.event.touches[i].state = WebTouchPoint::StateCancelled; 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return event; 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool IsNewTouchGesture(const WebTouchEvent& event) { 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (event.type != WebInputEvent::TouchStart) 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!event.touchesLength) 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < event.touchesLength; i++) { 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (event.touches[i].state != WebTouchPoint::StatePressed) 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return true; 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ShouldTouchTypeTriggerTimeout(WebInputEvent::Type type) { 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return type == WebInputEvent::TouchStart || 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) type == WebInputEvent::TouchMove; 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class TouchEventQueue::TouchTimeoutHandler { 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TouchTimeoutHandler(TouchEventQueue* touch_queue, size_t timeout_delay_ms) 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : touch_queue_(touch_queue), 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) timeout_delay_(base::TimeDelta::FromMilliseconds(timeout_delay_ms)), 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) pending_ack_state_(PENDING_ACK_NONE), 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) timeout_monitor_(base::Bind(&TouchTimeoutHandler::OnTimeOut, 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Unretained(this))) {} 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ~TouchTimeoutHandler() {} 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void Start(const TouchEventWithLatencyInfo& event) { 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE); 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(ShouldTouchTypeTriggerTimeout(event.event.type)); 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) timeout_event_ = event; 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) timeout_monitor_.Restart(timeout_delay_); 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool ConfirmTouchEvent(InputEventAckState ack_result) { 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) switch (pending_ack_state_) { 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PENDING_ACK_NONE: 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) timeout_monitor_.Stop(); 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PENDING_ACK_ORIGINAL_EVENT: 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (AckedTimeoutEventRequiresCancel(ack_result)) { 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetPendingAckState(PENDING_ACK_CANCEL_EVENT); 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TouchEventWithLatencyInfo cancel_event = 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ObtainCancelEventForTouchEvent(timeout_event_); 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_queue_->UpdateTouchAckStates( 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cancel_event.event, kDefaultNotForwardedAck); 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_queue_->client_->SendTouchEventImmediately(cancel_event); 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetPendingAckState(PENDING_ACK_NONE); 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_queue_->UpdateTouchAckStates(timeout_event_.event, ack_result); 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return true; 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PENDING_ACK_CANCEL_EVENT: 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetPendingAckState(PENDING_ACK_NONE); 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return true; 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool HasTimeoutEvent() const { 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return pending_ack_state_ != PENDING_ACK_NONE; 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool IsTimeoutTimerRunning() const { 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return timeout_monitor_.IsRunning(); 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) enum PendingAckState { 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PENDING_ACK_NONE, 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PENDING_ACK_ORIGINAL_EVENT, 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PENDING_ACK_CANCEL_EVENT, 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) }; 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void OnTimeOut() { 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetPendingAckState(PENDING_ACK_ORIGINAL_EVENT); 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_queue_->FlushQueue(); 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Skip a cancel event if the timed-out event had no consumer and was the 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // initial event in the gesture. 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool AckedTimeoutEventRequiresCancel(InputEventAckState ack_result) const { 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(HasTimeoutEvent()); 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return true; 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return !IsNewTouchGesture(timeout_event_.event); 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void SetPendingAckState(PendingAckState new_pending_ack_state) { 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_NE(pending_ack_state_, new_pending_ack_state); 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) switch (new_pending_ack_state) { 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PENDING_ACK_ORIGINAL_EVENT: 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE); 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this); 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PENDING_ACK_CANCEL_EVENT: 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(pending_ack_state_, PENDING_ACK_ORIGINAL_EVENT); 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!timeout_monitor_.IsRunning()); 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(touch_queue_->empty()); 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TRACE_EVENT_ASYNC_STEP_INTO0( 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "input", "TouchEventTimeout", this, "CancelEvent"); 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PENDING_ACK_NONE: 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!timeout_monitor_.IsRunning()); 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(touch_queue_->empty()); 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TRACE_EVENT_ASYNC_END0("input", "TouchEventTimeout", this); 145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) pending_ack_state_ = new_pending_ack_state; 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TouchEventQueue* touch_queue_; 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // How long to wait on a touch ack before cancelling the touch sequence. 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::TimeDelta timeout_delay_; 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The touch event source for which we expect the next ack. 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PendingAckState pending_ack_state_; 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The event for which the ack timeout is triggered. 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TouchEventWithLatencyInfo timeout_event_; 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Provides timeout-based callback behavior. 163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TimeoutMonitor timeout_monitor_; 164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class represents a single coalesced touch event. However, it also keeps 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// track of all the original touch-events that were coalesced into a single 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// event. The coalesced event is forwarded to the renderer, while the original 170ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// touch-events are sent to the Client (on ACK for the coalesced event) so that 171ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// the Client receives the event with their original timestamp. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CoalescedWebTouchEvent { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event, 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool ignore_ack) 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : coalesced_event_(event), 177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ignore_ack_(ignore_ack) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.push_back(event); 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN0( 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "input", "TouchEventQueue::QueueEvent", this); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ~CoalescedWebTouchEvent() { 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TRACE_EVENT_ASYNC_END0( 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "input", "TouchEventQueue::QueueEvent", this); 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Coalesces the event with the existing event if possible. Returns whether 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the event was coalesced. 1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool CoalesceEventIfPossible( 1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const TouchEventWithLatencyInfo& event_with_latency) { 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ignore_ack_) 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!coalesced_event_.CanCoalesceWith(event_with_latency)) 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TRACE_EVENT_INSTANT0( 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "input", "TouchEventQueue::MoveCoalesced", TRACE_EVENT_SCOPE_THREAD); 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) coalesced_event_.CoalesceWith(event_with_latency); 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) events_.push_back(event_with_latency); 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const TouchEventWithLatencyInfo& coalesced_event() const { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return coalesced_event_; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebTouchEventWithLatencyList::iterator begin() { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return events_.begin(); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebTouchEventWithLatencyList::iterator end() { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return events_.end(); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size() const { return events_.size(); } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ignore_ack() const { return ignore_ack_; } 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the event that is forwarded to the renderer. 2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TouchEventWithLatencyInfo coalesced_event_; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the list of the original events that were coalesced. 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) WebTouchEventWithLatencyList events_; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If |ignore_ack_| is true, don't send this touch event to client 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // when the event is acked. 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ignore_ack_; 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTouchEventQueue::TouchEventQueue(TouchEventQueueClient* client) 236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch : client_(client), 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dispatching_touch_ack_(NULL), 238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dispatching_touch_(false), 239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) no_touch_to_renderer_(false), 240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) renderer_is_consuming_touch_gesture_(false), 241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ack_timeout_enabled_(false) { 242ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(client); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TouchEventQueue::~TouchEventQueue() { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!touch_queue_.empty()) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&touch_queue_); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If the queueing of |event| was triggered by an ack dispatch, defer 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // processing the event until the dispatch has finished. 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (touch_queue_.empty() && !dispatching_touch_ack_) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no touch event in the queue. Forward it to the renderer 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // immediately. 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); 25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TryForwardNextEventToRenderer(); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the last queued touch-event was a touch-move, and the current event is 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // also a touch-move, then the events can be coalesced into a single event. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (touch_queue_.size() > 1) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CoalescedWebTouchEvent* last_event = touch_queue_.back(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_event->CoalesceEventIfPossible(event)) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, 2723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const ui::LatencyInfo& latency_info) { 2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!dispatching_touch_ack_); 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dispatching_touch_ = false; 275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (timeout_handler_ && timeout_handler_->ConfirmTouchEvent(ack_result)) 277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (touch_queue_.empty()) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) renderer_is_consuming_touch_gesture_ = true; 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const WebTouchEvent& acked_event = 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_queue_.front()->coalesced_event().event; 287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateTouchAckStates(acked_event, ack_result); 2883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch PopTouchEventToClient(ack_result, latency_info); 28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TryForwardNextEventToRenderer(); 29068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TouchEventQueue::TryForwardNextEventToRenderer() { 2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!dispatching_touch_ack_); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there are queued touch events, then try to forward them to the renderer 295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // immediately, or ACK the events back to the client if appropriate. 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!touch_queue_.empty()) { 2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const TouchEventWithLatencyInfo& touch = 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) touch_queue_.front()->coalesced_event(); 299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (IsNewTouchGesture(touch.event)) 300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) renderer_is_consuming_touch_gesture_ = false; 3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (ShouldForwardToRenderer(touch.event)) { 302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ForwardToRenderer(touch); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo()); 306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void TouchEventQueue::ForwardToRenderer( 310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const TouchEventWithLatencyInfo& touch) { 311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!dispatching_touch_); 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // A synchronous ack will reset |dispatching_touch_|, in which case 313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // the touch timeout should not be started. 314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); 315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) client_->SendTouchEventImmediately(touch); 316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (ack_timeout_enabled_ && 317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dispatching_touch_ && 318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !renderer_is_consuming_touch_gesture_ && 319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ShouldTouchTypeTriggerTimeout(touch.event.type)) { 320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(timeout_handler_); 321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) timeout_handler_->Start(touch); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TouchEventQueue::OnGestureScrollEvent( 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GestureEventWithLatencyInfo& gesture_event) { 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebInputEvent::Type type = gesture_event.event.type; 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (type == blink::WebInputEvent::GestureScrollBegin) { 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We assume the scroll event are generated synchronously from 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // dispatching a touch event ack, so that we can fake a cancel 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // event that has the correct touch ids as the touch event that 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // is being acked. If not, we don't do the touch-cancel optimization. 3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (no_touch_to_renderer_ || !dispatching_touch_ack_) 3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) no_touch_to_renderer_ = true; 336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If we have a timeout event, a cancel has already been dispatched 338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // for the current touch stream. 339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (HasTimeoutEvent()) 340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Fake a TouchCancel to cancel the touch points of the touch event 3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // that is currently being acked. 344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we 3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // are in the scope of PopTouchEventToClient() and that no touch event 3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // in the queue is waiting for ack from renderer. So we can just insert 3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the touch cancel at the beginning of the queue. 348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_queue_.push_front(new CoalescedWebTouchEvent( 349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ObtainCancelEventForTouchEvent( 350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dispatching_touch_ack_->coalesced_event()), true)); 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (type == blink::WebInputEvent::GestureScrollEnd || 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) type == blink::WebInputEvent::GestureFlingStart) { 3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) no_touch_to_renderer_ = false; 3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TouchEventQueue::FlushQueue() { 3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!dispatching_touch_ack_); 359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!dispatching_touch_); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!touch_queue_.empty()) 361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo()); 362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool TouchEventQueue::IsPendingAckTouchStart() const { 365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!dispatching_touch_ack_); 366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (touch_queue_.empty()) 367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const blink::WebTouchEvent& event = 370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_queue_.front()->coalesced_event().event; 371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return (event.type == WebInputEvent::TouchStart); 372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void TouchEventQueue::SetAckTimeoutEnabled(bool enabled, 375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) size_t ack_timeout_delay_ms) { 376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!enabled) { 377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Avoid resetting |timeout_handler_|, as an outstanding timeout may 378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // be active and must be completed for ack handling consistency. 379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ack_timeout_enabled_ = false; 380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ack_timeout_enabled_ = true; 384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!timeout_handler_) 385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) timeout_handler_.reset(new TouchTimeoutHandler(this, ack_timeout_delay_ms)); 386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool TouchEventQueue::HasTimeoutEvent() const { 389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return timeout_handler_ && timeout_handler_->HasTimeoutEvent(); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool TouchEventQueue::IsTimeoutRunningForTesting() const { 393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning(); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const TouchEventWithLatencyInfo& 397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TouchEventQueue::GetLatestEventForTesting() const { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return touch_queue_.back()->coalesced_event(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid TouchEventQueue::PopTouchEventToClient( 4023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch InputEventAckState ack_result, 4033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const ui::LatencyInfo& renderer_latency_info) { 404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!dispatching_touch_ack_); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (touch_queue_.empty()) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CoalescedWebTouchEvent> acked_event(touch_queue_.front()); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) touch_queue_.pop_front(); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (acked_event->ignore_ack()) 4114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that acking the touch-event may result in multiple gestures being sent 4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // to the renderer, or touch-events being queued. 4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::AutoReset<CoalescedWebTouchEvent*> 4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dispatching_touch_ack(&dispatching_touch_ack_, acked_event.get()); 4177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (WebTouchEventWithLatencyList::iterator iter = acked_event->begin(), 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = acked_event->end(); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != end; ++iter) { 4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iter->latency.AddNewLatencyFrom(renderer_latency_info); 422ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch client_->OnTouchEventAck((*iter), ack_result); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TouchEventQueue::ShouldForwardToRenderer( 427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const WebTouchEvent& event) const { 428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (HasTimeoutEvent()) 429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (no_touch_to_renderer_ && 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event.type != blink::WebInputEvent::TouchCancel) 4334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Touch press events should always be forwarded to the renderer. 436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (event.type == WebInputEvent::TouchStart) 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < event.touchesLength; ++i) { 440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const WebTouchPoint& point = event.touches[i]; 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If a point has been stationary, then don't take it into account. 442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (point.state == WebTouchPoint::StateStationary) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (touch_ack_states_.count(point.id) > 0) { 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (touch_ack_states_.find(point.id)->second != 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the ACK status of a point is unknown, then the event should be 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // forwarded to the renderer. 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void TouchEventQueue::UpdateTouchAckStates(const WebTouchEvent& event, 460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InputEventAckState ack_result) { 461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Update the ACK status for each touch point in the ACKed event. 462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (event.type == WebInputEvent::TouchEnd || 463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) event.type == WebInputEvent::TouchCancel) { 464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The points have been released. Erase the ACK states. 465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (unsigned i = 0; i < event.touchesLength; ++i) { 466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const WebTouchPoint& point = event.touches[i]; 467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (point.state == WebTouchPoint::StateReleased || 468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) point.state == WebTouchPoint::StateCancelled) 469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_ack_states_.erase(point.id); 470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (event.type == WebInputEvent::TouchStart) { 472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (unsigned i = 0; i < event.touchesLength; ++i) { 473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const WebTouchPoint& point = event.touches[i]; 474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (point.state == WebTouchPoint::StatePressed) 475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) touch_ack_states_[point.id] = ack_result; 476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 481