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/input_router_impl.h" | 5 #include "content/browser/renderer_host/input/input_router_impl.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 const ui::LatencyInfo& latency_info, | 349 const ui::LatencyInfo& latency_info, |
350 bool is_keyboard_shortcut) { | 350 bool is_keyboard_shortcut) { |
351 output_stream_validator_.Validate(input_event); | 351 output_stream_validator_.Validate(input_event); |
352 | 352 |
353 if (OfferToClient(input_event, latency_info)) | 353 if (OfferToClient(input_event, latency_info)) |
354 return; | 354 return; |
355 | 355 |
356 OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); | 356 OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); |
357 | 357 |
358 // Touch events should always indicate in the event whether they are | 358 // Touch events should always indicate in the event whether they are |
359 // cancelable (respect ACK disposition) or not. | 359 // cancelable (respect ACK disposition) or not except touchmove. |
360 bool ignores_ack = WebInputEventTraits::IgnoresAckDisposition(input_event); | 360 bool needs_synthetic_ack = |
361 if (WebInputEvent::isTouchEventType(input_event.type)) { | 361 WebInputEventTraits::WillReceiveAckFromRenderer(input_event); |
362 | |
363 if (WebInputEvent::isTouchEventType(input_event.type) && | |
364 input_event.type != WebInputEvent::TouchMove) { | |
362 const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(input_event); | 365 const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(input_event); |
363 DCHECK_NE(ignores_ack, !!touch.cancelable); | 366 DCHECK_EQ(needs_synthetic_ack, touch.cancelable); |
364 } | 367 } |
365 | 368 |
366 // If we don't care about the ack disposition, send the ack immediately. | 369 // If we don't need synthetic ack from render, send the ack immediately. |
367 if (ignores_ack) { | 370 if (!needs_synthetic_ack) { |
jdduke (slow)
2015/05/08 21:30:48
Hmm, synthetic means fake, so I think this should
lanwei
2015/05/11 19:27:56
Done.
| |
368 ProcessInputEventAck(input_event.type, | 371 ProcessInputEventAck( |
369 INPUT_EVENT_ACK_STATE_IGNORED, | 372 input_event.type, INPUT_EVENT_ACK_STATE_IGNORED, latency_info, |
370 latency_info, | 373 WebInputEventTraits::GetUniqueTouchEventId(input_event), |
371 IGNORING_DISPOSITION); | 374 IGNORING_DISPOSITION); |
372 } | 375 } |
373 } | 376 } |
374 | 377 |
375 bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event, | 378 bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event, |
376 const ui::LatencyInfo& latency_info) { | 379 const ui::LatencyInfo& latency_info) { |
377 bool consumed = false; | 380 bool consumed = false; |
378 | 381 |
379 InputEventAckState filter_ack = | 382 InputEventAckState filter_ack = |
380 client_->FilterInputEvent(input_event, latency_info); | 383 client_->FilterInputEvent(input_event, latency_info); |
381 switch (filter_ack) { | 384 switch (filter_ack) { |
382 case INPUT_EVENT_ACK_STATE_CONSUMED: | 385 case INPUT_EVENT_ACK_STATE_CONSUMED: |
383 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: | 386 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: { |
384 // Send the ACK and early exit. | 387 // Send the ACK and early exit. |
385 next_mouse_move_.reset(); | 388 next_mouse_move_.reset(); |
386 ProcessInputEventAck(input_event.type, filter_ack, latency_info, CLIENT); | 389 InputEventAck ack( |
jdduke (slow)
2015/05/08 21:30:48
You can remove this unused variable.
lanwei
2015/05/11 19:27:55
Done.
| |
390 input_event.type, filter_ack, latency_info, | |
391 WebInputEventTraits::GetUniqueTouchEventId(input_event)); | |
392 ProcessInputEventAck( | |
393 input_event.type, filter_ack, latency_info, | |
394 WebInputEventTraits::GetUniqueTouchEventId(input_event), CLIENT); | |
387 // WARNING: |this| may be deleted at this point. | 395 // WARNING: |this| may be deleted at this point. |
388 consumed = true; | 396 consumed = true; |
389 break; | 397 break; |
398 } | |
390 case INPUT_EVENT_ACK_STATE_UNKNOWN: | 399 case INPUT_EVENT_ACK_STATE_UNKNOWN: |
391 // Simply drop the event. | 400 // Simply drop the event. |
392 consumed = true; | 401 consumed = true; |
393 break; | 402 break; |
394 default: | 403 default: |
395 break; | 404 break; |
396 } | 405 } |
397 | 406 |
398 return consumed; | 407 return consumed; |
399 } | 408 } |
400 | 409 |
401 bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event, | 410 bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event, |
402 const ui::LatencyInfo& latency_info, | 411 const ui::LatencyInfo& latency_info, |
403 bool is_keyboard_shortcut) { | 412 bool is_keyboard_shortcut) { |
404 if (Send(new InputMsg_HandleInputEvent( | 413 if (Send(new InputMsg_HandleInputEvent( |
405 routing_id(), &input_event, latency_info, is_keyboard_shortcut))) { | 414 routing_id(), &input_event, latency_info, is_keyboard_shortcut))) { |
406 // Ack messages for ignored ack event types should never be sent by the | 415 // Ack messages for ignored ack event types should never be sent by the |
407 // renderer. Consequently, such event types should not affect event time | 416 // renderer. Consequently, such event types should not affect event time |
408 // or in-flight event count metrics. | 417 // or in-flight event count metrics. |
409 if (!WebInputEventTraits::IgnoresAckDisposition(input_event)) { | 418 if (WebInputEventTraits::WillReceiveAckFromRenderer(input_event)) { |
410 input_event_start_time_ = TimeTicks::Now(); | 419 input_event_start_time_ = TimeTicks::Now(); |
411 client_->IncrementInFlightEventCount(); | 420 client_->IncrementInFlightEventCount(); |
412 } | 421 } |
413 return true; | 422 return true; |
414 } | 423 } |
415 return false; | 424 return false; |
416 } | 425 } |
417 | 426 |
418 void InputRouterImpl::OnInputEventAck( | 427 void InputRouterImpl::OnInputEventAck(const InputEventAck& ack) { |
419 const InputHostMsg_HandleInputEvent_ACK_Params& ack) { | |
420 client_->DecrementInFlightEventCount(); | 428 client_->DecrementInFlightEventCount(); |
421 | |
422 // Log the time delta for processing an input event. | 429 // Log the time delta for processing an input event. |
423 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; | 430 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; |
424 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta); | 431 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta); |
425 | 432 |
426 if (ack.overscroll) { | 433 if (ack.overscroll) { |
427 DCHECK(ack.type == WebInputEvent::MouseWheel || | 434 DCHECK(ack.type == WebInputEvent::MouseWheel || |
428 ack.type == WebInputEvent::GestureScrollUpdate); | 435 ack.type == WebInputEvent::GestureScrollUpdate); |
429 OnDidOverscroll(*ack.overscroll); | 436 OnDidOverscroll(*ack.overscroll); |
430 } | 437 } |
431 | 438 |
432 ProcessInputEventAck(ack.type, ack.state, ack.latency, RENDERER); | 439 ProcessInputEventAck(ack.type, ack.state, ack.latency, |
433 // WARNING: |this| may be deleted at this point. | 440 ack.unique_touch_event_id, RENDERER); |
434 | |
435 // This is used only for testing, and the other end does not use the | |
436 // source object. On linux, specifying | |
437 // Source<RenderWidgetHost> results in a very strange | |
438 // runtime error in the epilogue of the enclosing | |
439 // (ProcessInputEventAck) method, but not on other platforms; using | |
440 // 'void' instead is just as safe (since NotificationSource | |
441 // is not actually typesafe) and avoids this error. | |
442 int type = static_cast<int>(ack.type); | |
443 NotificationService::current()->Notify( | |
444 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK, | |
445 Source<void>(this), | |
446 Details<int>(&type)); | |
447 } | 441 } |
448 | 442 |
449 void InputRouterImpl::OnDidOverscroll(const DidOverscrollParams& params) { | 443 void InputRouterImpl::OnDidOverscroll(const DidOverscrollParams& params) { |
450 client_->DidOverscroll(params); | 444 client_->DidOverscroll(params); |
451 } | 445 } |
452 | 446 |
453 void InputRouterImpl::OnMsgMoveCaretAck() { | 447 void InputRouterImpl::OnMsgMoveCaretAck() { |
454 move_caret_pending_ = false; | 448 move_caret_pending_ = false; |
455 if (next_move_caret_) | 449 if (next_move_caret_) |
456 SendMoveCaret(next_move_caret_.Pass()); | 450 SendMoveCaret(next_move_caret_.Pass()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
495 // TOUCH_ACTION_NONE should disable the touch ack timeout. | 489 // TOUCH_ACTION_NONE should disable the touch ack timeout. |
496 UpdateTouchAckTimeoutEnabled(); | 490 UpdateTouchAckTimeoutEnabled(); |
497 } | 491 } |
498 | 492 |
499 void InputRouterImpl::OnDidStopFlinging() { | 493 void InputRouterImpl::OnDidStopFlinging() { |
500 // TODO(jdduke): Track fling status to allow flush notifications after a fling | 494 // TODO(jdduke): Track fling status to allow flush notifications after a fling |
501 // has terminated, crbug.com/483037. | 495 // has terminated, crbug.com/483037. |
502 client_->DidStopFlinging(); | 496 client_->DidStopFlinging(); |
503 } | 497 } |
504 | 498 |
505 void InputRouterImpl::ProcessInputEventAck( | 499 void InputRouterImpl::ProcessInputEventAck(WebInputEvent::Type event_type, |
506 WebInputEvent::Type event_type, | 500 InputEventAckState ack_result, |
507 InputEventAckState ack_result, | 501 const ui::LatencyInfo& latency_info, |
508 const ui::LatencyInfo& latency_info, | 502 uint32 unique_touch_event_id, |
509 AckSource ack_source) { | 503 AckSource ack_source) { |
510 TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck", | 504 TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck", |
511 "type", WebInputEventTraits::GetName(event_type), | 505 "type", WebInputEventTraits::GetName(event_type), |
512 "ack", GetEventAckName(ack_result)); | 506 "ack", GetEventAckName(ack_result)); |
513 | 507 |
514 // Note: The keyboard ack must be treated carefully, as it may result in | 508 // Note: The keyboard ack must be treated carefully, as it may result in |
515 // synchronous destruction of |this|. Handling immediately guards against | 509 // synchronous destruction of |this|. Handling immediately guards against |
516 // future references to |this|, as with |auto_reset_current_ack_source| below. | 510 // future references to |this|, as with |auto_reset_current_ack_source| below. |
517 if (WebInputEvent::isKeyboardEventType(event_type)) { | 511 if (WebInputEvent::isKeyboardEventType(event_type)) { |
518 ProcessKeyboardAck(event_type, ack_result); | 512 ProcessKeyboardAck(event_type, ack_result); |
519 // WARNING: |this| may be deleted at this point. | 513 // WARNING: |this| may be deleted at this point. |
520 return; | 514 return; |
521 } | 515 } |
522 | 516 |
523 base::AutoReset<AckSource> auto_reset_current_ack_source( | 517 base::AutoReset<AckSource> auto_reset_current_ack_source( |
524 ¤t_ack_source_, ack_source); | 518 ¤t_ack_source_, ack_source); |
525 | 519 |
526 if (WebInputEvent::isMouseEventType(event_type)) { | 520 if (WebInputEvent::isMouseEventType(event_type)) { |
527 ProcessMouseAck(event_type, ack_result); | 521 ProcessMouseAck(event_type, ack_result); |
528 } else if (event_type == WebInputEvent::MouseWheel) { | 522 } else if (event_type == WebInputEvent::MouseWheel) { |
529 ProcessWheelAck(ack_result, latency_info); | 523 ProcessWheelAck(ack_result, latency_info); |
530 } else if (WebInputEvent::isTouchEventType(event_type)) { | 524 } else if (WebInputEvent::isTouchEventType(event_type)) { |
531 ProcessTouchAck(ack_result, latency_info); | 525 ProcessTouchAck(ack_result, latency_info, unique_touch_event_id); |
532 } else if (WebInputEvent::isGestureEventType(event_type)) { | 526 } else if (WebInputEvent::isGestureEventType(event_type)) { |
533 ProcessGestureAck(event_type, ack_result, latency_info); | 527 ProcessGestureAck(event_type, ack_result, latency_info); |
534 } else if (event_type != WebInputEvent::Undefined) { | 528 } else if (event_type != WebInputEvent::Undefined) { |
535 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); | 529 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); |
536 } | 530 } |
537 | 531 |
538 SignalFlushedIfNecessary(); | 532 SignalFlushedIfNecessary(); |
539 } | 533 } |
540 | 534 |
541 void InputRouterImpl::ProcessKeyboardAck(blink::WebInputEvent::Type type, | 535 void InputRouterImpl::ProcessKeyboardAck(blink::WebInputEvent::Type type, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
600 } | 594 } |
601 } | 595 } |
602 | 596 |
603 void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type, | 597 void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type, |
604 InputEventAckState ack_result, | 598 InputEventAckState ack_result, |
605 const ui::LatencyInfo& latency) { | 599 const ui::LatencyInfo& latency) { |
606 // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. | 600 // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. |
607 gesture_event_queue_.ProcessGestureAck(ack_result, type, latency); | 601 gesture_event_queue_.ProcessGestureAck(ack_result, type, latency); |
608 } | 602 } |
609 | 603 |
610 void InputRouterImpl::ProcessTouchAck( | 604 void InputRouterImpl::ProcessTouchAck(InputEventAckState ack_result, |
611 InputEventAckState ack_result, | 605 const ui::LatencyInfo& latency, |
612 const ui::LatencyInfo& latency) { | 606 uint32 unique_touch_event_id) { |
613 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. | 607 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. |
614 touch_event_queue_.ProcessTouchAck(ack_result, latency); | 608 touch_event_queue_.ProcessTouchAck(ack_result, latency, |
609 unique_touch_event_id); | |
615 } | 610 } |
616 | 611 |
617 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { | 612 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { |
618 // Mobile sites tend to be well-behaved with respect to touch handling, so | 613 // Mobile sites tend to be well-behaved with respect to touch handling, so |
619 // they have less need for the touch timeout fallback. | 614 // they have less need for the touch timeout fallback. |
620 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; | 615 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; |
621 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; | 616 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; |
622 | 617 |
623 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves | 618 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves |
624 // little purpose. It's also a strong signal that touch handling is critical | 619 // little purpose. It's also a strong signal that touch handling is critical |
(...skipping 12 matching lines...) Expand all Loading... | |
637 return; | 632 return; |
638 | 633 |
639 if (HasPendingEvents()) | 634 if (HasPendingEvents()) |
640 return; | 635 return; |
641 | 636 |
642 flush_requested_ = false; | 637 flush_requested_ = false; |
643 client_->DidFlush(); | 638 client_->DidFlush(); |
644 } | 639 } |
645 | 640 |
646 } // namespace content | 641 } // namespace content |
OLD | NEW |