Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/touch_event_queue.h" | 5 #include "content/browser/renderer_host/input/legacy_touch_event_queue.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
| 13 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
| 14 #include "content/browser/renderer_host/input/timeout_monitor.h" | 14 #include "content/browser/renderer_host/input/timeout_monitor.h" |
| 15 #include "content/common/input/web_touch_event_traits.h" | 15 #include "content/common/input/web_touch_event_traits.h" |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 43 } | 43 } |
| 44 | 44 |
| 45 bool ShouldTouchTriggerTimeout(const WebTouchEvent& event) { | 45 bool ShouldTouchTriggerTimeout(const WebTouchEvent& event) { |
| 46 return (event.type() == WebInputEvent::TouchStart || | 46 return (event.type() == WebInputEvent::TouchStart || |
| 47 event.type() == WebInputEvent::TouchMove) && | 47 event.type() == WebInputEvent::TouchMove) && |
| 48 event.dispatchType == WebInputEvent::Blocking; | 48 event.dispatchType == WebInputEvent::Blocking; |
| 49 } | 49 } |
| 50 | 50 |
| 51 // Compare all properties of touch points to determine the state. | 51 // Compare all properties of touch points to determine the state. |
| 52 bool HasPointChanged(const WebTouchPoint& point_1, | 52 bool HasPointChanged(const WebTouchPoint& point_1, |
| 53 const WebTouchPoint& point_2) { | 53 const WebTouchPoint& point_2) { |
| 54 DCHECK_EQ(point_1.id, point_2.id); | 54 DCHECK_EQ(point_1.id, point_2.id); |
| 55 if (point_1.screenPosition != point_2.screenPosition || | 55 if (point_1.screenPosition != point_2.screenPosition || |
| 56 point_1.position != point_2.position || | 56 point_1.position != point_2.position || |
| 57 point_1.radiusX != point_2.radiusX || | 57 point_1.radiusX != point_2.radiusX || |
| 58 point_1.radiusY != point_2.radiusY || | 58 point_1.radiusY != point_2.radiusY || |
| 59 point_1.rotationAngle != point_2.rotationAngle || | 59 point_1.rotationAngle != point_2.rotationAngle || |
| 60 point_1.force != point_2.force || | 60 point_1.force != point_2.force || point_1.tiltX != point_2.tiltX || |
| 61 point_1.tiltX != point_2.tiltX || | |
| 62 point_1.tiltY != point_2.tiltY) { | 61 point_1.tiltY != point_2.tiltY) { |
| 63 return true; | 62 return true; |
| 64 } | 63 } |
| 65 return false; | 64 return false; |
| 66 } | 65 } |
| 67 | 66 |
| 68 } // namespace | 67 } // namespace |
| 69 | 68 |
| 70 | |
| 71 // Cancels a touch sequence if a touchstart or touchmove ack response is | 69 // Cancels a touch sequence if a touchstart or touchmove ack response is |
| 72 // sufficiently delayed. | 70 // sufficiently delayed. |
| 73 class TouchEventQueue::TouchTimeoutHandler { | 71 class LegacyTouchEventQueue::TouchTimeoutHandler { |
| 74 public: | 72 public: |
| 75 TouchTimeoutHandler(TouchEventQueue* touch_queue, | 73 TouchTimeoutHandler(LegacyTouchEventQueue* touch_queue, |
| 76 base::TimeDelta desktop_timeout_delay, | 74 base::TimeDelta desktop_timeout_delay, |
| 77 base::TimeDelta mobile_timeout_delay) | 75 base::TimeDelta mobile_timeout_delay) |
| 78 : touch_queue_(touch_queue), | 76 : touch_queue_(touch_queue), |
| 79 desktop_timeout_delay_(desktop_timeout_delay), | 77 desktop_timeout_delay_(desktop_timeout_delay), |
| 80 mobile_timeout_delay_(mobile_timeout_delay), | 78 mobile_timeout_delay_(mobile_timeout_delay), |
| 81 use_mobile_timeout_(false), | 79 use_mobile_timeout_(false), |
| 82 pending_ack_state_(PENDING_ACK_NONE), | 80 pending_ack_state_(PENDING_ACK_NONE), |
| 83 timeout_monitor_(base::Bind(&TouchTimeoutHandler::OnTimeOut, | 81 timeout_monitor_(base::Bind(&TouchTimeoutHandler::OnTimeOut, |
| 84 base::Unretained(this))), | 82 base::Unretained(this))), |
| 85 enabled_(true), | 83 enabled_(true), |
| 86 enabled_for_current_sequence_(false), | 84 enabled_for_current_sequence_(false), |
| 87 sequence_awaiting_uma_update_(false), | 85 sequence_awaiting_uma_update_(false), |
| 88 sequence_using_mobile_timeout_(false) { | 86 sequence_using_mobile_timeout_(false) { |
| 89 SetUseMobileTimeout(false); | 87 SetUseMobileTimeout(false); |
| 90 } | 88 } |
| 91 | 89 |
| 92 ~TouchTimeoutHandler() { | 90 ~TouchTimeoutHandler() { LogSequenceEndForUMAIfNecessary(false); } |
| 93 LogSequenceEndForUMAIfNecessary(false); | |
| 94 } | |
| 95 | 91 |
| 96 void StartIfNecessary(const TouchEventWithLatencyInfo& event) { | 92 void StartIfNecessary(const TouchEventWithLatencyInfo& event) { |
| 97 if (pending_ack_state_ != PENDING_ACK_NONE) | 93 if (pending_ack_state_ != PENDING_ACK_NONE) |
| 98 return; | 94 return; |
| 99 | 95 |
| 100 if (!enabled_) | 96 if (!enabled_) |
| 101 return; | 97 return; |
| 102 | 98 |
| 103 const base::TimeDelta timeout_delay = GetTimeoutDelay(); | 99 const base::TimeDelta timeout_delay = GetTimeoutDelay(); |
| 104 if (timeout_delay.is_zero()) | 100 if (timeout_delay.is_zero()) |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 timeout_monitor_.Stop(); | 173 timeout_monitor_.Stop(); |
| 178 } | 174 } |
| 179 } | 175 } |
| 180 | 176 |
| 181 void SetUseMobileTimeout(bool use_mobile_timeout) { | 177 void SetUseMobileTimeout(bool use_mobile_timeout) { |
| 182 use_mobile_timeout_ = use_mobile_timeout; | 178 use_mobile_timeout_ = use_mobile_timeout; |
| 183 } | 179 } |
| 184 | 180 |
| 185 bool IsTimeoutTimerRunning() const { return timeout_monitor_.IsRunning(); } | 181 bool IsTimeoutTimerRunning() const { return timeout_monitor_.IsRunning(); } |
| 186 | 182 |
| 187 bool IsEnabled() const { | 183 bool IsEnabled() const { return enabled_ && !GetTimeoutDelay().is_zero(); } |
| 188 return enabled_ && !GetTimeoutDelay().is_zero(); | |
| 189 } | |
| 190 | 184 |
| 191 private: | 185 private: |
| 192 enum PendingAckState { | 186 enum PendingAckState { |
| 193 PENDING_ACK_NONE, | 187 PENDING_ACK_NONE, |
| 194 PENDING_ACK_ORIGINAL_EVENT, | 188 PENDING_ACK_ORIGINAL_EVENT, |
| 195 PENDING_ACK_CANCEL_EVENT, | 189 PENDING_ACK_CANCEL_EVENT, |
| 196 }; | 190 }; |
| 197 | 191 |
| 198 void OnTimeOut() { | 192 void OnTimeOut() { |
| 199 LogSequenceEndForUMAIfNecessary(true); | 193 LogSequenceEndForUMAIfNecessary(true); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 214 DCHECK_NE(pending_ack_state_, new_pending_ack_state); | 208 DCHECK_NE(pending_ack_state_, new_pending_ack_state); |
| 215 switch (new_pending_ack_state) { | 209 switch (new_pending_ack_state) { |
| 216 case PENDING_ACK_ORIGINAL_EVENT: | 210 case PENDING_ACK_ORIGINAL_EVENT: |
| 217 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE); | 211 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE); |
| 218 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this); | 212 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this); |
| 219 break; | 213 break; |
| 220 case PENDING_ACK_CANCEL_EVENT: | 214 case PENDING_ACK_CANCEL_EVENT: |
| 221 DCHECK_EQ(pending_ack_state_, PENDING_ACK_ORIGINAL_EVENT); | 215 DCHECK_EQ(pending_ack_state_, PENDING_ACK_ORIGINAL_EVENT); |
| 222 DCHECK(!timeout_monitor_.IsRunning()); | 216 DCHECK(!timeout_monitor_.IsRunning()); |
| 223 DCHECK(touch_queue_->empty()); | 217 DCHECK(touch_queue_->empty()); |
| 224 TRACE_EVENT_ASYNC_STEP_INTO0( | 218 TRACE_EVENT_ASYNC_STEP_INTO0("input", "TouchEventTimeout", this, |
| 225 "input", "TouchEventTimeout", this, "CancelEvent"); | 219 "CancelEvent"); |
| 226 break; | 220 break; |
| 227 case PENDING_ACK_NONE: | 221 case PENDING_ACK_NONE: |
| 228 DCHECK(!timeout_monitor_.IsRunning()); | 222 DCHECK(!timeout_monitor_.IsRunning()); |
| 229 DCHECK(touch_queue_->empty()); | 223 DCHECK(touch_queue_->empty()); |
| 230 TRACE_EVENT_ASYNC_END0("input", "TouchEventTimeout", this); | 224 TRACE_EVENT_ASYNC_END0("input", "TouchEventTimeout", this); |
| 231 break; | 225 break; |
| 232 } | 226 } |
| 233 pending_ack_state_ = new_pending_ack_state; | 227 pending_ack_state_ = new_pending_ack_state; |
| 234 } | 228 } |
| 235 | 229 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 254 } | 248 } |
| 255 | 249 |
| 256 base::TimeDelta GetTimeoutDelay() const { | 250 base::TimeDelta GetTimeoutDelay() const { |
| 257 return use_mobile_timeout_ ? mobile_timeout_delay_ : desktop_timeout_delay_; | 251 return use_mobile_timeout_ ? mobile_timeout_delay_ : desktop_timeout_delay_; |
| 258 } | 252 } |
| 259 | 253 |
| 260 bool HasTimeoutEvent() const { | 254 bool HasTimeoutEvent() const { |
| 261 return pending_ack_state_ != PENDING_ACK_NONE; | 255 return pending_ack_state_ != PENDING_ACK_NONE; |
| 262 } | 256 } |
| 263 | 257 |
| 264 TouchEventQueue* touch_queue_; | 258 LegacyTouchEventQueue* touch_queue_; |
| 265 | 259 |
| 266 // How long to wait on a touch ack before cancelling the touch sequence. | 260 // How long to wait on a touch ack before cancelling the touch sequence. |
| 267 const base::TimeDelta desktop_timeout_delay_; | 261 const base::TimeDelta desktop_timeout_delay_; |
| 268 const base::TimeDelta mobile_timeout_delay_; | 262 const base::TimeDelta mobile_timeout_delay_; |
| 269 bool use_mobile_timeout_; | 263 bool use_mobile_timeout_; |
| 270 | 264 |
| 271 // The touch event source for which we expect the next ack. | 265 // The touch event source for which we expect the next ack. |
| 272 PendingAckState pending_ack_state_; | 266 PendingAckState pending_ack_state_; |
| 273 | 267 |
| 274 // The event for which the ack timeout is triggered. | 268 // The event for which the ack timeout is triggered. |
| 275 TouchEventWithLatencyInfo timeout_event_; | 269 TouchEventWithLatencyInfo timeout_event_; |
| 276 | 270 |
| 277 // Provides timeout-based callback behavior. | 271 // Provides timeout-based callback behavior. |
| 278 TimeoutMonitor timeout_monitor_; | 272 TimeoutMonitor timeout_monitor_; |
| 279 | 273 |
| 280 bool enabled_; | 274 bool enabled_; |
| 281 bool enabled_for_current_sequence_; | 275 bool enabled_for_current_sequence_; |
| 282 | 276 |
| 283 // Bookkeeping to classify and log whether a touch sequence times out. | 277 // Bookkeeping to classify and log whether a touch sequence times out. |
| 284 bool sequence_awaiting_uma_update_; | 278 bool sequence_awaiting_uma_update_; |
| 285 bool sequence_using_mobile_timeout_; | 279 bool sequence_using_mobile_timeout_; |
| 286 }; | 280 }; |
| 287 | 281 |
| 288 // Provides touchmove slop suppression for a touch sequence until a | 282 // Provides touchmove slop suppression for a touch sequence until a |
| 289 // (unprevented) touch will trigger immediate scrolling. | 283 // (unprevented) touch will trigger immediate scrolling. |
| 290 class TouchEventQueue::TouchMoveSlopSuppressor { | 284 class LegacyTouchEventQueue::TouchMoveSlopSuppressor { |
|
tdresser
2017/01/27 15:11:56
We'll need to pull this out to enable code sharing
dtapuska
2017/01/27 15:57:38
Nope I think implementing this on main thread firs
| |
| 291 public: | 285 public: |
| 292 TouchMoveSlopSuppressor() : suppressing_touchmoves_(false) {} | 286 TouchMoveSlopSuppressor() : suppressing_touchmoves_(false) {} |
| 293 | 287 |
| 294 bool FilterEvent(const WebTouchEvent& event) { | 288 bool FilterEvent(const WebTouchEvent& event) { |
| 295 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { | 289 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { |
| 296 suppressing_touchmoves_ = true; | 290 suppressing_touchmoves_ = true; |
| 297 touch_start_location_ = gfx::PointF(event.touches[0].position); | 291 touch_start_location_ = gfx::PointF(event.touches[0].position); |
| 298 } | 292 } |
| 299 | 293 |
| 300 if (event.type() == WebInputEvent::TouchEnd || | 294 if (event.type() == WebInputEvent::TouchEnd || |
| 301 event.type() == WebInputEvent::TouchCancel) | 295 event.type() == WebInputEvent::TouchCancel) |
| 302 suppressing_touchmoves_ = false; | 296 suppressing_touchmoves_ = false; |
| 303 | 297 |
| 304 if (event.type() != WebInputEvent::TouchMove) | 298 if (event.type() != WebInputEvent::TouchMove) |
| 305 return false; | 299 return false; |
| 306 | 300 |
| 307 if (suppressing_touchmoves_) { | 301 if (suppressing_touchmoves_) { |
| 308 if (event.touchesLength > 1) { | 302 if (event.touchesLength > 1) { |
| 309 suppressing_touchmoves_ = false; | 303 suppressing_touchmoves_ = false; |
| 310 } else if (event.movedBeyondSlopRegion) { | 304 } else if (event.movedBeyondSlopRegion) { |
| 311 suppressing_touchmoves_ = false; | 305 suppressing_touchmoves_ = false; |
| 312 } else { | 306 } else { |
| 313 // No sane slop region should be larger than 60 DIPs. | 307 // No sane slop region should be larger than 60 DIPs. |
| 314 DCHECK_LT((gfx::PointF(event.touches[0].position) - | 308 DCHECK_LT( |
| 315 touch_start_location_).LengthSquared(), | 309 (gfx::PointF(event.touches[0].position) - touch_start_location_) |
| 316 kMaxConceivablePlatformSlopRegionLengthDipsSquared); | 310 .LengthSquared(), |
| 311 kMaxConceivablePlatformSlopRegionLengthDipsSquared); | |
| 317 } | 312 } |
| 318 } | 313 } |
| 319 | 314 |
| 320 return suppressing_touchmoves_; | 315 return suppressing_touchmoves_; |
| 321 } | 316 } |
| 322 | 317 |
| 323 void ConfirmTouchEvent(InputEventAckState ack_result) { | 318 void ConfirmTouchEvent(InputEventAckState ack_result) { |
| 324 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) | 319 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) |
| 325 suppressing_touchmoves_ = false; | 320 suppressing_touchmoves_ = false; |
| 326 } | 321 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 340 // This class represents a single coalesced touch event. However, it also keeps | 335 // This class represents a single coalesced touch event. However, it also keeps |
| 341 // track of all the original touch-events that were coalesced into a single | 336 // track of all the original touch-events that were coalesced into a single |
| 342 // event. The coalesced event is forwarded to the renderer, while the original | 337 // event. The coalesced event is forwarded to the renderer, while the original |
| 343 // touch-events are sent to the Client (on ACK for the coalesced event) so that | 338 // touch-events are sent to the Client (on ACK for the coalesced event) so that |
| 344 // the Client receives the event with their original timestamp. | 339 // the Client receives the event with their original timestamp. |
| 345 class CoalescedWebTouchEvent { | 340 class CoalescedWebTouchEvent { |
| 346 public: | 341 public: |
| 347 CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event, | 342 CoalescedWebTouchEvent(const TouchEventWithLatencyInfo& event, |
| 348 bool suppress_client_ack) | 343 bool suppress_client_ack) |
| 349 : coalesced_event_(event), suppress_client_ack_(suppress_client_ack) { | 344 : coalesced_event_(event), suppress_client_ack_(suppress_client_ack) { |
| 350 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventQueue::QueueEvent", this); | 345 TRACE_EVENT_ASYNC_BEGIN0("input", "LegacyTouchEventQueue::QueueEvent", |
| 346 this); | |
| 351 } | 347 } |
| 352 | 348 |
| 353 ~CoalescedWebTouchEvent() { | 349 ~CoalescedWebTouchEvent() { |
| 354 TRACE_EVENT_ASYNC_END0("input", "TouchEventQueue::QueueEvent", this); | 350 TRACE_EVENT_ASYNC_END0("input", "LegacyTouchEventQueue::QueueEvent", this); |
| 355 } | 351 } |
| 356 | 352 |
| 357 // Coalesces the event with the existing event if possible. Returns whether | 353 // Coalesces the event with the existing event if possible. Returns whether |
| 358 // the event was coalesced. | 354 // the event was coalesced. |
| 359 bool CoalesceEventIfPossible( | 355 bool CoalesceEventIfPossible( |
| 360 const TouchEventWithLatencyInfo& event_with_latency) { | 356 const TouchEventWithLatencyInfo& event_with_latency) { |
| 361 if (suppress_client_ack_) | 357 if (suppress_client_ack_) |
| 362 return false; | 358 return false; |
| 363 | 359 |
| 364 if (!coalesced_event_.CanCoalesceWith(event_with_latency)) | 360 if (!coalesced_event_.CanCoalesceWith(event_with_latency)) |
| 365 return false; | 361 return false; |
| 366 | 362 |
| 367 // Addition of the first event to |uncoaleseced_events_to_ack_| is deferred | 363 // Addition of the first event to |uncoaleseced_events_to_ack_| is deferred |
| 368 // until the first coalesced event, optimizing the (common) case where the | 364 // until the first coalesced event, optimizing the (common) case where the |
| 369 // event is not coalesced at all. | 365 // event is not coalesced at all. |
| 370 if (uncoaleseced_events_to_ack_.empty()) | 366 if (uncoaleseced_events_to_ack_.empty()) |
| 371 uncoaleseced_events_to_ack_.push_back(coalesced_event_); | 367 uncoaleseced_events_to_ack_.push_back(coalesced_event_); |
| 372 | 368 |
| 373 TRACE_EVENT_INSTANT0( | 369 TRACE_EVENT_INSTANT0("input", "LegacyTouchEventQueue::MoveCoalesced", |
| 374 "input", "TouchEventQueue::MoveCoalesced", TRACE_EVENT_SCOPE_THREAD); | 370 TRACE_EVENT_SCOPE_THREAD); |
| 375 coalesced_event_.CoalesceWith(event_with_latency); | 371 coalesced_event_.CoalesceWith(event_with_latency); |
| 376 uncoaleseced_events_to_ack_.push_back(event_with_latency); | 372 uncoaleseced_events_to_ack_.push_back(event_with_latency); |
| 377 DCHECK_GE(uncoaleseced_events_to_ack_.size(), 2U); | 373 DCHECK_GE(uncoaleseced_events_to_ack_.size(), 2U); |
| 378 return true; | 374 return true; |
| 379 } | 375 } |
| 380 | 376 |
| 381 void DispatchAckToClient(InputEventAckState ack_result, | 377 void DispatchAckToClient(InputEventAckState ack_result, |
| 382 const ui::LatencyInfo* optional_latency_info, | 378 const ui::LatencyInfo* optional_latency_info, |
| 383 TouchEventQueueClient* client) { | 379 TouchEventQueueClient* client) { |
| 384 DCHECK(client); | 380 DCHECK(client); |
| 385 if (suppress_client_ack_) | 381 if (suppress_client_ack_) |
| 386 return; | 382 return; |
| 387 | 383 |
| 388 if (uncoaleseced_events_to_ack_.empty()) { | 384 if (uncoaleseced_events_to_ack_.empty()) { |
| 389 if (optional_latency_info) | 385 if (optional_latency_info) |
| 390 coalesced_event_.latency.AddNewLatencyFrom(*optional_latency_info); | 386 coalesced_event_.latency.AddNewLatencyFrom(*optional_latency_info); |
| 391 client->OnTouchEventAck(coalesced_event_, ack_result); | 387 client->OnTouchEventAck(coalesced_event_, ack_result); |
| 392 return; | 388 return; |
| 393 } | 389 } |
| 394 | 390 |
| 395 DCHECK_GE(uncoaleseced_events_to_ack_.size(), 2U); | 391 DCHECK_GE(uncoaleseced_events_to_ack_.size(), 2U); |
| 396 for (WebTouchEventWithLatencyList::iterator | 392 for (WebTouchEventWithLatencyList::iterator |
| 397 iter = uncoaleseced_events_to_ack_.begin(), | 393 iter = uncoaleseced_events_to_ack_.begin(), |
| 398 end = uncoaleseced_events_to_ack_.end(); | 394 end = uncoaleseced_events_to_ack_.end(); |
| 399 iter != end; | 395 iter != end; ++iter) { |
| 400 ++iter) { | |
| 401 if (optional_latency_info) | 396 if (optional_latency_info) |
| 402 iter->latency.AddNewLatencyFrom(*optional_latency_info); | 397 iter->latency.AddNewLatencyFrom(*optional_latency_info); |
| 403 client->OnTouchEventAck(*iter, ack_result); | 398 client->OnTouchEventAck(*iter, ack_result); |
| 404 } | 399 } |
| 405 } | 400 } |
| 406 | 401 |
| 407 const TouchEventWithLatencyInfo& coalesced_event() const { | 402 const TouchEventWithLatencyInfo& coalesced_event() const { |
| 408 return coalesced_event_; | 403 return coalesced_event_; |
| 409 } | 404 } |
| 410 | 405 |
| 411 private: | 406 private: |
| 412 // This is the event that is forwarded to the renderer. | 407 // This is the event that is forwarded to the renderer. |
| 413 TouchEventWithLatencyInfo coalesced_event_; | 408 TouchEventWithLatencyInfo coalesced_event_; |
| 414 | 409 |
| 415 // This is the list of the original events that were coalesced, each requiring | 410 // This is the list of the original events that were coalesced, each requiring |
| 416 // future ack dispatch to the client. | 411 // future ack dispatch to the client. |
| 417 // Note that this will be empty if no coalescing has occurred. | 412 // Note that this will be empty if no coalescing has occurred. |
| 418 typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList; | 413 typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList; |
| 419 WebTouchEventWithLatencyList uncoaleseced_events_to_ack_; | 414 WebTouchEventWithLatencyList uncoaleseced_events_to_ack_; |
| 420 | 415 |
| 421 bool suppress_client_ack_; | 416 bool suppress_client_ack_; |
| 422 | 417 |
| 423 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent); | 418 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent); |
| 424 }; | 419 }; |
| 425 | 420 |
| 426 TouchEventQueue::Config::Config() | 421 LegacyTouchEventQueue::LegacyTouchEventQueue(TouchEventQueueClient* client, |
| 427 : desktop_touch_ack_timeout_delay(base::TimeDelta::FromMilliseconds(200)), | 422 const Config& config) |
| 428 mobile_touch_ack_timeout_delay(base::TimeDelta::FromMilliseconds(1000)), | 423 : TouchEventQueue(client, config), |
| 429 touch_ack_timeout_supported(false) { | |
| 430 } | |
| 431 | |
| 432 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client, | |
| 433 const Config& config) | |
| 434 : client_(client), | |
| 435 dispatching_touch_ack_(false), | 424 dispatching_touch_ack_(false), |
| 436 dispatching_touch_(false), | 425 dispatching_touch_(false), |
| 437 has_handlers_(true), | 426 has_handlers_(true), |
| 438 has_handler_for_current_sequence_(false), | 427 has_handler_for_current_sequence_(false), |
| 439 drop_remaining_touches_in_sequence_(false), | 428 drop_remaining_touches_in_sequence_(false), |
| 440 touchmove_slop_suppressor_(new TouchMoveSlopSuppressor), | 429 touchmove_slop_suppressor_(new TouchMoveSlopSuppressor), |
| 441 send_touch_events_async_(false), | 430 send_touch_events_async_(false), |
| 442 last_sent_touch_timestamp_sec_(0) { | 431 last_sent_touch_timestamp_sec_(0) { |
| 443 DCHECK(client); | |
| 444 if (config.touch_ack_timeout_supported) { | 432 if (config.touch_ack_timeout_supported) { |
| 445 timeout_handler_.reset( | 433 timeout_handler_.reset( |
| 446 new TouchTimeoutHandler(this, | 434 new TouchTimeoutHandler(this, config.desktop_touch_ack_timeout_delay, |
| 447 config.desktop_touch_ack_timeout_delay, | |
| 448 config.mobile_touch_ack_timeout_delay)); | 435 config.mobile_touch_ack_timeout_delay)); |
| 449 } | 436 } |
| 450 } | 437 } |
| 451 | 438 |
| 452 TouchEventQueue::~TouchEventQueue() { | 439 LegacyTouchEventQueue::~LegacyTouchEventQueue() {} |
| 453 } | |
| 454 | 440 |
| 455 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { | 441 void LegacyTouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { |
| 456 TRACE_EVENT0("input", "TouchEventQueue::QueueEvent"); | 442 TRACE_EVENT0("input", "LegacyTouchEventQueue::QueueEvent"); |
| 457 | 443 |
| 458 // If the queueing of |event| was triggered by an ack dispatch, defer | 444 // If the queueing of |event| was triggered by an ack dispatch, defer |
| 459 // processing the event until the dispatch has finished. | 445 // processing the event until the dispatch has finished. |
| 460 if (touch_queue_.empty() && !dispatching_touch_ack_) { | 446 if (touch_queue_.empty() && !dispatching_touch_ack_) { |
| 461 // Optimization of the case without touch handlers. Removing this path | 447 // Optimization of the case without touch handlers. Removing this path |
| 462 // yields identical results, but this avoids unnecessary allocations. | 448 // yields identical results, but this avoids unnecessary allocations. |
| 463 PreFilterResult filter_result = FilterBeforeForwarding(event.event); | 449 PreFilterResult filter_result = FilterBeforeForwarding(event.event); |
| 464 if (filter_result != FORWARD_TO_RENDERER) { | 450 if (filter_result != FORWARD_TO_RENDERER) { |
| 465 client_->OnFilteringTouchEvent(event.event); | 451 client_->OnFilteringTouchEvent(event.event); |
| 466 client_->OnTouchEventAck(event, | 452 client_->OnTouchEventAck(event, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 482 // also a touch-move, then the events can be coalesced into a single event. | 468 // also a touch-move, then the events can be coalesced into a single event. |
| 483 if (touch_queue_.size() > 1) { | 469 if (touch_queue_.size() > 1) { |
| 484 CoalescedWebTouchEvent* last_event = touch_queue_.back().get(); | 470 CoalescedWebTouchEvent* last_event = touch_queue_.back().get(); |
| 485 if (last_event->CoalesceEventIfPossible(event)) | 471 if (last_event->CoalesceEventIfPossible(event)) |
| 486 return; | 472 return; |
| 487 } | 473 } |
| 488 touch_queue_.push_back( | 474 touch_queue_.push_back( |
| 489 base::MakeUnique<CoalescedWebTouchEvent>(event, false)); | 475 base::MakeUnique<CoalescedWebTouchEvent>(event, false)); |
| 490 } | 476 } |
| 491 | 477 |
| 492 void TouchEventQueue::PrependTouchScrollNotification() { | 478 void LegacyTouchEventQueue::PrependTouchScrollNotification() { |
| 493 TRACE_EVENT0("input", "TouchEventQueue::PrependTouchScrollNotification"); | 479 TRACE_EVENT0("input", |
| 480 "LegacyTouchEventQueue::PrependTouchScrollNotification"); | |
| 494 | 481 |
| 495 // The queue should have an in-flight event when this method is called because | 482 // The queue should have an in-flight event when this method is called because |
| 496 // this method is triggered by InputRouterImpl::SendGestureEvent, which is | 483 // this method is triggered by InputRouterImpl::SendGestureEvent, which is |
| 497 // triggered by TouchEventQueue::AckTouchEventToClient, which has just | 484 // triggered by LegacyTouchEventQueue::AckTouchEventToClient, which has just |
| 498 // received an ack for the in-flight event. We leave the head of the queue | 485 // received an ack for the in-flight event. We leave the head of the queue |
| 499 // untouched since it is the in-flight event. | 486 // untouched since it is the in-flight event. |
| 500 // | 487 // |
| 501 // However, for the (integration) tests in RenderWidgetHostTest that trigger | 488 // However, for the (integration) tests in RenderWidgetHostTest that trigger |
| 502 // this method indirectly, they push the TouchScrollStarted event into | 489 // this method indirectly, they push the TouchScrollStarted event into |
| 503 // TouchEventQueue without any way to dispatch it. Below we added a check for | 490 // TouchEventQueue without any way to dispatch it. Below we added a check for |
| 504 // non-empty queue to keep those tests as-is w/o exposing internals of this | 491 // non-empty queue to keep those tests as-is w/o exposing internals of this |
| 505 // class all the way up. | 492 // class all the way up. |
| 506 if (!touch_queue_.empty()) { | 493 if (!touch_queue_.empty()) { |
| 507 TouchEventWithLatencyInfo touch( | 494 TouchEventWithLatencyInfo touch( |
| 508 WebInputEvent::TouchScrollStarted, WebInputEvent::NoModifiers, | 495 WebInputEvent::TouchScrollStarted, WebInputEvent::NoModifiers, |
| 509 ui::EventTimeStampToSeconds(ui::EventTimeForNow()), LatencyInfo()); | 496 ui::EventTimeStampToSeconds(ui::EventTimeForNow()), LatencyInfo()); |
| 510 touch.event.dispatchType = WebInputEvent::EventNonBlocking; | 497 touch.event.dispatchType = WebInputEvent::EventNonBlocking; |
| 511 | 498 |
| 512 auto it = touch_queue_.begin(); | 499 auto it = touch_queue_.begin(); |
| 513 DCHECK(it != touch_queue_.end()); | 500 DCHECK(it != touch_queue_.end()); |
| 514 touch_queue_.insert(++it, | 501 touch_queue_.insert(++it, |
| 515 base::MakeUnique<CoalescedWebTouchEvent>(touch, false)); | 502 base::MakeUnique<CoalescedWebTouchEvent>(touch, false)); |
| 516 } | 503 } |
| 517 } | 504 } |
| 518 | 505 |
| 519 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, | 506 void LegacyTouchEventQueue::ProcessTouchAck( |
| 520 const LatencyInfo& latency_info, | 507 InputEventAckState ack_result, |
| 521 const uint32_t unique_touch_event_id) { | 508 const LatencyInfo& latency_info, |
| 522 TRACE_EVENT0("input", "TouchEventQueue::ProcessTouchAck"); | 509 const uint32_t unique_touch_event_id) { |
| 510 TRACE_EVENT0("input", "LegacyTouchEventQueue::ProcessTouchAck"); | |
| 523 | 511 |
| 524 // We receive an ack for async touchmove from render. | 512 // We receive an ack for async touchmove from render. |
| 525 if (!ack_pending_async_touchmove_ids_.empty() && | 513 if (!ack_pending_async_touchmove_ids_.empty() && |
| 526 ack_pending_async_touchmove_ids_.front() == unique_touch_event_id) { | 514 ack_pending_async_touchmove_ids_.front() == unique_touch_event_id) { |
| 527 // Remove the first touchmove from the ack_pending_async_touchmove queue. | 515 // Remove the first touchmove from the ack_pending_async_touchmove queue. |
| 528 ack_pending_async_touchmove_ids_.pop_front(); | 516 ack_pending_async_touchmove_ids_.pop_front(); |
| 529 // Send the next pending async touch move once we receive all acks back. | 517 // Send the next pending async touch move once we receive all acks back. |
| 530 if (pending_async_touchmove_ && ack_pending_async_touchmove_ids_.empty()) { | 518 if (pending_async_touchmove_ && ack_pending_async_touchmove_ids_.empty()) { |
| 531 DCHECK(touch_queue_.empty()); | 519 DCHECK(touch_queue_.empty()); |
| 532 | 520 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 556 // when, for example, A is acked from renderer but B isn't, so the ack for B | 544 // when, for example, A is acked from renderer but B isn't, so the ack for B |
| 557 // is synthesized "locally" in InputRouter. | 545 // is synthesized "locally" in InputRouter. |
| 558 // | 546 // |
| 559 // TODO(crbug.com/600773): Bring the id checks back when dispatch triggering | 547 // TODO(crbug.com/600773): Bring the id checks back when dispatch triggering |
| 560 // is sane. | 548 // is sane. |
| 561 | 549 |
| 562 PopTouchEventToClient(ack_result, latency_info); | 550 PopTouchEventToClient(ack_result, latency_info); |
| 563 TryForwardNextEventToRenderer(); | 551 TryForwardNextEventToRenderer(); |
| 564 } | 552 } |
| 565 | 553 |
| 566 void TouchEventQueue::TryForwardNextEventToRenderer() { | 554 void LegacyTouchEventQueue::TryForwardNextEventToRenderer() { |
| 567 DCHECK(!dispatching_touch_ack_); | 555 DCHECK(!dispatching_touch_ack_); |
| 568 // If there are queued touch events, then try to forward them to the renderer | 556 // If there are queued touch events, then try to forward them to the renderer |
| 569 // immediately, or ACK the events back to the client if appropriate. | 557 // immediately, or ACK the events back to the client if appropriate. |
| 570 while (!touch_queue_.empty()) { | 558 while (!touch_queue_.empty()) { |
| 571 const WebTouchEvent& event = touch_queue_.front()->coalesced_event().event; | 559 const WebTouchEvent& event = touch_queue_.front()->coalesced_event().event; |
| 572 PreFilterResult filter_result = FilterBeforeForwarding(event); | 560 PreFilterResult filter_result = FilterBeforeForwarding(event); |
| 573 if (filter_result != FORWARD_TO_RENDERER) | 561 if (filter_result != FORWARD_TO_RENDERER) |
| 574 client_->OnFilteringTouchEvent(event); | 562 client_->OnFilteringTouchEvent(event); |
| 575 switch (filter_result) { | 563 switch (filter_result) { |
| 576 case ACK_WITH_NO_CONSUMER_EXISTS: | 564 case ACK_WITH_NO_CONSUMER_EXISTS: |
| 577 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); | 565 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); |
| 578 break; | 566 break; |
| 579 case ACK_WITH_NOT_CONSUMED: | 567 case ACK_WITH_NOT_CONSUMED: |
| 580 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 568 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); |
| 581 break; | 569 break; |
| 582 case FORWARD_TO_RENDERER: | 570 case FORWARD_TO_RENDERER: |
| 583 ForwardNextEventToRenderer(); | 571 ForwardNextEventToRenderer(); |
| 584 return; | 572 return; |
| 585 } | 573 } |
| 586 } | 574 } |
| 587 } | 575 } |
| 588 | 576 |
| 589 void TouchEventQueue::ForwardNextEventToRenderer() { | 577 void LegacyTouchEventQueue::ForwardNextEventToRenderer() { |
| 590 TRACE_EVENT0("input", "TouchEventQueue::ForwardNextEventToRenderer"); | 578 TRACE_EVENT0("input", "LegacyTouchEventQueue::ForwardNextEventToRenderer"); |
| 591 | 579 |
| 592 DCHECK(!empty()); | 580 DCHECK(!empty()); |
| 593 DCHECK(!dispatching_touch_); | 581 DCHECK(!dispatching_touch_); |
| 594 TouchEventWithLatencyInfo touch = touch_queue_.front()->coalesced_event(); | 582 TouchEventWithLatencyInfo touch = touch_queue_.front()->coalesced_event(); |
| 595 | 583 |
| 596 if (send_touch_events_async_ && | 584 if (send_touch_events_async_ && |
| 597 touch.event.type() == WebInputEvent::TouchMove) { | 585 touch.event.type() == WebInputEvent::TouchMove) { |
| 598 // Throttling touchmove's in a continuous touchmove stream while scrolling | 586 // Throttling touchmove's in a continuous touchmove stream while scrolling |
| 599 // reduces the risk of jank. However, it's still important that the web | 587 // reduces the risk of jank. However, it's still important that the web |
| 600 // application be sent touches at key points in the gesture stream, | 588 // application be sent touches at key points in the gesture stream, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 648 // Note: Touchstart events are marked cancelable to allow transitions between | 636 // Note: Touchstart events are marked cancelable to allow transitions between |
| 649 // platform scrolling and JS pinching. Touchend events, however, remain | 637 // platform scrolling and JS pinching. Touchend events, however, remain |
| 650 // uncancelable, mitigating the risk of jank when transitioning to a fling. | 638 // uncancelable, mitigating the risk of jank when transitioning to a fling. |
| 651 if (send_touch_events_async_ && | 639 if (send_touch_events_async_ && |
| 652 touch.event.type() != WebInputEvent::TouchStart) | 640 touch.event.type() != WebInputEvent::TouchStart) |
| 653 touch.event.dispatchType = WebInputEvent::EventNonBlocking; | 641 touch.event.dispatchType = WebInputEvent::EventNonBlocking; |
| 654 | 642 |
| 655 SendTouchEventImmediately(&touch); | 643 SendTouchEventImmediately(&touch); |
| 656 } | 644 } |
| 657 | 645 |
| 658 void TouchEventQueue::FlushPendingAsyncTouchmove() { | 646 void LegacyTouchEventQueue::FlushPendingAsyncTouchmove() { |
| 659 DCHECK(!dispatching_touch_); | 647 DCHECK(!dispatching_touch_); |
| 660 std::unique_ptr<TouchEventWithLatencyInfo> touch = | 648 std::unique_ptr<TouchEventWithLatencyInfo> touch = |
| 661 std::move(pending_async_touchmove_); | 649 std::move(pending_async_touchmove_); |
| 662 touch->event.dispatchType = WebInputEvent::EventNonBlocking; | 650 touch->event.dispatchType = WebInputEvent::EventNonBlocking; |
| 663 touch_queue_.push_front( | 651 touch_queue_.push_front( |
| 664 base::MakeUnique<CoalescedWebTouchEvent>(*touch, true)); | 652 base::MakeUnique<CoalescedWebTouchEvent>(*touch, true)); |
| 665 SendTouchEventImmediately(touch.get()); | 653 SendTouchEventImmediately(touch.get()); |
| 666 } | 654 } |
| 667 | 655 |
| 668 void TouchEventQueue::OnGestureScrollEvent( | 656 void LegacyTouchEventQueue::OnGestureScrollEvent( |
| 669 const GestureEventWithLatencyInfo& gesture_event) { | 657 const GestureEventWithLatencyInfo& gesture_event) { |
| 670 if (gesture_event.event.type() == blink::WebInputEvent::GestureScrollBegin) { | 658 if (gesture_event.event.type() == blink::WebInputEvent::GestureScrollBegin) { |
| 671 if (has_handler_for_current_sequence_ && | 659 if (has_handler_for_current_sequence_ && |
| 672 !drop_remaining_touches_in_sequence_) { | 660 !drop_remaining_touches_in_sequence_) { |
| 673 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) | 661 DCHECK(!touchmove_slop_suppressor_->suppressing_touchmoves()) |
| 674 << "A touch handler should be offered a touchmove before scrolling."; | 662 << "A touch handler should be offered a touchmove before scrolling."; |
| 675 } | 663 } |
| 676 | 664 |
| 677 pending_async_touchmove_.reset(); | 665 pending_async_touchmove_.reset(); |
| 678 | 666 |
| 679 return; | 667 return; |
| 680 } | 668 } |
| 681 | 669 |
| 682 if (gesture_event.event.type() == blink::WebInputEvent::GestureScrollUpdate && | 670 if (gesture_event.event.type() == blink::WebInputEvent::GestureScrollUpdate && |
| 683 gesture_event.event.resendingPluginId == -1) { | 671 gesture_event.event.resendingPluginId == -1) { |
| 684 send_touch_events_async_ = true; | 672 send_touch_events_async_ = true; |
| 685 } | 673 } |
| 686 } | 674 } |
| 687 | 675 |
| 688 void TouchEventQueue::OnGestureEventAck( | 676 void LegacyTouchEventQueue::OnGestureEventAck( |
| 689 const GestureEventWithLatencyInfo& event, | 677 const GestureEventWithLatencyInfo& event, |
| 690 InputEventAckState ack_result) { | 678 InputEventAckState ack_result) { |
| 691 // Throttle sending touchmove events as long as the scroll events are handled. | 679 // Throttle sending touchmove events as long as the scroll events are handled. |
| 692 // Note that there's no guarantee that this ACK is for the most recent | 680 // Note that there's no guarantee that this ACK is for the most recent |
| 693 // gesture event (or even part of the current sequence). Worst case, the | 681 // gesture event (or even part of the current sequence). Worst case, the |
| 694 // delay in updating the absorption state will result in minor UI glitches. | 682 // delay in updating the absorption state will result in minor UI glitches. |
| 695 // A valid |pending_async_touchmove_| will be flushed when the next event is | 683 // A valid |pending_async_touchmove_| will be flushed when the next event is |
| 696 // forwarded. Scroll updates that are being resent from a GuestView are | 684 // forwarded. Scroll updates that are being resent from a GuestView are |
| 697 // ignored. | 685 // ignored. |
| 698 if (event.event.type() == blink::WebInputEvent::GestureScrollUpdate && | 686 if (event.event.type() == blink::WebInputEvent::GestureScrollUpdate && |
| 699 event.event.resendingPluginId == -1) { | 687 event.event.resendingPluginId == -1) { |
| 700 send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED); | 688 send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED); |
| 701 } | 689 } |
| 702 } | 690 } |
| 703 | 691 |
| 704 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { | 692 void LegacyTouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { |
| 705 DCHECK(!dispatching_touch_ack_); | 693 DCHECK(!dispatching_touch_ack_); |
| 706 DCHECK(!dispatching_touch_); | 694 DCHECK(!dispatching_touch_); |
| 707 has_handlers_ = has_handlers; | 695 has_handlers_ = has_handlers; |
| 708 } | 696 } |
| 709 | 697 |
| 710 bool TouchEventQueue::IsPendingAckTouchStart() const { | 698 bool LegacyTouchEventQueue::IsPendingAckTouchStart() const { |
| 711 DCHECK(!dispatching_touch_ack_); | 699 DCHECK(!dispatching_touch_ack_); |
| 712 if (touch_queue_.empty()) | 700 if (touch_queue_.empty()) |
| 713 return false; | 701 return false; |
| 714 | 702 |
| 715 const blink::WebTouchEvent& event = | 703 const blink::WebTouchEvent& event = |
| 716 touch_queue_.front()->coalesced_event().event; | 704 touch_queue_.front()->coalesced_event().event; |
| 717 return (event.type() == WebInputEvent::TouchStart); | 705 return (event.type() == WebInputEvent::TouchStart); |
| 718 } | 706 } |
| 719 | 707 |
| 720 void TouchEventQueue::SetAckTimeoutEnabled(bool enabled) { | 708 void LegacyTouchEventQueue::SetAckTimeoutEnabled(bool enabled) { |
| 721 if (timeout_handler_) | 709 if (timeout_handler_) |
| 722 timeout_handler_->SetEnabled(enabled); | 710 timeout_handler_->SetEnabled(enabled); |
| 723 } | 711 } |
| 724 | 712 |
| 725 void TouchEventQueue::SetIsMobileOptimizedSite(bool mobile_optimized_site) { | 713 void LegacyTouchEventQueue::SetIsMobileOptimizedSite( |
| 714 bool mobile_optimized_site) { | |
| 726 if (timeout_handler_) | 715 if (timeout_handler_) |
| 727 timeout_handler_->SetUseMobileTimeout(mobile_optimized_site); | 716 timeout_handler_->SetUseMobileTimeout(mobile_optimized_site); |
| 728 } | 717 } |
| 729 | 718 |
| 730 bool TouchEventQueue::IsAckTimeoutEnabled() const { | 719 bool LegacyTouchEventQueue::IsAckTimeoutEnabled() const { |
| 731 return timeout_handler_ && timeout_handler_->IsEnabled(); | 720 return timeout_handler_ && timeout_handler_->IsEnabled(); |
| 732 } | 721 } |
| 733 | 722 |
| 734 bool TouchEventQueue::HasPendingAsyncTouchMoveForTesting() const { | 723 bool LegacyTouchEventQueue::Empty() const { |
| 724 return touch_queue_.empty(); | |
| 725 } | |
| 726 | |
| 727 bool LegacyTouchEventQueue::HasPendingAsyncTouchMoveForTesting() const { | |
| 735 return !!pending_async_touchmove_; | 728 return !!pending_async_touchmove_; |
| 736 } | 729 } |
| 737 | 730 |
| 738 bool TouchEventQueue::IsTimeoutRunningForTesting() const { | 731 bool LegacyTouchEventQueue::IsTimeoutRunningForTesting() const { |
| 739 return timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning(); | 732 return timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning(); |
| 740 } | 733 } |
| 741 | 734 |
| 742 const TouchEventWithLatencyInfo& | 735 const TouchEventWithLatencyInfo& |
| 743 TouchEventQueue::GetLatestEventForTesting() const { | 736 LegacyTouchEventQueue::GetLatestEventForTesting() const { |
| 744 return touch_queue_.back()->coalesced_event(); | 737 return touch_queue_.back()->coalesced_event(); |
| 745 } | 738 } |
| 746 | 739 |
| 747 void TouchEventQueue::FlushQueue() { | 740 void LegacyTouchEventQueue::FlushQueue() { |
| 748 DCHECK(!dispatching_touch_ack_); | 741 DCHECK(!dispatching_touch_ack_); |
| 749 DCHECK(!dispatching_touch_); | 742 DCHECK(!dispatching_touch_); |
| 750 pending_async_touchmove_.reset(); | 743 pending_async_touchmove_.reset(); |
| 751 drop_remaining_touches_in_sequence_ = true; | 744 drop_remaining_touches_in_sequence_ = true; |
| 752 while (!touch_queue_.empty()) | 745 while (!touch_queue_.empty()) |
| 753 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); | 746 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); |
| 754 } | 747 } |
| 755 | 748 |
| 756 void TouchEventQueue::PopTouchEventToClient(InputEventAckState ack_result) { | 749 void LegacyTouchEventQueue::PopTouchEventToClient( |
| 750 InputEventAckState ack_result) { | |
| 757 AckTouchEventToClient(ack_result, nullptr); | 751 AckTouchEventToClient(ack_result, nullptr); |
| 758 } | 752 } |
| 759 | 753 |
| 760 void TouchEventQueue::PopTouchEventToClient( | 754 void LegacyTouchEventQueue::PopTouchEventToClient( |
| 761 InputEventAckState ack_result, | 755 InputEventAckState ack_result, |
| 762 const LatencyInfo& renderer_latency_info) { | 756 const LatencyInfo& renderer_latency_info) { |
| 763 AckTouchEventToClient(ack_result, &renderer_latency_info); | 757 AckTouchEventToClient(ack_result, &renderer_latency_info); |
| 764 } | 758 } |
| 765 | 759 |
| 766 void TouchEventQueue::AckTouchEventToClient( | 760 void LegacyTouchEventQueue::AckTouchEventToClient( |
| 767 InputEventAckState ack_result, | 761 InputEventAckState ack_result, |
| 768 const ui::LatencyInfo* optional_latency_info) { | 762 const ui::LatencyInfo* optional_latency_info) { |
| 769 DCHECK(!dispatching_touch_ack_); | 763 DCHECK(!dispatching_touch_ack_); |
| 770 if (touch_queue_.empty()) { | 764 if (touch_queue_.empty()) { |
| 771 NOTREACHED() << "Too many acks"; | 765 NOTREACHED() << "Too many acks"; |
| 772 return; | 766 return; |
| 773 } | 767 } |
| 774 std::unique_ptr<CoalescedWebTouchEvent> acked_event = | 768 std::unique_ptr<CoalescedWebTouchEvent> acked_event = |
| 775 std::move(touch_queue_.front()); | 769 std::move(touch_queue_.front()); |
| 776 DCHECK(acked_event); | 770 DCHECK(acked_event); |
| 777 | 771 |
| 778 UpdateTouchConsumerStates(acked_event->coalesced_event().event, ack_result); | 772 UpdateTouchConsumerStates(acked_event->coalesced_event().event, ack_result); |
| 779 | 773 |
| 780 // Note that acking the touch-event may result in multiple gestures being sent | 774 // Note that acking the touch-event may result in multiple gestures being sent |
| 781 // to the renderer, or touch-events being queued. | 775 // to the renderer, or touch-events being queued. |
| 782 base::AutoReset<bool> dispatching_touch_ack(&dispatching_touch_ack_, true); | 776 base::AutoReset<bool> dispatching_touch_ack(&dispatching_touch_ack_, true); |
| 783 | 777 |
| 784 // Skip ack for TouchScrollStarted since it was synthesized within the queue. | 778 // Skip ack for TouchScrollStarted since it was synthesized within the queue. |
| 785 if (acked_event->coalesced_event().event.type() != | 779 if (acked_event->coalesced_event().event.type() != |
| 786 WebInputEvent::TouchScrollStarted) { | 780 WebInputEvent::TouchScrollStarted) { |
| 787 acked_event->DispatchAckToClient(ack_result, optional_latency_info, | 781 acked_event->DispatchAckToClient(ack_result, optional_latency_info, |
| 788 client_); | 782 client_); |
| 789 } | 783 } |
| 790 | 784 |
| 791 touch_queue_.pop_front(); | 785 touch_queue_.pop_front(); |
| 792 } | 786 } |
| 793 | 787 |
| 794 void TouchEventQueue::SendTouchEventImmediately( | 788 void LegacyTouchEventQueue::SendTouchEventImmediately( |
| 795 TouchEventWithLatencyInfo* touch) { | 789 TouchEventWithLatencyInfo* touch) { |
| 796 // TODO(crbug.com/600773): Hack to avoid cyclic reentry to this method. | 790 // TODO(crbug.com/600773): Hack to avoid cyclic reentry to this method. |
| 797 if (dispatching_touch_) | 791 if (dispatching_touch_) |
| 798 return; | 792 return; |
| 799 | 793 |
| 800 if (touch->event.type() == WebInputEvent::TouchStart) | 794 if (touch->event.type() == WebInputEvent::TouchStart) |
| 801 touch->event.touchStartOrFirstTouchMove = true; | 795 touch->event.touchStartOrFirstTouchMove = true; |
| 802 | 796 |
| 803 // For touchmove events, compare touch points position from current event | 797 // For touchmove events, compare touch points position from current event |
| 804 // to last sent event and update touch points state. | 798 // to last sent event and update touch points state. |
| 805 if (touch->event.type() == WebInputEvent::TouchMove) { | 799 if (touch->event.type() == WebInputEvent::TouchMove) { |
| 806 CHECK(last_sent_touchevent_); | 800 CHECK(last_sent_touchevent_); |
| 807 if (last_sent_touchevent_->type() == WebInputEvent::TouchStart) | 801 if (last_sent_touchevent_->type() == WebInputEvent::TouchStart) |
| 808 touch->event.touchStartOrFirstTouchMove = true; | 802 touch->event.touchStartOrFirstTouchMove = true; |
| 809 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) { | 803 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) { |
| 810 const WebTouchPoint& last_touch_point = | 804 const WebTouchPoint& last_touch_point = last_sent_touchevent_->touches[i]; |
| 811 last_sent_touchevent_->touches[i]; | |
| 812 // Touches with same id may not have same index in Touches array. | 805 // Touches with same id may not have same index in Touches array. |
| 813 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) { | 806 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) { |
| 814 const WebTouchPoint& current_touchmove_point = touch->event.touches[j]; | 807 const WebTouchPoint& current_touchmove_point = touch->event.touches[j]; |
| 815 if (current_touchmove_point.id != last_touch_point.id) | 808 if (current_touchmove_point.id != last_touch_point.id) |
| 816 continue; | 809 continue; |
| 817 | 810 |
| 818 if (!HasPointChanged(last_touch_point, current_touchmove_point)) | 811 if (!HasPointChanged(last_touch_point, current_touchmove_point)) |
| 819 touch->event.touches[j].state = WebTouchPoint::StateStationary; | 812 touch->event.touches[j].state = WebTouchPoint::StateStationary; |
| 820 | 813 |
| 821 break; | 814 break; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 849 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_IGNORED); | 842 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_IGNORED); |
| 850 TryForwardNextEventToRenderer(); | 843 TryForwardNextEventToRenderer(); |
| 851 return; | 844 return; |
| 852 } | 845 } |
| 853 | 846 |
| 854 if (timeout_handler_) | 847 if (timeout_handler_) |
| 855 timeout_handler_->StartIfNecessary(*touch); | 848 timeout_handler_->StartIfNecessary(*touch); |
| 856 } | 849 } |
| 857 } | 850 } |
| 858 | 851 |
| 859 TouchEventQueue::PreFilterResult | 852 LegacyTouchEventQueue::PreFilterResult |
| 860 TouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { | 853 LegacyTouchEventQueue::FilterBeforeForwarding(const WebTouchEvent& event) { |
| 861 if (event.type() == WebInputEvent::TouchScrollStarted) | 854 if (event.type() == WebInputEvent::TouchScrollStarted) |
| 862 return FORWARD_TO_RENDERER; | 855 return FORWARD_TO_RENDERER; |
| 863 | 856 |
| 864 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { | 857 if (WebTouchEventTraits::IsTouchSequenceStart(event)) { |
| 865 has_handler_for_current_sequence_ = false; | 858 has_handler_for_current_sequence_ = false; |
| 866 send_touch_events_async_ = false; | 859 send_touch_events_async_ = false; |
| 867 pending_async_touchmove_.reset(); | 860 pending_async_touchmove_.reset(); |
| 868 last_sent_touchevent_.reset(); | 861 last_sent_touchevent_.reset(); |
| 869 | 862 |
| 870 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); | 863 touch_sequence_start_position_ = gfx::PointF(event.touches[0].position); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 916 // even though none of the pointers have not changed in real. | 909 // even though none of the pointers have not changed in real. |
| 917 // Forward these events when at least one pointer has changed. | 910 // Forward these events when at least one pointer has changed. |
| 918 if (HasPointChanged(last_sent_touchevent_->touches[j], point)) | 911 if (HasPointChanged(last_sent_touchevent_->touches[j], point)) |
| 919 return FORWARD_TO_RENDERER; | 912 return FORWARD_TO_RENDERER; |
| 920 | 913 |
| 921 // This is a TouchMove event for which we have yet to find a | 914 // This is a TouchMove event for which we have yet to find a |
| 922 // non-stationary pointer. Continue checking the next pointers | 915 // non-stationary pointer. Continue checking the next pointers |
| 923 // in the |event|. | 916 // in the |event|. |
| 924 break; | 917 break; |
| 925 } | 918 } |
| 926 | |
| 927 } | 919 } |
| 928 } | 920 } |
| 929 | 921 |
| 930 return ACK_WITH_NO_CONSUMER_EXISTS; | 922 return ACK_WITH_NO_CONSUMER_EXISTS; |
| 931 } | 923 } |
| 932 | 924 |
| 933 void TouchEventQueue::UpdateTouchConsumerStates(const WebTouchEvent& event, | 925 void LegacyTouchEventQueue::UpdateTouchConsumerStates( |
| 934 InputEventAckState ack_result) { | 926 const WebTouchEvent& event, |
| 927 InputEventAckState ack_result) { | |
| 935 if (event.type() == WebInputEvent::TouchStart) { | 928 if (event.type() == WebInputEvent::TouchStart) { |
| 936 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) | 929 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) |
| 937 send_touch_events_async_ = false; | 930 send_touch_events_async_ = false; |
| 938 has_handler_for_current_sequence_ |= | 931 has_handler_for_current_sequence_ |= |
| 939 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; | 932 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; |
| 940 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { | 933 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { |
| 941 has_handler_for_current_sequence_ = false; | 934 has_handler_for_current_sequence_ = false; |
| 942 } | 935 } |
| 943 } | 936 } |
| 944 | 937 |
| 945 } // namespace content | 938 } // namespace content |
| OLD | NEW |