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

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

Issue 25022003: Report LatencyInfo through trace buffer (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: fix nits Created 7 years, 2 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/immediate_input_router.h" 5 #include "content/browser/renderer_host/input/immediate_input_router.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "content/browser/renderer_host/input/gesture_event_filter.h" 9 #include "content/browser/renderer_host/input/gesture_event_filter.h"
10 #include "content/browser/renderer_host/input/input_ack_handler.h" 10 #include "content/browser/renderer_host/input/input_ack_handler.h"
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 IPC_MESSAGE_UNHANDLED(handled = false) 299 IPC_MESSAGE_UNHANDLED(handled = false)
300 IPC_END_MESSAGE_MAP() 300 IPC_END_MESSAGE_MAP()
301 301
302 if (!message_is_ok) 302 if (!message_is_ok)
303 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); 303 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE);
304 304
305 return handled; 305 return handled;
306 } 306 }
307 307
308 void ImmediateInputRouter::OnTouchEventAck( 308 void ImmediateInputRouter::OnTouchEventAck(
309 const TouchEventWithLatencyInfo& event, 309 const WebKit::WebTouchEvent& event,
310 InputEventAckState ack_result) { 310 InputEventAckState ack_result,
311 ack_handler_->OnTouchEventAck(event, ack_result); 311 ui::LatencyInfo* latency) {
312 ack_handler_->OnTouchEventAck(event, ack_result, latency);
312 } 313 }
313 314
314 bool ImmediateInputRouter::SendSelectRange(scoped_ptr<IPC::Message> message) { 315 bool ImmediateInputRouter::SendSelectRange(scoped_ptr<IPC::Message> message) {
315 DCHECK(message->type() == InputMsg_SelectRange::ID); 316 DCHECK(message->type() == InputMsg_SelectRange::ID);
316 if (select_range_pending_) { 317 if (select_range_pending_) {
317 next_selection_range_ = message.Pass(); 318 next_selection_range_ = message.Pass();
318 return true; 319 return true;
319 } 320 }
320 321
321 select_range_pending_ = true; 322 select_range_pending_ = true;
(...skipping 29 matching lines...) Expand all
351 const WebInputEvent& input_event, 352 const WebInputEvent& input_event,
352 const ui::LatencyInfo& latency_info, 353 const ui::LatencyInfo& latency_info,
353 bool is_keyboard_shortcut) { 354 bool is_keyboard_shortcut) {
354 TRACE_EVENT0("input", "ImmediateInputRouter::FilterAndSendWebInputEvent"); 355 TRACE_EVENT0("input", "ImmediateInputRouter::FilterAndSendWebInputEvent");
355 356
356 if (!process_->HasConnection()) 357 if (!process_->HasConnection())
357 return; 358 return;
358 359
359 DCHECK(!process_->IgnoreInputEvents()); 360 DCHECK(!process_->IgnoreInputEvents());
360 361
362 ui::LatencyInfo renderer_latency;
361 // Perform optional, synchronous event handling, sending ACK messages for 363 // Perform optional, synchronous event handling, sending ACK messages for
362 // processed events, or proceeding as usual. 364 // processed events, or proceeding as usual.
363 InputEventAckState filter_ack = client_->FilterInputEvent(input_event, 365 InputEventAckState filter_ack = client_->FilterInputEvent(input_event,
364 latency_info); 366 latency_info);
365 switch (filter_ack) { 367 switch (filter_ack) {
366 // Send the ACK and early exit. 368 // Send the ACK and early exit.
367 case INPUT_EVENT_ACK_STATE_CONSUMED: 369 case INPUT_EVENT_ACK_STATE_CONSUMED:
368 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: 370 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS:
369 next_mouse_move_.reset(); 371 next_mouse_move_.reset();
370 ProcessInputEventAck(input_event.type, filter_ack, latency_info); 372 ProcessInputEventAck(input_event.type, filter_ack, &renderer_latency);
371 // WARNING: |this| may be deleted at this point. 373 // WARNING: |this| may be deleted at this point.
372 return; 374 return;
373 375
374 case INPUT_EVENT_ACK_STATE_UNKNOWN: { 376 case INPUT_EVENT_ACK_STATE_UNKNOWN: {
375 if (input_event.type == WebKit::WebInputEvent::MouseMove) { 377 if (input_event.type == WebKit::WebInputEvent::MouseMove) {
376 // Since this mouse-move event has been consumed, there will be no ACKs. 378 // Since this mouse-move event has been consumed, there will be no ACKs.
377 // So reset the state here so that future mouse-move events do reach the 379 // So reset the state here so that future mouse-move events do reach the
378 // renderer. 380 // renderer.
379 mouse_move_pending_ = false; 381 mouse_move_pending_ = false;
380 } else if (input_event.type == WebKit::WebInputEvent::MouseWheel) { 382 } else if (input_event.type == WebKit::WebInputEvent::MouseWheel) {
381 // Reset the wheel-event state when appropriate. 383 // Reset the wheel-event state when appropriate.
382 mouse_wheel_pending_ = false; 384 mouse_wheel_pending_ = false;
383 } else if (WebInputEvent::isGestureEventType(input_event.type) && 385 } else if (WebInputEvent::isGestureEventType(input_event.type) &&
384 gesture_event_filter_->HasQueuedGestureEvents()) { 386 gesture_event_filter_->HasQueuedGestureEvents()) {
385 // If the gesture-event filter has queued gesture events, that implies 387 // If the gesture-event filter has queued gesture events, that implies
386 // it's awaiting an ack for the event. Since the event is being dropped, 388 // it's awaiting an ack for the event. Since the event is being dropped,
387 // it is never sent to the renderer, and so it won't receive any ACKs. 389 // it is never sent to the renderer, and so it won't receive any ACKs.
388 // So send the ACK to the gesture event filter immediately, and mark it 390 // So send the ACK to the gesture event filter immediately, and mark it
389 // as having been processed. 391 // as having been processed.
390 gesture_event_filter_->ProcessGestureAck(true, input_event.type); 392 gesture_event_filter_->ProcessGestureAck(true, input_event.type);
391 } else if (WebInputEvent::isTouchEventType(input_event.type)) { 393 } else if (WebInputEvent::isTouchEventType(input_event.type)) {
392 // During an overscroll gesture initiated by touch-scrolling, the 394 // During an overscroll gesture initiated by touch-scrolling, the
393 // touch-events do not reset or contribute to the overscroll gesture. 395 // touch-events do not reset or contribute to the overscroll gesture.
394 // However, the touch-events are not sent to the renderer. So send an 396 // However, the touch-events are not sent to the renderer. So send an
395 // ACK to the touch-event queue immediately. Mark the event as not 397 // ACK to the touch-event queue immediately. Mark the event as not
396 // processed, to make sure that the touch-scroll gesture that initiated 398 // processed, to make sure that the touch-scroll gesture that initiated
397 // the overscroll is updated properly. 399 // the overscroll is updated properly.
398 touch_event_queue_->ProcessTouchAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, 400 touch_event_queue_->ProcessTouchAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
399 latency_info); 401 renderer_latency);
400 } 402 }
401 return; 403 return;
402 } 404 }
403 405
404 // Proceed as normal. 406 // Proceed as normal.
405 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: 407 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED:
406 break; 408 break;
407 } 409 }
408 410
409 // Transmit any pending wheel events on a non-wheel event. This ensures that 411 // Transmit any pending wheel events on a non-wheel event. This ensures that
(...skipping 10 matching lines...) Expand all
420 422
421 SendWebInputEvent(input_event, latency_info, is_keyboard_shortcut); 423 SendWebInputEvent(input_event, latency_info, is_keyboard_shortcut);
422 424
423 // Any input event cancels a pending mouse move event. 425 // Any input event cancels a pending mouse move event.
424 next_mouse_move_.reset(); 426 next_mouse_move_.reset();
425 } 427 }
426 428
427 void ImmediateInputRouter::OnInputEventAck( 429 void ImmediateInputRouter::OnInputEventAck(
428 WebInputEvent::Type event_type, 430 WebInputEvent::Type event_type,
429 InputEventAckState ack_result, 431 InputEventAckState ack_result,
430 const ui::LatencyInfo& latency_info) { 432 ui::LatencyInfo latency_info) {
jdduke (slow) 2013/10/08 16:28:08 So, we're copying the ui::LatencyInfo here, only t
Yufeng Shen (Slow to review) 2013/10/08 19:35:59 Done.
431 // Log the time delta for processing an input event. 433 // Log the time delta for processing an input event.
432 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; 434 TimeDelta delta = TimeTicks::Now() - input_event_start_time_;
433 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta); 435 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta);
434 436
435 client_->DecrementInFlightEventCount(); 437 client_->DecrementInFlightEventCount();
436 438
437 ProcessInputEventAck(event_type, ack_result, latency_info); 439 ProcessInputEventAck(event_type, ack_result, &latency_info);
438 } 440 }
439 441
440 void ImmediateInputRouter::OnMsgMoveCaretAck() { 442 void ImmediateInputRouter::OnMsgMoveCaretAck() {
441 move_caret_pending_ = false; 443 move_caret_pending_ = false;
442 if (next_move_caret_) 444 if (next_move_caret_)
443 SendMoveCaret(next_move_caret_.Pass()); 445 SendMoveCaret(next_move_caret_.Pass());
444 } 446 }
445 447
446 void ImmediateInputRouter::OnSelectRangeAck() { 448 void ImmediateInputRouter::OnSelectRangeAck() {
447 select_range_pending_ = false; 449 select_range_pending_ = false;
448 if (next_selection_range_) 450 if (next_selection_range_)
449 SendSelectRange(next_selection_range_.Pass()); 451 SendSelectRange(next_selection_range_.Pass());
450 } 452 }
451 453
452 void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) { 454 void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) {
453 if (has_touch_handler_ == has_handlers) 455 if (has_touch_handler_ == has_handlers)
454 return; 456 return;
455 has_touch_handler_ = has_handlers; 457 has_touch_handler_ = has_handlers;
456 if (!has_handlers) 458 if (!has_handlers)
457 touch_event_queue_->FlushQueue(); 459 touch_event_queue_->FlushQueue();
458 client_->OnHasTouchEventHandlers(has_handlers); 460 client_->OnHasTouchEventHandlers(has_handlers);
459 } 461 }
460 462
461 void ImmediateInputRouter::ProcessInputEventAck( 463 void ImmediateInputRouter::ProcessInputEventAck(
462 WebInputEvent::Type event_type, 464 WebInputEvent::Type event_type,
463 InputEventAckState ack_result, 465 InputEventAckState ack_result,
464 const ui::LatencyInfo& latency_info) { 466 ui::LatencyInfo* latency_info) {
465 TRACE_EVENT1("input", "ImmediateInputRouter::ProcessInputEventAck", 467 TRACE_EVENT1("input", "ImmediateInputRouter::ProcessInputEventAck",
466 "ack", GetEventAckName(ack_result)); 468 "ack", GetEventAckName(ack_result));
467 469
468 int type = static_cast<int>(event_type); 470 int type = static_cast<int>(event_type);
469 if (type < WebInputEvent::Undefined) { 471 if (type < WebInputEvent::Undefined) {
470 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); 472 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE);
471 } else if (type == WebInputEvent::MouseMove) { 473 } else if (type == WebInputEvent::MouseMove) {
472 mouse_move_pending_ = false; 474 mouse_move_pending_ = false;
473 475
474 // now, we can send the next mouse move event 476 // now, we can send the next mouse move event
475 if (next_mouse_move_) { 477 if (next_mouse_move_) {
476 DCHECK(next_mouse_move_->event.type == WebInputEvent::MouseMove); 478 DCHECK(next_mouse_move_->event.type == WebInputEvent::MouseMove);
477 scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move 479 scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move
478 = next_mouse_move_.Pass(); 480 = next_mouse_move_.Pass();
479 SendMouseEvent(*next_mouse_move); 481 SendMouseEvent(*next_mouse_move);
480 } 482 }
481 } else if (WebInputEvent::isKeyboardEventType(type)) { 483 } else if (WebInputEvent::isKeyboardEventType(type)) {
482 ProcessKeyboardAck(type, ack_result); 484 ProcessKeyboardAck(type, ack_result);
483 } else if (type == WebInputEvent::MouseWheel) { 485 } else if (type == WebInputEvent::MouseWheel) {
484 ProcessWheelAck(ack_result); 486 ProcessWheelAck(ack_result, latency_info);
485 } else if (WebInputEvent::isTouchEventType(type)) { 487 } else if (WebInputEvent::isTouchEventType(type)) {
486 ProcessTouchAck(ack_result, latency_info); 488 ProcessTouchAck(ack_result, *latency_info);
487 } else if (WebInputEvent::isGestureEventType(type)) { 489 } else if (WebInputEvent::isGestureEventType(type)) {
488 ProcessGestureAck(type, ack_result); 490 ProcessGestureAck(type, ack_result, latency_info);
489 } 491 }
490 492
491 // WARNING: |this| may be deleted at this point. 493 // WARNING: |this| may be deleted at this point.
492 494
493 // This is used only for testing, and the other end does not use the 495 // This is used only for testing, and the other end does not use the
494 // source object. On linux, specifying 496 // source object. On linux, specifying
495 // Source<RenderWidgetHost> results in a very strange 497 // Source<RenderWidgetHost> results in a very strange
496 // runtime error in the epilogue of the enclosing 498 // runtime error in the epilogue of the enclosing
497 // (ProcessInputEventAck) method, but not on other platforms; using 499 // (ProcessInputEventAck) method, but not on other platforms; using
498 // 'void' instead is just as safe (since NotificationSource 500 // 'void' instead is just as safe (since NotificationSource
(...skipping 18 matching lines...) Expand all
517 NativeWebKeyboardEvent front_item = key_queue_.front(); 519 NativeWebKeyboardEvent front_item = key_queue_.front();
518 key_queue_.pop_front(); 520 key_queue_.pop_front();
519 521
520 ack_handler_->OnKeyboardEventAck(front_item, ack_result); 522 ack_handler_->OnKeyboardEventAck(front_item, ack_result);
521 // WARNING: This ImmediateInputRouter can be deallocated at this point 523 // WARNING: This ImmediateInputRouter can be deallocated at this point
522 // (i.e. in the case of Ctrl+W, where the call to 524 // (i.e. in the case of Ctrl+W, where the call to
523 // HandleKeyboardEvent destroys this ImmediateInputRouter). 525 // HandleKeyboardEvent destroys this ImmediateInputRouter).
524 } 526 }
525 } 527 }
526 528
527 void ImmediateInputRouter::ProcessWheelAck(InputEventAckState ack_result) { 529 void ImmediateInputRouter::ProcessWheelAck(InputEventAckState ack_result,
530 ui::LatencyInfo* latency) {
528 mouse_wheel_pending_ = false; 531 mouse_wheel_pending_ = false;
529 532
533 // TODO(miletus): Add renderer side latency to each uncoalesced mouse
534 // wheel event and add terminal component to each of them.
535 ui::LatencyInfo combined_latency = current_wheel_event_.latency;
536 combined_latency.AddNewLatencyFrom(*latency);
530 // Process the unhandled wheel event here before calling 537 // Process the unhandled wheel event here before calling
531 // ForwardWheelEventWithLatencyInfo() since it will mutate 538 // ForwardWheelEventWithLatencyInfo() since it will mutate
532 // current_wheel_event_. 539 // current_wheel_event_.
533 ack_handler_->OnWheelEventAck(current_wheel_event_.event, ack_result); 540 ack_handler_->OnWheelEventAck(current_wheel_event_.event,
541 ack_result,
542 &combined_latency);
534 543
535 // Now send the next (coalesced) mouse wheel event. 544 // Now send the next (coalesced) mouse wheel event.
536 if (!coalesced_mouse_wheel_events_.empty()) { 545 if (!coalesced_mouse_wheel_events_.empty()) {
537 MouseWheelEventWithLatencyInfo next_wheel_event = 546 MouseWheelEventWithLatencyInfo next_wheel_event =
538 coalesced_mouse_wheel_events_.front(); 547 coalesced_mouse_wheel_events_.front();
539 coalesced_mouse_wheel_events_.pop_front(); 548 coalesced_mouse_wheel_events_.pop_front();
540 SendWheelEvent(next_wheel_event); 549 SendWheelEvent(next_wheel_event);
541 } 550 }
542 } 551 }
543 552
544 void ImmediateInputRouter::ProcessGestureAck(int type, 553 void ImmediateInputRouter::ProcessGestureAck(int type,
545 InputEventAckState ack_result) { 554 InputEventAckState ack_result,
555 ui::LatencyInfo* latency) {
546 const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result); 556 const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
557 // TODO(miletus): Add renderer side latency to each uncoalesced gesture
558 // event event and add terminal component to each of them.
547 ack_handler_->OnGestureEventAck( 559 ack_handler_->OnGestureEventAck(
548 gesture_event_filter_->GetGestureEventAwaitingAck(), ack_result); 560 gesture_event_filter_->GetGestureEventAwaitingAck(), ack_result, latency);
549 gesture_event_filter_->ProcessGestureAck(processed, type); 561 gesture_event_filter_->ProcessGestureAck(processed, type);
550 } 562 }
551 563
552 void ImmediateInputRouter::ProcessTouchAck( 564 void ImmediateInputRouter::ProcessTouchAck(
553 InputEventAckState ack_result, 565 InputEventAckState ack_result,
554 const ui::LatencyInfo& latency_info) { 566 const ui::LatencyInfo& latency_info) {
555 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. 567 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate.
556 touch_event_queue_->ProcessTouchAck(ack_result, latency_info); 568 touch_event_queue_->ProcessTouchAck(ack_result, latency_info);
557 } 569 }
558 570
559 void ImmediateInputRouter::HandleGestureScroll( 571 void ImmediateInputRouter::HandleGestureScroll(
560 const GestureEventWithLatencyInfo& gesture_event) { 572 const GestureEventWithLatencyInfo& gesture_event) {
561 if (!enable_no_touch_to_renderer_while_scrolling_) 573 if (!enable_no_touch_to_renderer_while_scrolling_)
562 return; 574 return;
563 575
564 // Once scrolling is started stop forwarding touch move events to renderer. 576 // Once scrolling is started stop forwarding touch move events to renderer.
565 if (gesture_event.event.type == WebInputEvent::GestureScrollBegin) 577 if (gesture_event.event.type == WebInputEvent::GestureScrollBegin)
566 touch_event_queue_->set_no_touch_move_to_renderer(true); 578 touch_event_queue_->set_no_touch_move_to_renderer(true);
567 579
568 if (gesture_event.event.type == WebInputEvent::GestureScrollEnd || 580 if (gesture_event.event.type == WebInputEvent::GestureScrollEnd ||
569 gesture_event.event.type == WebInputEvent::GestureFlingStart) { 581 gesture_event.event.type == WebInputEvent::GestureFlingStart) {
570 touch_event_queue_->set_no_touch_move_to_renderer(false); 582 touch_event_queue_->set_no_touch_move_to_renderer(false);
571 } 583 }
572 } 584 }
573 585
574 } // namespace content 586 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698