| 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/command_line.h" | |
| 8 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 9 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 10 #include "content/browser/renderer_host/input/input_router.h" | 9 #include "content/browser/renderer_host/input/input_router.h" |
| 11 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
r.h" | 10 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
r.h" |
| 12 #include "content/browser/renderer_host/input/touchscreen_tap_suppression_contro
ller.h" | 11 #include "content/browser/renderer_host/input/touchscreen_tap_suppression_contro
ller.h" |
| 13 #include "content/public/common/content_switches.h" | 12 #include "content/public/common/content_switches.h" |
| 14 | 13 |
| 15 using blink::WebGestureEvent; | 14 using blink::WebGestureEvent; |
| 16 using blink::WebInputEvent; | 15 using blink::WebInputEvent; |
| 17 | 16 |
| 18 namespace content { | 17 namespace content { |
| 19 namespace { | |
| 20 | 18 |
| 21 // Default debouncing interval duration: if a scroll is in progress, non-scroll | 19 GestureEventQueue::Config::Config() { |
| 22 // events during this interval are deferred to either its end or discarded on | 20 } |
| 23 // receipt of another GestureScrollUpdate. | |
| 24 static const int kDebouncingIntervalTimeMs = 30; | |
| 25 | |
| 26 } // namespace | |
| 27 | 21 |
| 28 GestureEventQueue::GestureEventQueue( | 22 GestureEventQueue::GestureEventQueue( |
| 29 GestureEventQueueClient* client, | 23 GestureEventQueueClient* client, |
| 30 TouchpadTapSuppressionControllerClient* touchpad_client) | 24 TouchpadTapSuppressionControllerClient* touchpad_client, |
| 31 : client_(client), | 25 const Config& config) |
| 32 fling_in_progress_(false), | 26 : client_(client), |
| 33 scrolling_in_progress_(false), | 27 fling_in_progress_(false), |
| 34 ignore_next_ack_(false), | 28 scrolling_in_progress_(false), |
| 35 touchpad_tap_suppression_controller_( | 29 ignore_next_ack_(false), |
| 36 new TouchpadTapSuppressionController(touchpad_client)), | 30 touchpad_tap_suppression_controller_( |
| 37 touchscreen_tap_suppression_controller_( | 31 touchpad_client, config.touchpad_tap_suppression_config), |
| 38 new TouchscreenTapSuppressionController(this)), | 32 touchscreen_tap_suppression_controller_( |
| 39 debounce_interval_time_ms_(kDebouncingIntervalTimeMs), | 33 this, config.touchscreen_tap_suppression_config), |
| 40 debounce_enabled_(true) { | 34 debounce_interval_(config.debounce_interval) { |
| 41 DCHECK(client); | 35 DCHECK(client); |
| 42 DCHECK(touchpad_tap_suppression_controller_); | 36 DCHECK(touchpad_client); |
| 43 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 44 switches::kDisableGestureDebounce)) { | |
| 45 debounce_enabled_ = false; | |
| 46 } | |
| 47 } | 37 } |
| 48 | 38 |
| 49 GestureEventQueue::~GestureEventQueue() { } | 39 GestureEventQueue::~GestureEventQueue() { } |
| 50 | 40 |
| 51 bool GestureEventQueue::ShouldDiscardFlingCancelEvent( | 41 bool GestureEventQueue::ShouldDiscardFlingCancelEvent( |
| 52 const GestureEventWithLatencyInfo& gesture_event) const { | 42 const GestureEventWithLatencyInfo& gesture_event) const { |
| 53 if (coalesced_gesture_events_.empty() && fling_in_progress_) | 43 if (coalesced_gesture_events_.empty() && fling_in_progress_) |
| 54 return false; | 44 return false; |
| 55 GestureQueue::const_reverse_iterator it = | 45 GestureQueue::const_reverse_iterator it = |
| 56 coalesced_gesture_events_.rbegin(); | 46 coalesced_gesture_events_.rbegin(); |
| 57 while (it != coalesced_gesture_events_.rend()) { | 47 while (it != coalesced_gesture_events_.rend()) { |
| 58 if (it->event.type == WebInputEvent::GestureFlingStart) | 48 if (it->event.type == WebInputEvent::GestureFlingStart) |
| 59 return false; | 49 return false; |
| 60 if (it->event.type == WebInputEvent::GestureFlingCancel) | 50 if (it->event.type == WebInputEvent::GestureFlingCancel) |
| 61 return true; | 51 return true; |
| 62 it++; | 52 it++; |
| 63 } | 53 } |
| 64 return true; | 54 return true; |
| 65 } | 55 } |
| 66 | 56 |
| 67 bool GestureEventQueue::ShouldForwardForBounceReduction( | 57 bool GestureEventQueue::ShouldForwardForBounceReduction( |
| 68 const GestureEventWithLatencyInfo& gesture_event) { | 58 const GestureEventWithLatencyInfo& gesture_event) { |
| 69 if (!debounce_enabled_) | 59 if (debounce_interval_ <= base::TimeDelta()) |
| 70 return true; | 60 return true; |
| 71 switch (gesture_event.event.type) { | 61 switch (gesture_event.event.type) { |
| 72 case WebInputEvent::GestureScrollUpdate: | 62 case WebInputEvent::GestureScrollUpdate: |
| 73 if (!scrolling_in_progress_) { | 63 if (!scrolling_in_progress_) { |
| 74 debounce_deferring_timer_.Start( | 64 debounce_deferring_timer_.Start( |
| 75 FROM_HERE, | 65 FROM_HERE, |
| 76 base::TimeDelta::FromMilliseconds(debounce_interval_time_ms_), | 66 debounce_interval_, |
| 77 this, | 67 this, |
| 78 &GestureEventQueue::SendScrollEndingEventsNow); | 68 &GestureEventQueue::SendScrollEndingEventsNow); |
| 79 } else { | 69 } else { |
| 80 // Extend the bounce interval. | 70 // Extend the bounce interval. |
| 81 debounce_deferring_timer_.Reset(); | 71 debounce_deferring_timer_.Reset(); |
| 82 } | 72 } |
| 83 scrolling_in_progress_ = true; | 73 scrolling_in_progress_ = true; |
| 84 debouncing_deferral_queue_.clear(); | 74 debouncing_deferral_queue_.clear(); |
| 85 return true; | 75 return true; |
| 86 case WebInputEvent::GesturePinchBegin: | 76 case WebInputEvent::GesturePinchBegin: |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 const GestureEventWithLatencyInfo& gesture_event) const { | 110 const GestureEventWithLatencyInfo& gesture_event) const { |
| 121 return gesture_event.event.type != WebInputEvent::GestureFlingCancel || | 111 return gesture_event.event.type != WebInputEvent::GestureFlingCancel || |
| 122 !ShouldDiscardFlingCancelEvent(gesture_event); | 112 !ShouldDiscardFlingCancelEvent(gesture_event); |
| 123 } | 113 } |
| 124 | 114 |
| 125 bool GestureEventQueue::ShouldForwardForTapSuppression( | 115 bool GestureEventQueue::ShouldForwardForTapSuppression( |
| 126 const GestureEventWithLatencyInfo& gesture_event) { | 116 const GestureEventWithLatencyInfo& gesture_event) { |
| 127 switch (gesture_event.event.type) { | 117 switch (gesture_event.event.type) { |
| 128 case WebInputEvent::GestureFlingCancel: | 118 case WebInputEvent::GestureFlingCancel: |
| 129 if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen) | 119 if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen) |
| 130 touchscreen_tap_suppression_controller_->GestureFlingCancel(); | 120 touchscreen_tap_suppression_controller_.GestureFlingCancel(); |
| 131 else | 121 else |
| 132 touchpad_tap_suppression_controller_->GestureFlingCancel(); | 122 touchpad_tap_suppression_controller_.GestureFlingCancel(); |
| 133 return true; | 123 return true; |
| 134 case WebInputEvent::GestureTapDown: | 124 case WebInputEvent::GestureTapDown: |
| 135 case WebInputEvent::GestureShowPress: | 125 case WebInputEvent::GestureShowPress: |
| 136 case WebInputEvent::GestureTapUnconfirmed: | 126 case WebInputEvent::GestureTapUnconfirmed: |
| 137 case WebInputEvent::GestureTapCancel: | 127 case WebInputEvent::GestureTapCancel: |
| 138 case WebInputEvent::GestureTap: | 128 case WebInputEvent::GestureTap: |
| 139 case WebInputEvent::GestureDoubleTap: | 129 case WebInputEvent::GestureDoubleTap: |
| 140 if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen) { | 130 if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen) { |
| 141 return !touchscreen_tap_suppression_controller_-> | 131 return !touchscreen_tap_suppression_controller_.FilterTapEvent( |
| 142 FilterTapEvent(gesture_event); | 132 gesture_event); |
| 143 } | 133 } |
| 144 return true; | 134 return true; |
| 145 default: | 135 default: |
| 146 return true; | 136 return true; |
| 147 } | 137 } |
| 148 } | 138 } |
| 149 | 139 |
| 150 bool GestureEventQueue::ShouldForwardForCoalescing( | 140 bool GestureEventQueue::ShouldForwardForCoalescing( |
| 151 const GestureEventWithLatencyInfo& gesture_event) { | 141 const GestureEventWithLatencyInfo& gesture_event) { |
| 152 switch (gesture_event.event.type) { | 142 switch (gesture_event.event.type) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 event_with_latency.latency.AddNewLatencyFrom(latency); | 183 event_with_latency.latency.AddNewLatencyFrom(latency); |
| 194 | 184 |
| 195 // Ack'ing an event may enqueue additional gesture events. By ack'ing the | 185 // Ack'ing an event may enqueue additional gesture events. By ack'ing the |
| 196 // event before the forwarding of queued events below, such additional events | 186 // event before the forwarding of queued events below, such additional events |
| 197 // can be coalesced with existing queued events prior to dispatch. | 187 // can be coalesced with existing queued events prior to dispatch. |
| 198 client_->OnGestureEventAck(event_with_latency, ack_result); | 188 client_->OnGestureEventAck(event_with_latency, ack_result); |
| 199 | 189 |
| 200 const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result); | 190 const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result); |
| 201 if (type == WebInputEvent::GestureFlingCancel) { | 191 if (type == WebInputEvent::GestureFlingCancel) { |
| 202 if (event_with_latency.event.sourceDevice == WebGestureEvent::Touchscreen) | 192 if (event_with_latency.event.sourceDevice == WebGestureEvent::Touchscreen) |
| 203 touchscreen_tap_suppression_controller_->GestureFlingCancelAck(processed); | 193 touchscreen_tap_suppression_controller_.GestureFlingCancelAck(processed); |
| 204 else | 194 else |
| 205 touchpad_tap_suppression_controller_->GestureFlingCancelAck(processed); | 195 touchpad_tap_suppression_controller_.GestureFlingCancelAck(processed); |
| 206 } | 196 } |
| 207 DCHECK_LT(event_index, coalesced_gesture_events_.size()); | 197 DCHECK_LT(event_index, coalesced_gesture_events_.size()); |
| 208 coalesced_gesture_events_.erase(coalesced_gesture_events_.begin() + | 198 coalesced_gesture_events_.erase(coalesced_gesture_events_.begin() + |
| 209 event_index); | 199 event_index); |
| 210 | 200 |
| 211 if (ignore_next_ack_) { | 201 if (ignore_next_ack_) { |
| 212 ignore_next_ack_ = false; | 202 ignore_next_ack_ = false; |
| 213 return; | 203 return; |
| 214 } | 204 } |
| 215 | 205 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 231 ignore_next_ack_ = true; | 221 ignore_next_ack_ = true; |
| 232 } | 222 } |
| 233 | 223 |
| 234 client_->SendGestureEventImmediately(first_gesture_event); | 224 client_->SendGestureEventImmediately(first_gesture_event); |
| 235 if (second_gesture_event.event.type != WebInputEvent::Undefined) | 225 if (second_gesture_event.event.type != WebInputEvent::Undefined) |
| 236 client_->SendGestureEventImmediately(second_gesture_event); | 226 client_->SendGestureEventImmediately(second_gesture_event); |
| 237 } | 227 } |
| 238 | 228 |
| 239 TouchpadTapSuppressionController* | 229 TouchpadTapSuppressionController* |
| 240 GestureEventQueue::GetTouchpadTapSuppressionController() { | 230 GestureEventQueue::GetTouchpadTapSuppressionController() { |
| 241 return touchpad_tap_suppression_controller_.get(); | 231 return &touchpad_tap_suppression_controller_; |
| 242 } | 232 } |
| 243 | 233 |
| 244 bool GestureEventQueue::ExpectingGestureAck() const { | 234 bool GestureEventQueue::ExpectingGestureAck() const { |
| 245 return !coalesced_gesture_events_.empty(); | 235 return !coalesced_gesture_events_.empty(); |
| 246 } | 236 } |
| 247 | 237 |
| 248 void GestureEventQueue::FlingHasBeenHalted() { | 238 void GestureEventQueue::FlingHasBeenHalted() { |
| 249 fling_in_progress_ = false; | 239 fling_in_progress_ = false; |
| 250 } | 240 } |
| 251 | 241 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 return 0; | 373 return 0; |
| 384 | 374 |
| 385 if (!ignore_next_ack_) | 375 if (!ignore_next_ack_) |
| 386 return 1; | 376 return 1; |
| 387 | 377 |
| 388 DCHECK_GT(coalesced_gesture_events_.size(), 1U); | 378 DCHECK_GT(coalesced_gesture_events_.size(), 1U); |
| 389 return 2; | 379 return 2; |
| 390 } | 380 } |
| 391 | 381 |
| 392 } // namespace content | 382 } // namespace content |
| OLD | NEW |