touch_event_queue.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/debug/trace_event.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class represents a single coalesced touch event. However, it also keeps 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// track of all the original touch-events that were coalesced into a single 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// event. The coalesced event is forwarded to the renderer, while the original 18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// touch-events are sent to the Client (on ACK for the coalesced event) so that 19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// the Client receives the event with their original timestamp. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CoalescedWebTouchEvent { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) explicit CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event) 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : coalesced_event_(event), 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ignore_ack_(false) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.push_back(event); 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN0( 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "input", "TouchEventQueue::QueueEvent", this); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ~CoalescedWebTouchEvent() { 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TRACE_EVENT_ASYNC_END0( 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "input", "TouchEventQueue::QueueEvent", this); 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Coalesces the event with the existing event if possible. Returns whether 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the event was coalesced. 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool CoalesceEventIfPossible( 387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const TouchEventWithLatencyInfo& event_with_latency) { 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ignore_ack_) 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!coalesced_event_.CanCoalesceWith(event_with_latency)) 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TRACE_EVENT_INSTANT0( 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "input", "TouchEventQueue::MoveCoalesced", TRACE_EVENT_SCOPE_THREAD); 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) coalesced_event_.CoalesceWith(event_with_latency); 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) events_.push_back(event_with_latency); 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const TouchEventWithLatencyInfo& coalesced_event() const { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return coalesced_event_; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebTouchEventWithLatencyList::iterator begin() { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return events_.begin(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebTouchEventWithLatencyList::iterator end() { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return events_.end(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size() const { return events_.size(); } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ignore_ack() const { return ignore_ack_; } 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void set_ignore_ack(bool value) { ignore_ack_ = value; } 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the event that is forwarded to the renderer. 717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TouchEventWithLatencyInfo coalesced_event_; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the list of the original events that were coalesced. 747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) WebTouchEventWithLatencyList events_; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If |ignore_ack_| is true, don't send this touch event to client 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // when the event is acked. 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ignore_ack_; 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 83ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochTouchEventQueue::TouchEventQueue(TouchEventQueueClient* client) 84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch : client_(client), 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dispatching_touch_ack_(NULL), 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) no_touch_to_renderer_(false) { 87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(client); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TouchEventQueue::~TouchEventQueue() { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!touch_queue_.empty()) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&touch_queue_); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If the queueing of |event| was triggered by an ack dispatch, defer 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // processing the event until the dispatch has finished. 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (touch_queue_.empty() && !dispatching_touch_ack_) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no touch event in the queue. Forward it to the renderer 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // immediately. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) touch_queue_.push_back(new CoalescedWebTouchEvent(event)); 10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TryForwardNextEventToRenderer(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the last queued touch-event was a touch-move, and the current event is 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // also a touch-move, then the events can be coalesced into a single event. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (touch_queue_.size() > 1) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CoalescedWebTouchEvent* last_event = touch_queue_.back(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_event->CoalesceEventIfPossible(event)) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) touch_queue_.push_back(new CoalescedWebTouchEvent(event)); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, 1173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const ui::LatencyInfo& latency_info) { 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!dispatching_touch_ack_); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (touch_queue_.empty()) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update the ACK status for each touch point in the ACKed event. 1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const WebKit::WebTouchEvent& event = 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) touch_queue_.front()->coalesced_event().event; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event.type == WebKit::WebInputEvent::TouchEnd || 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event.type == WebKit::WebInputEvent::TouchCancel) { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The points have been released. Erase the ACK states. 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned i = 0; i < event.touchesLength; ++i) { 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WebKit::WebTouchPoint& point = event.touches[i]; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (point.state == WebKit::WebTouchPoint::StateReleased || 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) point.state == WebKit::WebTouchPoint::StateCancelled) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) touch_ack_states_.erase(point.id); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (event.type == WebKit::WebInputEvent::TouchStart) { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned i = 0; i < event.touchesLength; ++i) { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WebKit::WebTouchPoint& point = event.touches[i]; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (point.state == WebKit::WebTouchPoint::StatePressed) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) touch_ack_states_[point.id] = ack_result; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch PopTouchEventToClient(ack_result, latency_info); 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TryForwardNextEventToRenderer(); 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TouchEventQueue::TryForwardNextEventToRenderer() { 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!dispatching_touch_ack_); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there are queued touch events, then try to forward them to the renderer 149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // immediately, or ACK the events back to the client if appropriate. 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!touch_queue_.empty()) { 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const TouchEventWithLatencyInfo& touch = 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) touch_queue_.front()->coalesced_event(); 1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (ShouldForwardToRenderer(touch.event)) { 154ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch client_->SendTouchEventImmediately(touch); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, 1583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ui::LatencyInfo()); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TouchEventQueue::OnGestureScrollEvent( 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GestureEventWithLatencyInfo& gesture_event) { 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebKit::WebInputEvent::Type type = gesture_event.event.type; 1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (type == WebKit::WebInputEvent::GestureScrollBegin) { 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We assume the scroll event are generated synchronously from 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // dispatching a touch event ack, so that we can fake a cancel 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // event that has the correct touch ids as the touch event that 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // is being acked. If not, we don't do the touch-cancel optimization. 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (no_touch_to_renderer_ || !dispatching_touch_ack_) 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) no_touch_to_renderer_ = true; 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Fake a TouchCancel to cancel the touch points of the touch event 1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // that is currently being acked. 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TouchEventWithLatencyInfo cancel_event = 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dispatching_touch_ack_->coalesced_event(); 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cancel_event.event.type = WebKit::WebInputEvent::TouchCancel; 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < cancel_event.event.touchesLength; i++) 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cancel_event.event.touches[i].state = 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebKit::WebTouchPoint::StateCancelled; 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CoalescedWebTouchEvent* coalesced_cancel_event = 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new CoalescedWebTouchEvent(cancel_event); 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Ignore the ack of the touch cancel so when it is acked, it won't get 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // sent to gesture recognizer. 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) coalesced_cancel_event->set_ignore_ack(true); 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |dispatching_touch_ack_| is non-null when we reach here, meaning we 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // are in the scope of PopTouchEventToClient() and that no touch event 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // in the queue is waiting for ack from renderer. So we can just insert 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the touch cancel at the beginning of the queue. 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) touch_queue_.push_front(coalesced_cancel_event); 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else if (type == WebKit::WebInputEvent::GestureScrollEnd || 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) type == WebKit::WebInputEvent::GestureFlingStart) { 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) no_touch_to_renderer_ = false; 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TouchEventQueue::FlushQueue() { 1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!dispatching_touch_ack_); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!touch_queue_.empty()) 2003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, 2013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch ui::LatencyInfo()); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t TouchEventQueue::GetQueueSize() const { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return touch_queue_.size(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const TouchEventWithLatencyInfo& TouchEventQueue::GetLatestEvent() const { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return touch_queue_.back()->coalesced_event(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid TouchEventQueue::PopTouchEventToClient( 2133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch InputEventAckState ack_result, 2143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const ui::LatencyInfo& renderer_latency_info) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (touch_queue_.empty()) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CoalescedWebTouchEvent> acked_event(touch_queue_.front()); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) touch_queue_.pop_front(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (acked_event->ignore_ack()) 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that acking the touch-event may result in multiple gestures being sent 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // to the renderer, or touch-events being queued. 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::AutoReset<CoalescedWebTouchEvent*> 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dispatching_touch_ack(&dispatching_touch_ack_, acked_event.get()); 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (WebTouchEventWithLatencyList::iterator iter = acked_event->begin(), 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = acked_event->end(); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != end; ++iter) { 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iter->latency.AddNewLatencyFrom(renderer_latency_info); 232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch client_->OnTouchEventAck((*iter), ack_result); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TouchEventQueue::ShouldForwardToRenderer( 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WebKit::WebTouchEvent& event) const { 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (no_touch_to_renderer_ && 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) event.type != WebKit::WebInputEvent::TouchCancel) 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Touch press events should always be forwarded to the renderer. 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event.type == WebKit::WebInputEvent::TouchStart) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < event.touchesLength; ++i) { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WebKit::WebTouchPoint& point = event.touches[i]; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If a point has been stationary, then don't take it into account. 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (point.state == WebKit::WebTouchPoint::StateStationary) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (touch_ack_states_.count(point.id) > 0) { 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (touch_ack_states_.find(point.id)->second != 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the ACK status of a point is unknown, then the event should be 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // forwarded to the renderer. 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 267