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