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