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 |