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