| 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 #include "content/browser/renderer_host/input/touch_event_queue.h" | 5 #include "content/browser/renderer_host/input/touch_event_queue.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 | 10 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 touch_queue_.push_back(new CoalescedWebTouchEvent(event)); | 113 touch_queue_.push_back(new CoalescedWebTouchEvent(event)); |
| 114 } | 114 } |
| 115 | 115 |
| 116 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, | 116 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, |
| 117 const ui::LatencyInfo& latency_info) { | 117 const ui::LatencyInfo& latency_info) { |
| 118 DCHECK(!dispatching_touch_ack_); | 118 DCHECK(!dispatching_touch_ack_); |
| 119 if (touch_queue_.empty()) | 119 if (touch_queue_.empty()) |
| 120 return; | 120 return; |
| 121 | 121 |
| 122 // Update the ACK status for each touch point in the ACKed event. | 122 // Update the ACK status for each touch point in the ACKed event. |
| 123 const WebKit::WebTouchEvent& event = | 123 const blink::WebTouchEvent& event = |
| 124 touch_queue_.front()->coalesced_event().event; | 124 touch_queue_.front()->coalesced_event().event; |
| 125 if (event.type == WebKit::WebInputEvent::TouchEnd || | 125 if (event.type == blink::WebInputEvent::TouchEnd || |
| 126 event.type == WebKit::WebInputEvent::TouchCancel) { | 126 event.type == blink::WebInputEvent::TouchCancel) { |
| 127 // The points have been released. Erase the ACK states. | 127 // The points have been released. Erase the ACK states. |
| 128 for (unsigned i = 0; i < event.touchesLength; ++i) { | 128 for (unsigned i = 0; i < event.touchesLength; ++i) { |
| 129 const WebKit::WebTouchPoint& point = event.touches[i]; | 129 const blink::WebTouchPoint& point = event.touches[i]; |
| 130 if (point.state == WebKit::WebTouchPoint::StateReleased || | 130 if (point.state == blink::WebTouchPoint::StateReleased || |
| 131 point.state == WebKit::WebTouchPoint::StateCancelled) | 131 point.state == blink::WebTouchPoint::StateCancelled) |
| 132 touch_ack_states_.erase(point.id); | 132 touch_ack_states_.erase(point.id); |
| 133 } | 133 } |
| 134 } else if (event.type == WebKit::WebInputEvent::TouchStart) { | 134 } else if (event.type == blink::WebInputEvent::TouchStart) { |
| 135 for (unsigned i = 0; i < event.touchesLength; ++i) { | 135 for (unsigned i = 0; i < event.touchesLength; ++i) { |
| 136 const WebKit::WebTouchPoint& point = event.touches[i]; | 136 const blink::WebTouchPoint& point = event.touches[i]; |
| 137 if (point.state == WebKit::WebTouchPoint::StatePressed) | 137 if (point.state == blink::WebTouchPoint::StatePressed) |
| 138 touch_ack_states_[point.id] = ack_result; | 138 touch_ack_states_[point.id] = ack_result; |
| 139 } | 139 } |
| 140 } | 140 } |
| 141 | 141 |
| 142 PopTouchEventToClient(ack_result, latency_info); | 142 PopTouchEventToClient(ack_result, latency_info); |
| 143 TryForwardNextEventToRenderer(); | 143 TryForwardNextEventToRenderer(); |
| 144 } | 144 } |
| 145 | 145 |
| 146 void TouchEventQueue::TryForwardNextEventToRenderer() { | 146 void TouchEventQueue::TryForwardNextEventToRenderer() { |
| 147 DCHECK(!dispatching_touch_ack_); | 147 DCHECK(!dispatching_touch_ack_); |
| 148 // If there are queued touch events, then try to forward them to the renderer | 148 // If there are queued touch events, then try to forward them to the renderer |
| 149 // immediately, or ACK the events back to the client if appropriate. | 149 // immediately, or ACK the events back to the client if appropriate. |
| 150 while (!touch_queue_.empty()) { | 150 while (!touch_queue_.empty()) { |
| 151 const TouchEventWithLatencyInfo& touch = | 151 const TouchEventWithLatencyInfo& touch = |
| 152 touch_queue_.front()->coalesced_event(); | 152 touch_queue_.front()->coalesced_event(); |
| 153 if (ShouldForwardToRenderer(touch.event)) { | 153 if (ShouldForwardToRenderer(touch.event)) { |
| 154 client_->SendTouchEventImmediately(touch); | 154 client_->SendTouchEventImmediately(touch); |
| 155 break; | 155 break; |
| 156 } | 156 } |
| 157 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, | 157 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, |
| 158 ui::LatencyInfo()); | 158 ui::LatencyInfo()); |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 | 161 |
| 162 void TouchEventQueue::OnGestureScrollEvent( | 162 void TouchEventQueue::OnGestureScrollEvent( |
| 163 const GestureEventWithLatencyInfo& gesture_event) { | 163 const GestureEventWithLatencyInfo& gesture_event) { |
| 164 WebKit::WebInputEvent::Type type = gesture_event.event.type; | 164 blink::WebInputEvent::Type type = gesture_event.event.type; |
| 165 if (type == WebKit::WebInputEvent::GestureScrollBegin) { | 165 if (type == blink::WebInputEvent::GestureScrollBegin) { |
| 166 // We assume the scroll event are generated synchronously from | 166 // We assume the scroll event are generated synchronously from |
| 167 // dispatching a touch event ack, so that we can fake a cancel | 167 // dispatching a touch event ack, so that we can fake a cancel |
| 168 // event that has the correct touch ids as the touch event that | 168 // event that has the correct touch ids as the touch event that |
| 169 // is being acked. If not, we don't do the touch-cancel optimization. | 169 // is being acked. If not, we don't do the touch-cancel optimization. |
| 170 if (no_touch_to_renderer_ || !dispatching_touch_ack_) | 170 if (no_touch_to_renderer_ || !dispatching_touch_ack_) |
| 171 return; | 171 return; |
| 172 no_touch_to_renderer_ = true; | 172 no_touch_to_renderer_ = true; |
| 173 // Fake a TouchCancel to cancel the touch points of the touch event | 173 // Fake a TouchCancel to cancel the touch points of the touch event |
| 174 // that is currently being acked. | 174 // that is currently being acked. |
| 175 TouchEventWithLatencyInfo cancel_event = | 175 TouchEventWithLatencyInfo cancel_event = |
| 176 dispatching_touch_ack_->coalesced_event(); | 176 dispatching_touch_ack_->coalesced_event(); |
| 177 cancel_event.event.type = WebKit::WebInputEvent::TouchCancel; | 177 cancel_event.event.type = blink::WebInputEvent::TouchCancel; |
| 178 for (size_t i = 0; i < cancel_event.event.touchesLength; i++) | 178 for (size_t i = 0; i < cancel_event.event.touchesLength; i++) |
| 179 cancel_event.event.touches[i].state = | 179 cancel_event.event.touches[i].state = |
| 180 WebKit::WebTouchPoint::StateCancelled; | 180 blink::WebTouchPoint::StateCancelled; |
| 181 CoalescedWebTouchEvent* coalesced_cancel_event = | 181 CoalescedWebTouchEvent* coalesced_cancel_event = |
| 182 new CoalescedWebTouchEvent(cancel_event); | 182 new CoalescedWebTouchEvent(cancel_event); |
| 183 // Ignore the ack of the touch cancel so when it is acked, it won't get | 183 // Ignore the ack of the touch cancel so when it is acked, it won't get |
| 184 // sent to gesture recognizer. | 184 // sent to gesture recognizer. |
| 185 coalesced_cancel_event->set_ignore_ack(true); | 185 coalesced_cancel_event->set_ignore_ack(true); |
| 186 // |dispatching_touch_ack_| is non-null when we reach here, meaning we | 186 // |dispatching_touch_ack_| is non-null when we reach here, meaning we |
| 187 // are in the scope of PopTouchEventToClient() and that no touch event | 187 // are in the scope of PopTouchEventToClient() and that no touch event |
| 188 // in the queue is waiting for ack from renderer. So we can just insert | 188 // in the queue is waiting for ack from renderer. So we can just insert |
| 189 // the touch cancel at the beginning of the queue. | 189 // the touch cancel at the beginning of the queue. |
| 190 touch_queue_.push_front(coalesced_cancel_event); | 190 touch_queue_.push_front(coalesced_cancel_event); |
| 191 } else if (type == WebKit::WebInputEvent::GestureScrollEnd || | 191 } else if (type == blink::WebInputEvent::GestureScrollEnd || |
| 192 type == WebKit::WebInputEvent::GestureFlingStart) { | 192 type == blink::WebInputEvent::GestureFlingStart) { |
| 193 no_touch_to_renderer_ = false; | 193 no_touch_to_renderer_ = false; |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 | 196 |
| 197 void TouchEventQueue::FlushQueue() { | 197 void TouchEventQueue::FlushQueue() { |
| 198 DCHECK(!dispatching_touch_ack_); | 198 DCHECK(!dispatching_touch_ack_); |
| 199 while (!touch_queue_.empty()) | 199 while (!touch_queue_.empty()) |
| 200 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, | 200 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, |
| 201 ui::LatencyInfo()); | 201 ui::LatencyInfo()); |
| 202 } | 202 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 227 | 227 |
| 228 for (WebTouchEventWithLatencyList::iterator iter = acked_event->begin(), | 228 for (WebTouchEventWithLatencyList::iterator iter = acked_event->begin(), |
| 229 end = acked_event->end(); | 229 end = acked_event->end(); |
| 230 iter != end; ++iter) { | 230 iter != end; ++iter) { |
| 231 iter->latency.AddNewLatencyFrom(renderer_latency_info); | 231 iter->latency.AddNewLatencyFrom(renderer_latency_info); |
| 232 client_->OnTouchEventAck((*iter), ack_result); | 232 client_->OnTouchEventAck((*iter), ack_result); |
| 233 } | 233 } |
| 234 } | 234 } |
| 235 | 235 |
| 236 bool TouchEventQueue::ShouldForwardToRenderer( | 236 bool TouchEventQueue::ShouldForwardToRenderer( |
| 237 const WebKit::WebTouchEvent& event) const { | 237 const blink::WebTouchEvent& event) const { |
| 238 if (no_touch_to_renderer_ && | 238 if (no_touch_to_renderer_ && |
| 239 event.type != WebKit::WebInputEvent::TouchCancel) | 239 event.type != blink::WebInputEvent::TouchCancel) |
| 240 return false; | 240 return false; |
| 241 | 241 |
| 242 // Touch press events should always be forwarded to the renderer. | 242 // Touch press events should always be forwarded to the renderer. |
| 243 if (event.type == WebKit::WebInputEvent::TouchStart) | 243 if (event.type == blink::WebInputEvent::TouchStart) |
| 244 return true; | 244 return true; |
| 245 | 245 |
| 246 for (unsigned int i = 0; i < event.touchesLength; ++i) { | 246 for (unsigned int i = 0; i < event.touchesLength; ++i) { |
| 247 const WebKit::WebTouchPoint& point = event.touches[i]; | 247 const blink::WebTouchPoint& point = event.touches[i]; |
| 248 // If a point has been stationary, then don't take it into account. | 248 // If a point has been stationary, then don't take it into account. |
| 249 if (point.state == WebKit::WebTouchPoint::StateStationary) | 249 if (point.state == blink::WebTouchPoint::StateStationary) |
| 250 continue; | 250 continue; |
| 251 | 251 |
| 252 if (touch_ack_states_.count(point.id) > 0) { | 252 if (touch_ack_states_.count(point.id) > 0) { |
| 253 if (touch_ack_states_.find(point.id)->second != | 253 if (touch_ack_states_.find(point.id)->second != |
| 254 INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) | 254 INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) |
| 255 return true; | 255 return true; |
| 256 } else { | 256 } else { |
| 257 // If the ACK status of a point is unknown, then the event should be | 257 // If the ACK status of a point is unknown, then the event should be |
| 258 // forwarded to the renderer. | 258 // forwarded to the renderer. |
| 259 return true; | 259 return true; |
| 260 } | 260 } |
| 261 } | 261 } |
| 262 | 262 |
| 263 return false; | 263 return false; |
| 264 } | 264 } |
| 265 | 265 |
| 266 } // namespace content | 266 } // namespace content |
| OLD | NEW |