| 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 |