| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/gesture_event_queue.h" | 5 #include "content/browser/renderer_host/input/gesture_event_queue.h" |
| 6 | 6 |
| 7 #include "base/trace_event/trace_event.h" | 7 #include "base/trace_event/trace_event.h" |
| 8 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
r.h" | 8 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
r.h" |
| 9 #include "content/browser/renderer_host/input/touchscreen_tap_suppression_contro
ller.h" | 9 #include "content/browser/renderer_host/input/touchscreen_tap_suppression_contro
ller.h" |
| 10 #include "ui/events/blink/web_input_event_traits.h" | 10 #include "ui/events/blink/web_input_event_traits.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 QueueAndForwardIfNecessary(gesture_event); | 50 QueueAndForwardIfNecessary(gesture_event); |
| 51 } | 51 } |
| 52 | 52 |
| 53 bool GestureEventQueue::ShouldDiscardFlingCancelEvent( | 53 bool GestureEventQueue::ShouldDiscardFlingCancelEvent( |
| 54 const GestureEventWithLatencyInfo& gesture_event) const { | 54 const GestureEventWithLatencyInfo& gesture_event) const { |
| 55 if (coalesced_gesture_events_.empty() && fling_in_progress_) | 55 if (coalesced_gesture_events_.empty() && fling_in_progress_) |
| 56 return false; | 56 return false; |
| 57 GestureQueue::const_reverse_iterator it = | 57 GestureQueue::const_reverse_iterator it = |
| 58 coalesced_gesture_events_.rbegin(); | 58 coalesced_gesture_events_.rbegin(); |
| 59 while (it != coalesced_gesture_events_.rend()) { | 59 while (it != coalesced_gesture_events_.rend()) { |
| 60 if (it->event.type == WebInputEvent::GestureFlingStart) | 60 if (it->event.type() == WebInputEvent::GestureFlingStart) |
| 61 return false; | 61 return false; |
| 62 if (it->event.type == WebInputEvent::GestureFlingCancel) | 62 if (it->event.type() == WebInputEvent::GestureFlingCancel) |
| 63 return true; | 63 return true; |
| 64 it++; | 64 it++; |
| 65 } | 65 } |
| 66 return true; | 66 return true; |
| 67 } | 67 } |
| 68 | 68 |
| 69 bool GestureEventQueue::ShouldForwardForBounceReduction( | 69 bool GestureEventQueue::ShouldForwardForBounceReduction( |
| 70 const GestureEventWithLatencyInfo& gesture_event) { | 70 const GestureEventWithLatencyInfo& gesture_event) { |
| 71 if (debounce_interval_ <= base::TimeDelta()) | 71 if (debounce_interval_ <= base::TimeDelta()) |
| 72 return true; | 72 return true; |
| 73 switch (gesture_event.event.type) { | 73 switch (gesture_event.event.type()) { |
| 74 case WebInputEvent::GestureScrollUpdate: | 74 case WebInputEvent::GestureScrollUpdate: |
| 75 if (!scrolling_in_progress_) { | 75 if (!scrolling_in_progress_) { |
| 76 debounce_deferring_timer_.Start( | 76 debounce_deferring_timer_.Start( |
| 77 FROM_HERE, | 77 FROM_HERE, |
| 78 debounce_interval_, | 78 debounce_interval_, |
| 79 this, | 79 this, |
| 80 &GestureEventQueue::SendScrollEndingEventsNow); | 80 &GestureEventQueue::SendScrollEndingEventsNow); |
| 81 } else { | 81 } else { |
| 82 // Extend the bounce interval. | 82 // Extend the bounce interval. |
| 83 debounce_deferring_timer_.Reset(); | 83 debounce_deferring_timer_.Reset(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 95 if (scrolling_in_progress_) { | 95 if (scrolling_in_progress_) { |
| 96 debouncing_deferral_queue_.push_back(gesture_event); | 96 debouncing_deferral_queue_.push_back(gesture_event); |
| 97 return false; | 97 return false; |
| 98 } | 98 } |
| 99 return true; | 99 return true; |
| 100 } | 100 } |
| 101 } | 101 } |
| 102 | 102 |
| 103 bool GestureEventQueue::ShouldForwardForGFCFiltering( | 103 bool GestureEventQueue::ShouldForwardForGFCFiltering( |
| 104 const GestureEventWithLatencyInfo& gesture_event) const { | 104 const GestureEventWithLatencyInfo& gesture_event) const { |
| 105 return gesture_event.event.type != WebInputEvent::GestureFlingCancel || | 105 return gesture_event.event.type() != WebInputEvent::GestureFlingCancel || |
| 106 !ShouldDiscardFlingCancelEvent(gesture_event); | 106 !ShouldDiscardFlingCancelEvent(gesture_event); |
| 107 } | 107 } |
| 108 | 108 |
| 109 bool GestureEventQueue::ShouldForwardForTapSuppression( | 109 bool GestureEventQueue::ShouldForwardForTapSuppression( |
| 110 const GestureEventWithLatencyInfo& gesture_event) { | 110 const GestureEventWithLatencyInfo& gesture_event) { |
| 111 switch (gesture_event.event.type) { | 111 switch (gesture_event.event.type()) { |
| 112 case WebInputEvent::GestureFlingCancel: | 112 case WebInputEvent::GestureFlingCancel: |
| 113 if (gesture_event.event.sourceDevice == | 113 if (gesture_event.event.sourceDevice == |
| 114 blink::WebGestureDeviceTouchscreen) | 114 blink::WebGestureDeviceTouchscreen) |
| 115 touchscreen_tap_suppression_controller_.GestureFlingCancel(); | 115 touchscreen_tap_suppression_controller_.GestureFlingCancel(); |
| 116 else | 116 else |
| 117 touchpad_tap_suppression_controller_.GestureFlingCancel(); | 117 touchpad_tap_suppression_controller_.GestureFlingCancel(); |
| 118 return true; | 118 return true; |
| 119 case WebInputEvent::GestureTapDown: | 119 case WebInputEvent::GestureTapDown: |
| 120 case WebInputEvent::GestureShowPress: | 120 case WebInputEvent::GestureShowPress: |
| 121 case WebInputEvent::GestureTapUnconfirmed: | 121 case WebInputEvent::GestureTapUnconfirmed: |
| 122 case WebInputEvent::GestureTapCancel: | 122 case WebInputEvent::GestureTapCancel: |
| 123 case WebInputEvent::GestureTap: | 123 case WebInputEvent::GestureTap: |
| 124 case WebInputEvent::GestureDoubleTap: | 124 case WebInputEvent::GestureDoubleTap: |
| 125 case WebInputEvent::GestureLongPress: | 125 case WebInputEvent::GestureLongPress: |
| 126 case WebInputEvent::GestureLongTap: | 126 case WebInputEvent::GestureLongTap: |
| 127 case WebInputEvent::GestureTwoFingerTap: | 127 case WebInputEvent::GestureTwoFingerTap: |
| 128 if (gesture_event.event.sourceDevice == | 128 if (gesture_event.event.sourceDevice == |
| 129 blink::WebGestureDeviceTouchscreen) { | 129 blink::WebGestureDeviceTouchscreen) { |
| 130 return !touchscreen_tap_suppression_controller_.FilterTapEvent( | 130 return !touchscreen_tap_suppression_controller_.FilterTapEvent( |
| 131 gesture_event); | 131 gesture_event); |
| 132 } | 132 } |
| 133 return true; | 133 return true; |
| 134 default: | 134 default: |
| 135 return true; | 135 return true; |
| 136 } | 136 } |
| 137 } | 137 } |
| 138 | 138 |
| 139 void GestureEventQueue::QueueAndForwardIfNecessary( | 139 void GestureEventQueue::QueueAndForwardIfNecessary( |
| 140 const GestureEventWithLatencyInfo& gesture_event) { | 140 const GestureEventWithLatencyInfo& gesture_event) { |
| 141 switch (gesture_event.event.type) { | 141 switch (gesture_event.event.type()) { |
| 142 case WebInputEvent::GestureFlingCancel: | 142 case WebInputEvent::GestureFlingCancel: |
| 143 fling_in_progress_ = false; | 143 fling_in_progress_ = false; |
| 144 break; | 144 break; |
| 145 case WebInputEvent::GestureFlingStart: | 145 case WebInputEvent::GestureFlingStart: |
| 146 fling_in_progress_ = true; | 146 fling_in_progress_ = true; |
| 147 break; | 147 break; |
| 148 case WebInputEvent::GesturePinchUpdate: | 148 case WebInputEvent::GesturePinchUpdate: |
| 149 case WebInputEvent::GestureScrollUpdate: | 149 case WebInputEvent::GestureScrollUpdate: |
| 150 QueueScrollOrPinchAndForwardIfNecessary(gesture_event); | 150 QueueScrollOrPinchAndForwardIfNecessary(gesture_event); |
| 151 return; | 151 return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 164 bool GestureEventQueue::OnScrollBegin( | 164 bool GestureEventQueue::OnScrollBegin( |
| 165 const GestureEventWithLatencyInfo& gesture_event) { | 165 const GestureEventWithLatencyInfo& gesture_event) { |
| 166 // If a synthetic scroll begin is encountered, it can cancel out a previous | 166 // If a synthetic scroll begin is encountered, it can cancel out a previous |
| 167 // synthetic scroll end. This allows a later gesture scroll update to coalesce | 167 // synthetic scroll end. This allows a later gesture scroll update to coalesce |
| 168 // with the previous one. crbug.com/607340. | 168 // with the previous one. crbug.com/607340. |
| 169 bool synthetic = gesture_event.event.data.scrollBegin.synthetic; | 169 bool synthetic = gesture_event.event.data.scrollBegin.synthetic; |
| 170 bool have_unsent_events = | 170 bool have_unsent_events = |
| 171 EventsInFlightCount() < coalesced_gesture_events_.size(); | 171 EventsInFlightCount() < coalesced_gesture_events_.size(); |
| 172 if (synthetic && have_unsent_events) { | 172 if (synthetic && have_unsent_events) { |
| 173 GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back(); | 173 GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back(); |
| 174 if (last_event->event.type == WebInputEvent::GestureScrollEnd && | 174 if (last_event->event.type() == WebInputEvent::GestureScrollEnd && |
| 175 last_event->event.data.scrollEnd.synthetic) { | 175 last_event->event.data.scrollEnd.synthetic) { |
| 176 coalesced_gesture_events_.pop_back(); | 176 coalesced_gesture_events_.pop_back(); |
| 177 return true; | 177 return true; |
| 178 } | 178 } |
| 179 } | 179 } |
| 180 return false; | 180 return false; |
| 181 } | 181 } |
| 182 | 182 |
| 183 void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result, | 183 void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result, |
| 184 WebInputEvent::Type type, | 184 WebInputEvent::Type type, |
| 185 const ui::LatencyInfo& latency) { | 185 const ui::LatencyInfo& latency) { |
| 186 TRACE_EVENT0("input", "GestureEventQueue::ProcessGestureAck"); | 186 TRACE_EVENT0("input", "GestureEventQueue::ProcessGestureAck"); |
| 187 | 187 |
| 188 if (coalesced_gesture_events_.empty()) { | 188 if (coalesced_gesture_events_.empty()) { |
| 189 DLOG(ERROR) << "Received unexpected ACK for event type " << type; | 189 DLOG(ERROR) << "Received unexpected ACK for event type " << type; |
| 190 return; | 190 return; |
| 191 } | 191 } |
| 192 | 192 |
| 193 // It's possible that the ack for the second event in an in-flight, coalesced | 193 // It's possible that the ack for the second event in an in-flight, coalesced |
| 194 // Gesture{Scroll,Pinch}Update pair is received prior to the first event ack. | 194 // Gesture{Scroll,Pinch}Update pair is received prior to the first event ack. |
| 195 size_t event_index = 0; | 195 size_t event_index = 0; |
| 196 if (ignore_next_ack_ && | 196 if (ignore_next_ack_ && coalesced_gesture_events_.size() > 1 && |
| 197 coalesced_gesture_events_.size() > 1 && | 197 coalesced_gesture_events_[0].event.type() != type && |
| 198 coalesced_gesture_events_[0].event.type != type && | 198 coalesced_gesture_events_[1].event.type() == type) { |
| 199 coalesced_gesture_events_[1].event.type == type) { | |
| 200 event_index = 1; | 199 event_index = 1; |
| 201 } | 200 } |
| 202 GestureEventWithLatencyInfo event_with_latency = | 201 GestureEventWithLatencyInfo event_with_latency = |
| 203 coalesced_gesture_events_[event_index]; | 202 coalesced_gesture_events_[event_index]; |
| 204 DCHECK_EQ(event_with_latency.event.type, type); | 203 DCHECK_EQ(event_with_latency.event.type(), type); |
| 205 event_with_latency.latency.AddNewLatencyFrom(latency); | 204 event_with_latency.latency.AddNewLatencyFrom(latency); |
| 206 | 205 |
| 207 // Ack'ing an event may enqueue additional gesture events. By ack'ing the | 206 // Ack'ing an event may enqueue additional gesture events. By ack'ing the |
| 208 // event before the forwarding of queued events below, such additional events | 207 // event before the forwarding of queued events below, such additional events |
| 209 // can be coalesced with existing queued events prior to dispatch. | 208 // can be coalesced with existing queued events prior to dispatch. |
| 210 client_->OnGestureEventAck(event_with_latency, ack_result); | 209 client_->OnGestureEventAck(event_with_latency, ack_result); |
| 211 | 210 |
| 212 const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result); | 211 const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result); |
| 213 if (type == WebInputEvent::GestureFlingCancel) { | 212 if (type == WebInputEvent::GestureFlingCancel) { |
| 214 if (event_with_latency.event.sourceDevice == | 213 if (event_with_latency.event.sourceDevice == |
| (...skipping 13 matching lines...) Expand all Loading... |
| 228 | 227 |
| 229 if (coalesced_gesture_events_.empty()) | 228 if (coalesced_gesture_events_.empty()) |
| 230 return; | 229 return; |
| 231 | 230 |
| 232 const GestureEventWithLatencyInfo& first_gesture_event = | 231 const GestureEventWithLatencyInfo& first_gesture_event = |
| 233 coalesced_gesture_events_.front(); | 232 coalesced_gesture_events_.front(); |
| 234 | 233 |
| 235 // Check for the coupled GesturePinchUpdate before sending either event, | 234 // Check for the coupled GesturePinchUpdate before sending either event, |
| 236 // handling the case where the first GestureScrollUpdate ack is synchronous. | 235 // handling the case where the first GestureScrollUpdate ack is synchronous. |
| 237 GestureEventWithLatencyInfo second_gesture_event; | 236 GestureEventWithLatencyInfo second_gesture_event; |
| 238 if (first_gesture_event.event.type == WebInputEvent::GestureScrollUpdate && | 237 if (first_gesture_event.event.type() == WebInputEvent::GestureScrollUpdate && |
| 239 coalesced_gesture_events_.size() > 1 && | 238 coalesced_gesture_events_.size() > 1 && |
| 240 coalesced_gesture_events_[1].event.type == | 239 coalesced_gesture_events_[1].event.type() == |
| 241 WebInputEvent::GesturePinchUpdate) { | 240 WebInputEvent::GesturePinchUpdate) { |
| 242 second_gesture_event = coalesced_gesture_events_[1]; | 241 second_gesture_event = coalesced_gesture_events_[1]; |
| 243 ignore_next_ack_ = true; | 242 ignore_next_ack_ = true; |
| 244 } | 243 } |
| 245 | 244 |
| 246 client_->SendGestureEventImmediately(first_gesture_event); | 245 client_->SendGestureEventImmediately(first_gesture_event); |
| 247 if (second_gesture_event.event.type != WebInputEvent::Undefined) | 246 if (second_gesture_event.event.type() != WebInputEvent::Undefined) |
| 248 client_->SendGestureEventImmediately(second_gesture_event); | 247 client_->SendGestureEventImmediately(second_gesture_event); |
| 249 } | 248 } |
| 250 | 249 |
| 251 TouchpadTapSuppressionController* | 250 TouchpadTapSuppressionController* |
| 252 GestureEventQueue::GetTouchpadTapSuppressionController() { | 251 GestureEventQueue::GetTouchpadTapSuppressionController() { |
| 253 return &touchpad_tap_suppression_controller_; | 252 return &touchpad_tap_suppression_controller_; |
| 254 } | 253 } |
| 255 | 254 |
| 256 void GestureEventQueue::FlingHasBeenHalted() { | 255 void GestureEventQueue::FlingHasBeenHalted() { |
| 257 fling_in_progress_ = false; | 256 fling_in_progress_ = false; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 286 coalesced_gesture_events_.push_back(gesture_event); | 285 coalesced_gesture_events_.push_back(gesture_event); |
| 287 if (coalesced_gesture_events_.size() == 1) { | 286 if (coalesced_gesture_events_.size() == 1) { |
| 288 client_->SendGestureEventImmediately(gesture_event); | 287 client_->SendGestureEventImmediately(gesture_event); |
| 289 } else if (coalesced_gesture_events_.size() == 2) { | 288 } else if (coalesced_gesture_events_.size() == 2) { |
| 290 DCHECK(!ignore_next_ack_); | 289 DCHECK(!ignore_next_ack_); |
| 291 // If there is an in-flight scroll, the new pinch can be forwarded | 290 // If there is an in-flight scroll, the new pinch can be forwarded |
| 292 // immediately, avoiding a potential frame delay between the two | 291 // immediately, avoiding a potential frame delay between the two |
| 293 // (similarly for an in-flight pinch with a new scroll). | 292 // (similarly for an in-flight pinch with a new scroll). |
| 294 const GestureEventWithLatencyInfo& first_event = | 293 const GestureEventWithLatencyInfo& first_event = |
| 295 coalesced_gesture_events_.front(); | 294 coalesced_gesture_events_.front(); |
| 296 if (gesture_event.event.type != first_event.event.type && | 295 if (gesture_event.event.type() != first_event.event.type() && |
| 297 ui::IsCompatibleScrollorPinch(gesture_event.event, | 296 ui::IsCompatibleScrollorPinch(gesture_event.event, |
| 298 first_event.event)) { | 297 first_event.event)) { |
| 299 ignore_next_ack_ = true; | 298 ignore_next_ack_ = true; |
| 300 client_->SendGestureEventImmediately(gesture_event); | 299 client_->SendGestureEventImmediately(gesture_event); |
| 301 } | 300 } |
| 302 } | 301 } |
| 303 return; | 302 return; |
| 304 } | 303 } |
| 305 | 304 |
| 306 GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back(); | 305 GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 return 0; | 360 return 0; |
| 362 | 361 |
| 363 if (!ignore_next_ack_) | 362 if (!ignore_next_ack_) |
| 364 return 1; | 363 return 1; |
| 365 | 364 |
| 366 DCHECK_GT(coalesced_gesture_events_.size(), 1U); | 365 DCHECK_GT(coalesced_gesture_events_.size(), 1U); |
| 367 return 2; | 366 return 2; |
| 368 } | 367 } |
| 369 | 368 |
| 370 } // namespace content | 369 } // namespace content |
| OLD | NEW |