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