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 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
13 #include "content/browser/renderer_host/event_with_latency_info.h" | 13 #include "content/browser/renderer_host/event_with_latency_info.h" |
14 #include "content/common/content_export.h" | 14 #include "content/common/content_export.h" |
15 #include "content/common/input/input_event_ack_state.h" | 15 #include "content/common/input/input_event_ack_state.h" |
16 #include "third_party/WebKit/public/web/WebInputEvent.h" | 16 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 17 #include "ui/events/gesture_detection/bitset_32.h" |
17 #include "ui/gfx/geometry/point_f.h" | 18 #include "ui/gfx/geometry/point_f.h" |
18 | 19 |
19 namespace content { | 20 namespace content { |
20 | 21 |
21 class CoalescedWebTouchEvent; | 22 class CoalescedWebTouchEvent; |
22 | 23 |
23 // Interface with which TouchEventQueue can forward touch events, and dispatch | 24 // Interface with which TouchEventQueue can forward touch events, and dispatch |
24 // touch event responses. | 25 // touch event responses. |
25 class CONTENT_EXPORT TouchEventQueueClient { | 26 class CONTENT_EXPORT TouchEventQueueClient { |
26 public: | 27 public: |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 | 108 |
108 // Returns whether the currently pending touch event (waiting ACK) is for | 109 // Returns whether the currently pending touch event (waiting ACK) is for |
109 // a touch start event. | 110 // a touch start event. |
110 bool IsPendingAckTouchStart() const; | 111 bool IsPendingAckTouchStart() const; |
111 | 112 |
112 // Sets whether a delayed touch ack will cancel and flush the current | 113 // Sets whether a delayed touch ack will cancel and flush the current |
113 // touch sequence. Note that, if the timeout was previously disabled, enabling | 114 // touch sequence. Note that, if the timeout was previously disabled, enabling |
114 // it will take effect only for the following touch sequence. | 115 // it will take effect only for the following touch sequence. |
115 void SetAckTimeoutEnabled(bool enabled); | 116 void SetAckTimeoutEnabled(bool enabled); |
116 | 117 |
| 118 bool IsAckTimeoutEnabled() const; |
| 119 |
| 120 bool IsForwardingTouches(); |
| 121 |
117 bool empty() const WARN_UNUSED_RESULT { | 122 bool empty() const WARN_UNUSED_RESULT { |
118 return touch_queue_.empty(); | 123 return touch_queue_.empty(); |
119 } | 124 } |
120 | 125 |
121 size_t size() const { | 126 size_t size() const { |
122 return touch_queue_.size(); | 127 return touch_queue_.size(); |
123 } | 128 } |
124 | 129 |
125 bool ack_timeout_enabled() const { | 130 bool has_handlers() const { return has_handlers_; } |
126 return ack_timeout_enabled_; | |
127 } | |
128 | |
129 bool has_handlers() const { | |
130 return touch_filtering_state_ != DROP_ALL_TOUCHES; | |
131 } | |
132 | 131 |
133 private: | 132 private: |
134 class TouchTimeoutHandler; | 133 class TouchTimeoutHandler; |
135 class TouchMoveSlopSuppressor; | 134 class TouchMoveSlopSuppressor; |
136 friend class TouchTimeoutHandler; | 135 friend class TouchTimeoutHandler; |
137 friend class TouchEventQueueTest; | 136 friend class TouchEventQueueTest; |
138 | 137 |
139 bool HasPendingAsyncTouchMoveForTesting() const; | 138 bool HasPendingAsyncTouchMoveForTesting() const; |
140 bool IsTimeoutRunningForTesting() const; | 139 bool IsTimeoutRunningForTesting() const; |
141 const TouchEventWithLatencyInfo& GetLatestEventForTesting() const; | 140 const TouchEventWithLatencyInfo& GetLatestEventForTesting() const; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 | 173 |
175 enum PreFilterResult { | 174 enum PreFilterResult { |
176 ACK_WITH_NO_CONSUMER_EXISTS, | 175 ACK_WITH_NO_CONSUMER_EXISTS, |
177 ACK_WITH_NOT_CONSUMED, | 176 ACK_WITH_NOT_CONSUMED, |
178 FORWARD_TO_RENDERER, | 177 FORWARD_TO_RENDERER, |
179 }; | 178 }; |
180 // Filter touches prior to forwarding to the renderer, e.g., if the renderer | 179 // Filter touches prior to forwarding to the renderer, e.g., if the renderer |
181 // has no touch handler. | 180 // has no touch handler. |
182 PreFilterResult FilterBeforeForwarding(const blink::WebTouchEvent& event); | 181 PreFilterResult FilterBeforeForwarding(const blink::WebTouchEvent& event); |
183 void ForwardToRenderer(const TouchEventWithLatencyInfo& event); | 182 void ForwardToRenderer(const TouchEventWithLatencyInfo& event); |
184 void UpdateTouchAckStates(const blink::WebTouchEvent& event, | 183 void UpdateTouchConsumerStates(const blink::WebTouchEvent& event, |
185 InputEventAckState ack_result); | 184 InputEventAckState ack_result); |
186 bool AllTouchAckStatesHaveState(InputEventAckState ack_state) const; | |
187 | |
188 | 185 |
189 // Handles touch event forwarding and ack'ed event dispatch. | 186 // Handles touch event forwarding and ack'ed event dispatch. |
190 TouchEventQueueClient* client_; | 187 TouchEventQueueClient* client_; |
191 | 188 |
192 typedef std::deque<CoalescedWebTouchEvent*> TouchQueue; | 189 typedef std::deque<CoalescedWebTouchEvent*> TouchQueue; |
193 TouchQueue touch_queue_; | 190 TouchQueue touch_queue_; |
194 | 191 |
195 // Maintain the ACK status for each touch point. | 192 // Maps whether each active pointer has a consumer (i.e., a touch point has a |
196 typedef std::map<int, InputEventAckState> TouchPointAckStates; | 193 // valid consumer iff |touch_consumer_states[pointer.id]| is true.). |
197 TouchPointAckStates touch_ack_states_; | 194 // TODO(jdduke): Consider simply tracking whether *any* touchstart had a |
| 195 // consumer, crbug.com/416497. |
| 196 ui::BitSet32 touch_consumer_states_; |
198 | 197 |
199 // Position of the first touch in the most recent sequence forwarded to the | 198 // Position of the first touch in the most recent sequence forwarded to the |
200 // client. | 199 // client. |
201 gfx::PointF touch_sequence_start_position_; | 200 gfx::PointF touch_sequence_start_position_; |
202 | 201 |
203 // Used to defer touch forwarding when ack dispatch triggers |QueueEvent()|. | 202 // Used to defer touch forwarding when ack dispatch triggers |QueueEvent()|. |
204 // If not NULL, |dispatching_touch_ack_| is the touch event of which the ack | 203 // If not NULL, |dispatching_touch_ack_| is the touch event of which the ack |
205 // is being dispatched. | 204 // is being dispatched. |
206 const CoalescedWebTouchEvent* dispatching_touch_ack_; | 205 const CoalescedWebTouchEvent* dispatching_touch_ack_; |
207 | 206 |
208 // Used to prevent touch timeout scheduling if we receive a synchronous | 207 // Used to prevent touch timeout scheduling if we receive a synchronous |
209 // ack after forwarding a touch event to the client. | 208 // ack after forwarding a touch event to the client. |
210 bool dispatching_touch_; | 209 bool dispatching_touch_; |
211 | 210 |
212 enum TouchFilteringState { | 211 // Whether the renderer has at least one touch handler. |
213 FORWARD_ALL_TOUCHES, // Don't filter at all - the default. | 212 bool has_handlers_; |
214 FORWARD_TOUCHES_UNTIL_TIMEOUT, // Don't filter unless we get an ACK timeout. | 213 |
215 DROP_TOUCHES_IN_SEQUENCE, // Filter all events until a new touch | 214 // Whether to allow any remaining touches for the current sequence. Note that |
216 // sequence is received. | 215 // this is a stricter condition than an empty |touch_consumer_states_|, as it |
217 DROP_ALL_TOUCHES, // Filter all events, e.g., no touch handler. | 216 // also prevents forwarding of touchstart events for new pointers in the |
218 TOUCH_FILTERING_STATE_DEFAULT = FORWARD_ALL_TOUCHES, | 217 // current sequence. This is only used when the event is synthetically |
219 }; | 218 // cancelled after a touch timeout, or after a scroll event when the |
220 TouchFilteringState touch_filtering_state_; | 219 // mode is TOUCH_SCROLLING_MODE_TOUCHCANCEL. |
| 220 bool drop_remaining_touches_in_sequence_; |
221 | 221 |
222 // Optional handler for timed-out touch event acks. | 222 // Optional handler for timed-out touch event acks. |
223 bool ack_timeout_enabled_; | |
224 scoped_ptr<TouchTimeoutHandler> timeout_handler_; | 223 scoped_ptr<TouchTimeoutHandler> timeout_handler_; |
225 | 224 |
226 // Suppression of TouchMove's within a slop region when a sequence has not yet | 225 // Suppression of TouchMove's within a slop region when a sequence has not yet |
227 // been preventDefaulted. | 226 // been preventDefaulted. |
228 scoped_ptr<TouchMoveSlopSuppressor> touchmove_slop_suppressor_; | 227 scoped_ptr<TouchMoveSlopSuppressor> touchmove_slop_suppressor_; |
229 | 228 |
230 // Whether touch events should remain buffered and dispatched asynchronously | 229 // Whether touch events should remain buffered and dispatched asynchronously |
231 // while a scroll sequence is active. In this mode, touchmove's are throttled | 230 // while a scroll sequence is active. In this mode, touchmove's are throttled |
232 // and ack'ed immediately, but remain buffered in |pending_async_touchmove_| | 231 // and ack'ed immediately, but remain buffered in |pending_async_touchmove_| |
233 // until a sufficient time period has elapsed since the last sent touch event. | 232 // until a sufficient time period has elapsed since the last sent touch event. |
234 // For details see the design doc at http://goo.gl/lVyJAa. | 233 // For details see the design doc at http://goo.gl/lVyJAa. |
235 bool send_touch_events_async_; | 234 bool send_touch_events_async_; |
236 bool needs_async_touchmove_for_outer_slop_region_; | 235 bool needs_async_touchmove_for_outer_slop_region_; |
237 scoped_ptr<TouchEventWithLatencyInfo> pending_async_touchmove_; | 236 scoped_ptr<TouchEventWithLatencyInfo> pending_async_touchmove_; |
238 double last_sent_touch_timestamp_sec_; | 237 double last_sent_touch_timestamp_sec_; |
239 | 238 |
240 // How touch events are handled during scrolling. For now this is a global | 239 // How touch events are handled during scrolling. For now this is a global |
241 // setting for experimentation, but we may evolve it into an app-controlled | 240 // setting for experimentation, but we may evolve it into an app-controlled |
242 // mode. | 241 // mode. |
243 const TouchScrollingMode touch_scrolling_mode_; | 242 const TouchScrollingMode touch_scrolling_mode_; |
244 | 243 |
245 DISALLOW_COPY_AND_ASSIGN(TouchEventQueue); | 244 DISALLOW_COPY_AND_ASSIGN(TouchEventQueue); |
246 }; | 245 }; |
247 | 246 |
248 } // namespace content | 247 } // namespace content |
249 | 248 |
250 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_ | 249 #endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_EVENT_QUEUE_H_ |
OLD | NEW |