OLD | NEW |
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 #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_ | 5 #ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_ |
6 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_ | 6 #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <map> | 9 #include <map> |
10 | 10 |
(...skipping 30 matching lines...) Expand all Loading... |
41 // TODO(rbyers): Remove this once we're confident that touch move absorption | 41 // TODO(rbyers): Remove this once we're confident that touch move absorption |
42 // is OK. http://crbug.com/350430 | 42 // is OK. http://crbug.com/350430 |
43 enum TouchScrollingMode { | 43 enum TouchScrollingMode { |
44 // Send a touchcancel on scroll start and no further touch events for the | 44 // Send a touchcancel on scroll start and no further touch events for the |
45 // duration of the scroll. Chrome Android's traditional behavior. | 45 // duration of the scroll. Chrome Android's traditional behavior. |
46 TOUCH_SCROLLING_MODE_TOUCHCANCEL, | 46 TOUCH_SCROLLING_MODE_TOUCHCANCEL, |
47 // Send touchmove events throughout a scroll, blocking on each ACK and | 47 // Send touchmove events throughout a scroll, blocking on each ACK and |
48 // using the disposition to determine whether a scroll update should be | 48 // using the disposition to determine whether a scroll update should be |
49 // sent. Mobile Safari's default overflow scroll behavior. | 49 // sent. Mobile Safari's default overflow scroll behavior. |
50 TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE, | 50 TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE, |
51 // Like sync, except that consumed scroll events cause subsequent touchmove | 51 // Send touchmove events throughout a scroll, but throttle sending and |
52 // events to be suppressed. Unconsumed scroll events return touchmove | 52 // ignore the ACK as long as scrolling remains possible. Unconsumed scroll |
53 // events to being dispatched synchronously (so scrolling may be hijacked | 53 // events return touchmove events to being dispatched synchronously. |
54 // when a scroll limit is reached, and later resumed). http://goo.gl/RShsdN | 54 TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE, |
55 TOUCH_SCROLLING_MODE_ABSORB_TOUCHMOVE, | 55 TOUCH_SCROLLING_MODE_DEFAULT = TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE |
56 TOUCH_SCROLLING_MODE_DEFAULT = TOUCH_SCROLLING_MODE_TOUCHCANCEL | |
57 }; | 56 }; |
58 | 57 |
59 // The |client| must outlive the TouchEventQueue. If | 58 // The |client| must outlive the TouchEventQueue. If |
60 // |touchmove_suppression_length_dips| <= 0, touch move suppression is | 59 // |touchmove_suppression_length_dips| <= 0, touch move suppression is |
61 // disabled. | 60 // disabled. |
62 TouchEventQueue(TouchEventQueueClient* client, | 61 TouchEventQueue(TouchEventQueueClient* client, |
63 TouchScrollingMode mode, | 62 TouchScrollingMode mode, |
64 double touchmove_suppression_length_dips); | 63 double touchmove_suppression_length_dips); |
65 ~TouchEventQueue(); | 64 ~TouchEventQueue(); |
66 | 65 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 bool has_handlers() const { | 112 bool has_handlers() const { |
114 return touch_filtering_state_ != DROP_ALL_TOUCHES; | 113 return touch_filtering_state_ != DROP_ALL_TOUCHES; |
115 } | 114 } |
116 | 115 |
117 private: | 116 private: |
118 class TouchTimeoutHandler; | 117 class TouchTimeoutHandler; |
119 class TouchMoveSlopSuppressor; | 118 class TouchMoveSlopSuppressor; |
120 friend class TouchTimeoutHandler; | 119 friend class TouchTimeoutHandler; |
121 friend class TouchEventQueueTest; | 120 friend class TouchEventQueueTest; |
122 | 121 |
123 bool HasTimeoutEvent() const; | 122 bool HasPendingAsyncTouchMoveForTesting() const; |
124 bool IsTimeoutRunningForTesting() const; | 123 bool IsTimeoutRunningForTesting() const; |
125 const TouchEventWithLatencyInfo& GetLatestEventForTesting() const; | 124 const TouchEventWithLatencyInfo& GetLatestEventForTesting() const; |
126 | 125 |
127 // Empties the queue of touch events. This may result in any number of gesture | 126 // Empties the queue of touch events. This may result in any number of gesture |
128 // events being sent to the renderer. | 127 // events being sent to the renderer. |
129 void FlushQueue(); | 128 void FlushQueue(); |
130 | 129 |
131 // Walks the queue, checking each event for |ShouldForwardToRenderer()|. | 130 // Walks the queue, checking each event with |FilterBeforeForwarding()|. |
132 // If true, forwards the touch event and stops processing further events. | 131 // If allowed, forwards the touch event and stops processing further events. |
133 // If false, acks the event with |INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS|. | 132 // Otherwise, acks the event with |INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS|. |
134 void TryForwardNextEventToRenderer(); | 133 void TryForwardNextEventToRenderer(); |
135 | 134 |
136 // Pops the touch-event from the top of the queue and sends it to the | 135 // Forwards the event at the head of the queue to the renderer. |
137 // TouchEventQueueClient. This reduces the size of the queue by one. | 136 void ForwardNextEventToRenderer(); |
| 137 |
| 138 // Pops the touch-event from the head of the queue and acks it to the client. |
| 139 void PopTouchEventToClient(InputEventAckState ack_result); |
| 140 |
| 141 // Pops the touch-event from the top of the queue and acks it to the client, |
| 142 // updating the event with |renderer_latency_info|. |
138 void PopTouchEventToClient(InputEventAckState ack_result, | 143 void PopTouchEventToClient(InputEventAckState ack_result, |
139 const ui::LatencyInfo& renderer_latency_info); | 144 const ui::LatencyInfo& renderer_latency_info); |
140 | 145 |
| 146 // Ack all coalesced events in |acked_event| to the client with |ack_result|. |
| 147 void AckTouchEventToClient(InputEventAckState ack_result, |
| 148 scoped_ptr<CoalescedWebTouchEvent> acked_event); |
| 149 |
| 150 // Safely pop the head of the queue. |
| 151 scoped_ptr<CoalescedWebTouchEvent> PopTouchEvent(); |
| 152 |
| 153 // Dispatch |touch| to the client. |
| 154 void SendTouchEventImmediately(const TouchEventWithLatencyInfo& touch); |
| 155 |
141 enum PreFilterResult { | 156 enum PreFilterResult { |
142 ACK_WITH_NO_CONSUMER_EXISTS, | 157 ACK_WITH_NO_CONSUMER_EXISTS, |
143 ACK_WITH_NOT_CONSUMED, | 158 ACK_WITH_NOT_CONSUMED, |
144 FORWARD_TO_RENDERER, | 159 FORWARD_TO_RENDERER, |
145 }; | 160 }; |
146 // Filter touches prior to forwarding to the renderer, e.g., if the renderer | 161 // Filter touches prior to forwarding to the renderer, e.g., if the renderer |
147 // has no touch handler. | 162 // has no touch handler. |
148 PreFilterResult FilterBeforeForwarding(const blink::WebTouchEvent& event); | 163 PreFilterResult FilterBeforeForwarding(const blink::WebTouchEvent& event); |
149 void ForwardToRenderer(const TouchEventWithLatencyInfo& event); | 164 void ForwardToRenderer(const TouchEventWithLatencyInfo& event); |
150 void UpdateTouchAckStates(const blink::WebTouchEvent& event, | 165 void UpdateTouchAckStates(const blink::WebTouchEvent& event, |
151 InputEventAckState ack_result); | 166 InputEventAckState ack_result); |
152 | 167 |
153 | 168 |
154 // Handles touch event forwarding and ack'ed event dispatch. | 169 // Handles touch event forwarding and ack'ed event dispatch. |
155 TouchEventQueueClient* client_; | 170 TouchEventQueueClient* client_; |
156 | 171 |
157 typedef std::deque<CoalescedWebTouchEvent*> TouchQueue; | 172 typedef std::deque<CoalescedWebTouchEvent*> TouchQueue; |
158 TouchQueue touch_queue_; | 173 TouchQueue touch_queue_; |
159 | 174 |
160 // Maintain the ACK status for each touch point. | 175 // Maintain the ACK status for each touch point. |
161 typedef std::map<int, InputEventAckState> TouchPointAckStates; | 176 typedef std::map<int, InputEventAckState> TouchPointAckStates; |
162 TouchPointAckStates touch_ack_states_; | 177 TouchPointAckStates touch_ack_states_; |
163 | 178 |
| 179 // Position of the first touch in the most recent sequence forwarded to the |
| 180 // client. |
| 181 gfx::PointF touch_sequence_start_position_; |
| 182 |
164 // Used to defer touch forwarding when ack dispatch triggers |QueueEvent()|. | 183 // Used to defer touch forwarding when ack dispatch triggers |QueueEvent()|. |
165 // If not NULL, |dispatching_touch_ack_| is the touch event of which the ack | 184 // If not NULL, |dispatching_touch_ack_| is the touch event of which the ack |
166 // is being dispatched. | 185 // is being dispatched. |
167 CoalescedWebTouchEvent* dispatching_touch_ack_; | 186 const CoalescedWebTouchEvent* dispatching_touch_ack_; |
168 | 187 |
169 // Used to prevent touch timeout scheduling if we receive a synchronous | 188 // Used to prevent touch timeout scheduling if we receive a synchronous |
170 // ack after forwarding a touch event to the client. | 189 // ack after forwarding a touch event to the client. |
171 bool dispatching_touch_; | 190 bool dispatching_touch_; |
172 | 191 |
173 enum TouchFilteringState { | 192 enum TouchFilteringState { |
174 FORWARD_ALL_TOUCHES, // Don't filter at all - the default. | 193 FORWARD_ALL_TOUCHES, // Don't filter at all - the default. |
175 FORWARD_TOUCHES_UNTIL_TIMEOUT, // Don't filter unless we get an ACK timeout. | 194 FORWARD_TOUCHES_UNTIL_TIMEOUT, // Don't filter unless we get an ACK timeout. |
176 DROP_TOUCHES_IN_SEQUENCE, // Filter all events until a new touch | 195 DROP_TOUCHES_IN_SEQUENCE, // Filter all events until a new touch |
177 // sequence is received. | 196 // sequence is received. |
178 DROP_ALL_TOUCHES, // Filter all events, e.g., no touch handler. | 197 DROP_ALL_TOUCHES, // Filter all events, e.g., no touch handler. |
179 TOUCH_FILTERING_STATE_DEFAULT = FORWARD_ALL_TOUCHES, | 198 TOUCH_FILTERING_STATE_DEFAULT = FORWARD_ALL_TOUCHES, |
180 }; | 199 }; |
181 TouchFilteringState touch_filtering_state_; | 200 TouchFilteringState touch_filtering_state_; |
182 | 201 |
183 // Optional handler for timed-out touch event acks, disabled by default. | 202 // Optional handler for timed-out touch event acks, disabled by default. |
184 bool ack_timeout_enabled_; | 203 bool ack_timeout_enabled_; |
185 scoped_ptr<TouchTimeoutHandler> timeout_handler_; | 204 scoped_ptr<TouchTimeoutHandler> timeout_handler_; |
186 | 205 |
187 // Suppression of TouchMove's within a slop region when a sequence has not yet | 206 // Suppression of TouchMove's within a slop region when a sequence has not yet |
188 // been preventDefaulted. | 207 // been preventDefaulted. |
189 scoped_ptr<TouchMoveSlopSuppressor> touchmove_slop_suppressor_; | 208 scoped_ptr<TouchMoveSlopSuppressor> touchmove_slop_suppressor_; |
190 | 209 |
191 // Whether touchmove events should be dropped due to the | 210 // Whether touch events should remain buffered and dispatched asynchronously |
192 // TOUCH_SCROLLING_MODE_ABSORB_TOUCHMOVE mode. Note that we can't use | 211 // while a scroll sequence is active. In this mode, touchmove's are throttled |
193 // touch_filtering_state_ for this (without adding a few new states and | 212 // and ack'ed immediately, but remain buffered in |pending_async_touch_move_| |
194 // complicating the code significantly) because it can occur with and without | 213 // until a sufficient time period has elapsed since the last sent touch event. |
195 // timeout, and shouldn't cause touchend to be dropped. | 214 // For details see the design doc at http://goo.gl/lVyJAa. |
196 bool absorbing_touch_moves_; | 215 bool send_touch_events_async_; |
| 216 scoped_ptr<TouchEventWithLatencyInfo> pending_async_touch_move_; |
| 217 double last_sent_touch_timestamp_sec_; |
| 218 bool needs_async_touch_move_for_outer_slop_region_; |
197 | 219 |
198 // How touch events are handled during scrolling. For now this is a global | 220 // How touch events are handled during scrolling. For now this is a global |
199 // setting for experimentation, but we may evolve it into an app-controlled | 221 // setting for experimentation, but we may evolve it into an app-controlled |
200 // mode. | 222 // mode. |
201 const TouchScrollingMode touch_scrolling_mode_; | 223 const TouchScrollingMode touch_scrolling_mode_; |
202 | 224 |
203 DISALLOW_COPY_AND_ASSIGN(TouchEventQueue); | 225 DISALLOW_COPY_AND_ASSIGN(TouchEventQueue); |
204 }; | 226 }; |
205 | 227 |
206 } // namespace content | 228 } // namespace content |
207 | 229 |
208 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_ | 230 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_ |
OLD | NEW |