Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(304)

Side by Side Diff: content/browser/renderer_host/input/touch_event_queue.cc

Issue 130993003: Prevent partial touch sequences from reaching the renderer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Name cleanup Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/touch_event_queue.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 15 matching lines...) Expand all
26 26
27 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( 27 TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent(
28 const TouchEventWithLatencyInfo& event_to_cancel) { 28 const TouchEventWithLatencyInfo& event_to_cancel) {
29 TouchEventWithLatencyInfo event = event_to_cancel; 29 TouchEventWithLatencyInfo event = event_to_cancel;
30 event.event.type = WebInputEvent::TouchCancel; 30 event.event.type = WebInputEvent::TouchCancel;
31 for (size_t i = 0; i < event.event.touchesLength; i++) 31 for (size_t i = 0; i < event.event.touchesLength; i++)
32 event.event.touches[i].state = WebTouchPoint::StateCancelled; 32 event.event.touches[i].state = WebTouchPoint::StateCancelled;
33 return event; 33 return event;
34 } 34 }
35 35
36 bool IsNewTouchGesture(const WebTouchEvent& event) { 36 bool IsNewTouchSequence(const WebTouchEvent& event) {
37 if (event.type != WebInputEvent::TouchStart) 37 if (event.type != WebInputEvent::TouchStart)
38 return false; 38 return false;
39 if (!event.touchesLength) 39 if (!event.touchesLength)
40 return false; 40 return false;
41 for (size_t i = 0; i < event.touchesLength; i++) { 41 for (size_t i = 0; i < event.touchesLength; i++) {
42 if (event.touches[i].state != WebTouchPoint::StatePressed) 42 if (event.touches[i].state != WebTouchPoint::StatePressed)
43 return false; 43 return false;
44 } 44 }
45 return true; 45 return true;
46 } 46 }
(...skipping 26 matching lines...) Expand all
73 bool ConfirmTouchEvent(InputEventAckState ack_result) { 73 bool ConfirmTouchEvent(InputEventAckState ack_result) {
74 switch (pending_ack_state_) { 74 switch (pending_ack_state_) {
75 case PENDING_ACK_NONE: 75 case PENDING_ACK_NONE:
76 timeout_monitor_.Stop(); 76 timeout_monitor_.Stop();
77 return false; 77 return false;
78 case PENDING_ACK_ORIGINAL_EVENT: 78 case PENDING_ACK_ORIGINAL_EVENT:
79 if (AckedTimeoutEventRequiresCancel(ack_result)) { 79 if (AckedTimeoutEventRequiresCancel(ack_result)) {
80 SetPendingAckState(PENDING_ACK_CANCEL_EVENT); 80 SetPendingAckState(PENDING_ACK_CANCEL_EVENT);
81 TouchEventWithLatencyInfo cancel_event = 81 TouchEventWithLatencyInfo cancel_event =
82 ObtainCancelEventForTouchEvent(timeout_event_); 82 ObtainCancelEventForTouchEvent(timeout_event_);
83 touch_queue_->UpdateTouchAckStates(
84 cancel_event.event, kDefaultNotForwardedAck);
85 touch_queue_->client_->SendTouchEventImmediately(cancel_event); 83 touch_queue_->client_->SendTouchEventImmediately(cancel_event);
86 } else { 84 } else {
87 SetPendingAckState(PENDING_ACK_NONE); 85 SetPendingAckState(PENDING_ACK_NONE);
88 touch_queue_->UpdateTouchAckStates(timeout_event_.event, ack_result); 86 touch_queue_->UpdateTouchAckStates(timeout_event_.event, ack_result);
89 } 87 }
90 return true; 88 return true;
91 case PENDING_ACK_CANCEL_EVENT: 89 case PENDING_ACK_CANCEL_EVENT:
92 SetPendingAckState(PENDING_ACK_NONE); 90 SetPendingAckState(PENDING_ACK_NONE);
93 return true; 91 return true;
94 } 92 }
(...skipping 24 matching lines...) Expand all
119 SetPendingAckState(PENDING_ACK_ORIGINAL_EVENT); 117 SetPendingAckState(PENDING_ACK_ORIGINAL_EVENT);
120 touch_queue_->FlushQueue(); 118 touch_queue_->FlushQueue();
121 } 119 }
122 120
123 // Skip a cancel event if the timed-out event had no consumer and was the 121 // Skip a cancel event if the timed-out event had no consumer and was the
124 // initial event in the gesture. 122 // initial event in the gesture.
125 bool AckedTimeoutEventRequiresCancel(InputEventAckState ack_result) const { 123 bool AckedTimeoutEventRequiresCancel(InputEventAckState ack_result) const {
126 DCHECK(HasTimeoutEvent()); 124 DCHECK(HasTimeoutEvent());
127 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) 125 if (ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS)
128 return true; 126 return true;
129 return !IsNewTouchGesture(timeout_event_.event); 127 return !IsNewTouchSequence(timeout_event_.event);
130 } 128 }
131 129
132 void SetPendingAckState(PendingAckState new_pending_ack_state) { 130 void SetPendingAckState(PendingAckState new_pending_ack_state) {
133 DCHECK_NE(pending_ack_state_, new_pending_ack_state); 131 DCHECK_NE(pending_ack_state_, new_pending_ack_state);
134 switch (new_pending_ack_state) { 132 switch (new_pending_ack_state) {
135 case PENDING_ACK_ORIGINAL_EVENT: 133 case PENDING_ACK_ORIGINAL_EVENT:
136 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE); 134 DCHECK_EQ(pending_ack_state_, PENDING_ACK_NONE);
137 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this); 135 TRACE_EVENT_ASYNC_BEGIN0("input", "TouchEventTimeout", this);
138 break; 136 break;
139 case PENDING_ACK_CANCEL_EVENT: 137 case PENDING_ACK_CANCEL_EVENT:
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 // when the event is acked. 232 // when the event is acked.
235 bool ignore_ack_; 233 bool ignore_ack_;
236 234
237 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent); 235 DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent);
238 }; 236 };
239 237
240 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client) 238 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client)
241 : client_(client), 239 : client_(client),
242 dispatching_touch_ack_(NULL), 240 dispatching_touch_ack_(NULL),
243 dispatching_touch_(false), 241 dispatching_touch_(false),
244 has_handlers_(false), 242 touch_filtering_state_(TOUCH_FILTERING_STATE_DEFAULT),
245 scroll_in_progress_(false),
246 renderer_is_consuming_touch_gesture_(false),
247 ack_timeout_enabled_(false) { 243 ack_timeout_enabled_(false) {
248 DCHECK(client); 244 DCHECK(client);
249 } 245 }
250 246
251 TouchEventQueue::~TouchEventQueue() { 247 TouchEventQueue::~TouchEventQueue() {
252 if (!touch_queue_.empty()) 248 if (!touch_queue_.empty())
253 STLDeleteElements(&touch_queue_); 249 STLDeleteElements(&touch_queue_);
254 } 250 }
255 251
256 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { 252 void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
257 // Optimization of the case without touch handlers. Removing this path
258 // yields identical results, but this avoids unnecessary allocations.
259 if (!has_handlers_) {
260 DCHECK(touch_queue_.empty());
261 client_->OnTouchEventAck(event, kDefaultNotForwardedAck);
262 return;
263 }
264
265 // If the queueing of |event| was triggered by an ack dispatch, defer 253 // If the queueing of |event| was triggered by an ack dispatch, defer
266 // processing the event until the dispatch has finished. 254 // processing the event until the dispatch has finished.
267 if (touch_queue_.empty() && !dispatching_touch_ack_) { 255 if (touch_queue_.empty() && !dispatching_touch_ack_) {
256 // Optimization of the case without touch handlers. Removing this path
257 // yields identical results, but this avoids unnecessary allocations.
258 if (touch_filtering_state_ == DROP_ALL_TOUCHES ||
259 (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE &&
260 !IsNewTouchSequence(event.event))) {
261 client_->OnTouchEventAck(event, kDefaultNotForwardedAck);
262 return;
263 }
264
268 // There is no touch event in the queue. Forward it to the renderer 265 // There is no touch event in the queue. Forward it to the renderer
269 // immediately. 266 // immediately.
270 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); 267 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false));
271 TryForwardNextEventToRenderer(); 268 TryForwardNextEventToRenderer();
272 return; 269 return;
273 } 270 }
274 271
275 // If the last queued touch-event was a touch-move, and the current event is 272 // If the last queued touch-event was a touch-move, and the current event is
276 // also a touch-move, then the events can be coalesced into a single event. 273 // also a touch-move, then the events can be coalesced into a single event.
277 if (touch_queue_.size() > 1) { 274 if (touch_queue_.size() > 1) {
278 CoalescedWebTouchEvent* last_event = touch_queue_.back(); 275 CoalescedWebTouchEvent* last_event = touch_queue_.back();
279 if (last_event->CoalesceEventIfPossible(event)) 276 if (last_event->CoalesceEventIfPossible(event))
280 return; 277 return;
281 } 278 }
282 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false)); 279 touch_queue_.push_back(new CoalescedWebTouchEvent(event, false));
283 } 280 }
284 281
285 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result, 282 void TouchEventQueue::ProcessTouchAck(InputEventAckState ack_result,
286 const ui::LatencyInfo& latency_info) { 283 const ui::LatencyInfo& latency_info) {
287 DCHECK(!dispatching_touch_ack_); 284 DCHECK(!dispatching_touch_ack_);
288 dispatching_touch_ = false; 285 dispatching_touch_ = false;
289 286
290 if (timeout_handler_ && timeout_handler_->ConfirmTouchEvent(ack_result)) 287 if (timeout_handler_ && timeout_handler_->ConfirmTouchEvent(ack_result))
291 return; 288 return;
292 289
293 if (touch_queue_.empty()) 290 if (touch_queue_.empty())
294 return; 291 return;
295 292
296 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) 293 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED &&
297 renderer_is_consuming_touch_gesture_ = true; 294 touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT)
295 touch_filtering_state_ = FORWARD_ALL_TOUCHES;
298 296
299 const WebTouchEvent& acked_event = 297 const WebTouchEvent& acked_event =
300 touch_queue_.front()->coalesced_event().event; 298 touch_queue_.front()->coalesced_event().event;
301 UpdateTouchAckStates(acked_event, ack_result); 299 UpdateTouchAckStates(acked_event, ack_result);
302 PopTouchEventToClient(ack_result, latency_info); 300 PopTouchEventToClient(ack_result, latency_info);
303 TryForwardNextEventToRenderer(); 301 TryForwardNextEventToRenderer();
304 } 302 }
305 303
306 void TouchEventQueue::TryForwardNextEventToRenderer() { 304 void TouchEventQueue::TryForwardNextEventToRenderer() {
307 DCHECK(!dispatching_touch_ack_); 305 DCHECK(!dispatching_touch_ack_);
308 // If there are queued touch events, then try to forward them to the renderer 306 // If there are queued touch events, then try to forward them to the renderer
309 // immediately, or ACK the events back to the client if appropriate. 307 // immediately, or ACK the events back to the client if appropriate.
310 while (!touch_queue_.empty()) { 308 while (!touch_queue_.empty()) {
311 const TouchEventWithLatencyInfo& touch = 309 const TouchEventWithLatencyInfo& touch =
312 touch_queue_.front()->coalesced_event(); 310 touch_queue_.front()->coalesced_event();
313 if (IsNewTouchGesture(touch.event)) {
314 touch_ack_states_.clear();
315 renderer_is_consuming_touch_gesture_ = false;
316 }
317 if (ShouldForwardToRenderer(touch.event)) { 311 if (ShouldForwardToRenderer(touch.event)) {
318 ForwardToRenderer(touch); 312 ForwardToRenderer(touch);
319 break; 313 break;
320 } 314 }
321 PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo()); 315 PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo());
322 } 316 }
323 } 317 }
324 318
325 void TouchEventQueue::ForwardToRenderer( 319 void TouchEventQueue::ForwardToRenderer(
326 const TouchEventWithLatencyInfo& touch) { 320 const TouchEventWithLatencyInfo& touch) {
327 DCHECK(!dispatching_touch_); 321 DCHECK(!dispatching_touch_);
322 DCHECK_NE(touch_filtering_state_, DROP_ALL_TOUCHES);
323
324 if (IsNewTouchSequence(touch.event)) {
325 touch_filtering_state_ =
326 ack_timeout_enabled_ ? FORWARD_TOUCHES_UNTIL_TIMEOUT
327 : FORWARD_ALL_TOUCHES;
328 touch_ack_states_.clear();
329 }
330
328 // A synchronous ack will reset |dispatching_touch_|, in which case 331 // A synchronous ack will reset |dispatching_touch_|, in which case
329 // the touch timeout should not be started. 332 // the touch timeout should not be started.
330 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true); 333 base::AutoReset<bool> dispatching_touch(&dispatching_touch_, true);
331 client_->SendTouchEventImmediately(touch); 334 client_->SendTouchEventImmediately(touch);
332 if (ack_timeout_enabled_ && 335 if (dispatching_touch_ &&
333 dispatching_touch_ && 336 touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT &&
334 !renderer_is_consuming_touch_gesture_ &&
335 ShouldTouchTypeTriggerTimeout(touch.event.type)) { 337 ShouldTouchTypeTriggerTimeout(touch.event.type)) {
336 DCHECK(timeout_handler_); 338 DCHECK(timeout_handler_);
337 timeout_handler_->Start(touch); 339 timeout_handler_->Start(touch);
338 } 340 }
339 } 341 }
340 342
341 void TouchEventQueue::OnGestureScrollEvent( 343 void TouchEventQueue::OnGestureScrollEvent(
342 const GestureEventWithLatencyInfo& gesture_event) { 344 const GestureEventWithLatencyInfo& gesture_event) {
343 blink::WebInputEvent::Type type = gesture_event.event.type; 345 if (gesture_event.event.type != blink::WebInputEvent::GestureScrollBegin)
344 if (type == blink::WebInputEvent::GestureScrollBegin) { 346 return;
345 // We assume the scroll event are generated synchronously from
346 // dispatching a touch event ack, so that we can fake a cancel
347 // event that has the correct touch ids as the touch event that
348 // is being acked. If not, we don't do the touch-cancel optimization.
349 if (scroll_in_progress_ || !dispatching_touch_ack_)
350 return;
351 scroll_in_progress_ = true;
352 347
353 // If we have a timeout event, a cancel has already been dispatched 348 // We assume that scroll events are generated synchronously from
354 // for the current touch stream. 349 // dispatching a touch event ack. This allows us to generate a synthetic
355 if (HasTimeoutEvent()) 350 // cancel event that has the same touch ids as the touch event that
356 return; 351 // is being acked. Otherwise, we don't perform the touch-cancel optimization.
352 if (!dispatching_touch_ack_)
353 return;
357 354
358 // Fake a TouchCancel to cancel the touch points of the touch event 355 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE)
359 // that is currently being acked. 356 return;
360 // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we 357
361 // are in the scope of PopTouchEventToClient() and that no touch event 358 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
362 // in the queue is waiting for ack from renderer. So we can just insert 359
363 // the touch cancel at the beginning of the queue. 360 // Fake a TouchCancel to cancel the touch points of the touch event
364 touch_queue_.push_front(new CoalescedWebTouchEvent( 361 // that is currently being acked.
365 ObtainCancelEventForTouchEvent( 362 // Note: |dispatching_touch_ack_| is non-null when we reach here, meaning we
366 dispatching_touch_ack_->coalesced_event()), true)); 363 // are in the scope of PopTouchEventToClient() and that no touch event
367 } else if (type == blink::WebInputEvent::GestureScrollEnd || 364 // in the queue is waiting for ack from renderer. So we can just insert
368 type == blink::WebInputEvent::GestureFlingStart) { 365 // the touch cancel at the beginning of the queue.
369 scroll_in_progress_ = false; 366 touch_queue_.push_front(new CoalescedWebTouchEvent(
370 } 367 ObtainCancelEventForTouchEvent(
368 dispatching_touch_ack_->coalesced_event()), true));
371 } 369 }
372 370
373 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) { 371 void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) {
374 DCHECK(!dispatching_touch_ack_); 372 DCHECK(!dispatching_touch_ack_);
375 DCHECK(!dispatching_touch_); 373 DCHECK(!dispatching_touch_);
376 if (has_handlers_ == has_handlers)
377 return;
378 374
379 has_handlers_ = has_handlers; 375 if (has_handlers) {
380 376 if (touch_filtering_state_ == DROP_ALL_TOUCHES) {
381 if (!has_handlers_) { 377 // If no touch handler was previously registered, ensure that we don't
382 // TODO(jdduke): Synthesize a TouchCancel if necessary to update Blink touch 378 // send a partial touch sequence to the renderer.
383 // state tracking. 379 DCHECK(touch_queue_.empty());
380 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
381 }
382 } else {
383 touch_filtering_state_ = DROP_ALL_TOUCHES;
Rick Byers 2014/01/23 18:40:14 I had to think about this for a minute to convince
jdduke (slow) 2014/01/24 05:29:22 Ahh, I actually never intended to remove that TODO
384 if (timeout_handler_) 384 if (timeout_handler_)
385 timeout_handler_->Reset(); 385 timeout_handler_->Reset();
386 if (!touch_queue_.empty()) 386 if (!touch_queue_.empty())
387 ProcessTouchAck(kDefaultNotForwardedAck, ui::LatencyInfo()); 387 ProcessTouchAck(kDefaultNotForwardedAck, ui::LatencyInfo());
388 // As there is no touch handler, ack'ing the event should flush the queue. 388 // As there is no touch handler, ack'ing the event should flush the queue.
389 DCHECK(touch_queue_.empty()); 389 DCHECK(touch_queue_.empty());
390 } else {
391 DCHECK(touch_queue_.empty());
392 // Prevent a partial sequence from being sent to the renderer.
393 TouchPointAckStates::iterator ack_it = touch_ack_states_.begin();
394 for (; ack_it != touch_ack_states_.end(); ++ack_it)
395 ack_it->second = kDefaultNotForwardedAck;
396 } 390 }
397 } 391 }
398 392
399 bool TouchEventQueue::IsPendingAckTouchStart() const { 393 bool TouchEventQueue::IsPendingAckTouchStart() const {
400 DCHECK(!dispatching_touch_ack_); 394 DCHECK(!dispatching_touch_ack_);
401 if (touch_queue_.empty()) 395 if (touch_queue_.empty())
402 return false; 396 return false;
403 397
404 const blink::WebTouchEvent& event = 398 const blink::WebTouchEvent& event =
405 touch_queue_.front()->coalesced_event().event; 399 touch_queue_.front()->coalesced_event().event;
(...skipping 23 matching lines...) Expand all
429 } 423 }
430 424
431 const TouchEventWithLatencyInfo& 425 const TouchEventWithLatencyInfo&
432 TouchEventQueue::GetLatestEventForTesting() const { 426 TouchEventQueue::GetLatestEventForTesting() const {
433 return touch_queue_.back()->coalesced_event(); 427 return touch_queue_.back()->coalesced_event();
434 } 428 }
435 429
436 void TouchEventQueue::FlushQueue() { 430 void TouchEventQueue::FlushQueue() {
437 DCHECK(!dispatching_touch_ack_); 431 DCHECK(!dispatching_touch_ack_);
438 DCHECK(!dispatching_touch_); 432 DCHECK(!dispatching_touch_);
433 if (touch_filtering_state_ != DROP_ALL_TOUCHES)
434 touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
439 while (!touch_queue_.empty()) 435 while (!touch_queue_.empty())
440 PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo()); 436 PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo());
441 } 437 }
442 438
443 void TouchEventQueue::PopTouchEventToClient( 439 void TouchEventQueue::PopTouchEventToClient(
444 InputEventAckState ack_result, 440 InputEventAckState ack_result,
445 const ui::LatencyInfo& renderer_latency_info) { 441 const ui::LatencyInfo& renderer_latency_info) {
446 DCHECK(!dispatching_touch_ack_); 442 DCHECK(!dispatching_touch_ack_);
447 if (touch_queue_.empty()) 443 if (touch_queue_.empty())
448 return; 444 return;
(...skipping 14 matching lines...) Expand all
463 iter->latency.AddNewLatencyFrom(renderer_latency_info); 459 iter->latency.AddNewLatencyFrom(renderer_latency_info);
464 client_->OnTouchEventAck((*iter), ack_result); 460 client_->OnTouchEventAck((*iter), ack_result);
465 } 461 }
466 } 462 }
467 463
468 bool TouchEventQueue::ShouldForwardToRenderer( 464 bool TouchEventQueue::ShouldForwardToRenderer(
469 const WebTouchEvent& event) const { 465 const WebTouchEvent& event) const {
470 if (HasTimeoutEvent()) 466 if (HasTimeoutEvent())
471 return false; 467 return false;
472 468
473 if (!has_handlers_) 469 if (touch_filtering_state_ == DROP_ALL_TOUCHES)
474 return false; 470 return false;
475 471
476 if (scroll_in_progress_ && 472 if (touch_filtering_state_ == DROP_TOUCHES_IN_SEQUENCE &&
477 event.type != blink::WebInputEvent::TouchCancel) 473 event.type != WebInputEvent::TouchCancel) {
474 if (IsNewTouchSequence(event))
475 return true;
478 return false; 476 return false;
477 }
479 478
480 // Touch press events should always be forwarded to the renderer. 479 // Touch press events should always be forwarded to the renderer.
481 if (event.type == WebInputEvent::TouchStart) 480 if (event.type == WebInputEvent::TouchStart)
482 return true; 481 return true;
483 482
484 for (unsigned int i = 0; i < event.touchesLength; ++i) { 483 for (unsigned int i = 0; i < event.touchesLength; ++i) {
485 const WebTouchPoint& point = event.touches[i]; 484 const WebTouchPoint& point = event.touches[i];
486 // If a point has been stationary, then don't take it into account. 485 // If a point has been stationary, then don't take it into account.
487 if (point.state == WebTouchPoint::StateStationary) 486 if (point.state == WebTouchPoint::StateStationary)
488 continue; 487 continue;
(...skipping 27 matching lines...) Expand all
516 } else if (event.type == WebInputEvent::TouchStart) { 515 } else if (event.type == WebInputEvent::TouchStart) {
517 for (unsigned i = 0; i < event.touchesLength; ++i) { 516 for (unsigned i = 0; i < event.touchesLength; ++i) {
518 const WebTouchPoint& point = event.touches[i]; 517 const WebTouchPoint& point = event.touches[i];
519 if (point.state == WebTouchPoint::StatePressed) 518 if (point.state == WebTouchPoint::StatePressed)
520 touch_ack_states_[point.id] = ack_result; 519 touch_ack_states_[point.id] = ack_result;
521 } 520 }
522 } 521 }
523 } 522 }
524 523
525 } // namespace content 524 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698