| 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/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_router_client.h" | 10 #include "content/browser/renderer_host/input/input_router_client.h" |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 | 354 |
| 355 // Perform optional, synchronous event handling, sending ACK messages for | 355 // Perform optional, synchronous event handling, sending ACK messages for |
| 356 // processed events, or proceeding as usual. | 356 // processed events, or proceeding as usual. |
| 357 InputEventAckState filter_ack = client_->FilterInputEvent(input_event, | 357 InputEventAckState filter_ack = client_->FilterInputEvent(input_event, |
| 358 latency_info); | 358 latency_info); |
| 359 switch (filter_ack) { | 359 switch (filter_ack) { |
| 360 // Send the ACK and early exit. | 360 // Send the ACK and early exit. |
| 361 case INPUT_EVENT_ACK_STATE_CONSUMED: | 361 case INPUT_EVENT_ACK_STATE_CONSUMED: |
| 362 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: | 362 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: |
| 363 next_mouse_move_.reset(); | 363 next_mouse_move_.reset(); |
| 364 ProcessInputEventAck(input_event.type, filter_ack); | 364 ProcessInputEventAck(input_event.type, filter_ack, latency_info); |
| 365 // WARNING: |this| may be deleted at this point. | 365 // WARNING: |this| may be deleted at this point. |
| 366 return; | 366 return; |
| 367 | 367 |
| 368 case INPUT_EVENT_ACK_STATE_UNKNOWN: { | 368 case INPUT_EVENT_ACK_STATE_UNKNOWN: { |
| 369 if (input_event.type == WebKit::WebInputEvent::MouseMove) { | 369 if (input_event.type == WebKit::WebInputEvent::MouseMove) { |
| 370 // Since this mouse-move event has been consumed, there will be no ACKs. | 370 // Since this mouse-move event has been consumed, there will be no ACKs. |
| 371 // So reset the state here so that future mouse-move events do reach the | 371 // So reset the state here so that future mouse-move events do reach the |
| 372 // renderer. | 372 // renderer. |
| 373 mouse_move_pending_ = false; | 373 mouse_move_pending_ = false; |
| 374 } else if (input_event.type == WebKit::WebInputEvent::MouseWheel) { | 374 } else if (input_event.type == WebKit::WebInputEvent::MouseWheel) { |
| 375 // Reset the wheel-event state when appropriate. | 375 // Reset the wheel-event state when appropriate. |
| 376 mouse_wheel_pending_ = false; | 376 mouse_wheel_pending_ = false; |
| 377 } else if (WebInputEvent::isGestureEventType(input_event.type) && | 377 } else if (WebInputEvent::isGestureEventType(input_event.type) && |
| 378 gesture_event_filter_->HasQueuedGestureEvents()) { | 378 gesture_event_filter_->HasQueuedGestureEvents()) { |
| 379 // If the gesture-event filter has queued gesture events, that implies | 379 // If the gesture-event filter has queued gesture events, that implies |
| 380 // it's awaiting an ack for the event. Since the event is being dropped, | 380 // it's awaiting an ack for the event. Since the event is being dropped, |
| 381 // it is never sent to the renderer, and so it won't receive any ACKs. | 381 // it is never sent to the renderer, and so it won't receive any ACKs. |
| 382 // So send the ACK to the gesture event filter immediately, and mark it | 382 // So send the ACK to the gesture event filter immediately, and mark it |
| 383 // as having been processed. | 383 // as having been processed. |
| 384 gesture_event_filter_->ProcessGestureAck(true, input_event.type); | 384 gesture_event_filter_->ProcessGestureAck(true, input_event.type); |
| 385 } else if (WebInputEvent::isTouchEventType(input_event.type)) { | 385 } else if (WebInputEvent::isTouchEventType(input_event.type)) { |
| 386 // During an overscroll gesture initiated by touch-scrolling, the | 386 // During an overscroll gesture initiated by touch-scrolling, the |
| 387 // touch-events do not reset or contribute to the overscroll gesture. | 387 // touch-events do not reset or contribute to the overscroll gesture. |
| 388 // However, the touch-events are not sent to the renderer. So send an | 388 // However, the touch-events are not sent to the renderer. So send an |
| 389 // ACK to the touch-event queue immediately. Mark the event as not | 389 // ACK to the touch-event queue immediately. Mark the event as not |
| 390 // processed, to make sure that the touch-scroll gesture that initiated | 390 // processed, to make sure that the touch-scroll gesture that initiated |
| 391 // the overscroll is updated properly. | 391 // the overscroll is updated properly. |
| 392 touch_event_queue_->ProcessTouchAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); | 392 touch_event_queue_->ProcessTouchAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, |
| 393 latency_info); |
| 393 } | 394 } |
| 394 return; | 395 return; |
| 395 } | 396 } |
| 396 | 397 |
| 397 // Proceed as normal. | 398 // Proceed as normal. |
| 398 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: | 399 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: |
| 399 break; | 400 break; |
| 400 }; | 401 }; |
| 401 | 402 |
| 402 // Transmit any pending wheel events on a non-wheel event. This ensures that | 403 // Transmit any pending wheel events on a non-wheel event. This ensures that |
| 403 // the renderer receives the final PhaseEnded wheel event, which is necessary | 404 // the renderer receives the final PhaseEnded wheel event, which is necessary |
| 404 // to terminate rubber-banding, for example. | 405 // to terminate rubber-banding, for example. |
| 405 if (input_event.type != WebInputEvent::MouseWheel) { | 406 if (input_event.type != WebInputEvent::MouseWheel) { |
| 406 for (size_t i = 0; i < coalesced_mouse_wheel_events_.size(); ++i) { | 407 for (size_t i = 0; i < coalesced_mouse_wheel_events_.size(); ++i) { |
| 407 SendWebInputEvent(coalesced_mouse_wheel_events_[i].event, | 408 SendWebInputEvent(coalesced_mouse_wheel_events_[i].event, |
| 408 coalesced_mouse_wheel_events_[i].latency, | 409 coalesced_mouse_wheel_events_[i].latency, |
| 409 false); | 410 false); |
| 410 } | 411 } |
| 411 coalesced_mouse_wheel_events_.clear(); | 412 coalesced_mouse_wheel_events_.clear(); |
| 412 } | 413 } |
| 413 | 414 |
| 414 SendWebInputEvent(input_event, latency_info, is_keyboard_shortcut); | 415 SendWebInputEvent(input_event, latency_info, is_keyboard_shortcut); |
| 415 | 416 |
| 416 // Any input event cancels a pending mouse move event. | 417 // Any input event cancels a pending mouse move event. |
| 417 next_mouse_move_.reset(); | 418 next_mouse_move_.reset(); |
| 418 } | 419 } |
| 419 | 420 |
| 420 void ImmediateInputRouter::OnInputEventAck(WebInputEvent::Type event_type, | 421 void ImmediateInputRouter::OnInputEventAck( |
| 421 InputEventAckState ack_result) { | 422 WebInputEvent::Type event_type, |
| 423 InputEventAckState ack_result, |
| 424 const ui::LatencyInfo& latency_info) { |
| 422 // Log the time delta for processing an input event. | 425 // Log the time delta for processing an input event. |
| 423 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; | 426 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; |
| 424 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta); | 427 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta); |
| 425 | 428 |
| 426 client_->DecrementInFlightEventCount(); | 429 client_->DecrementInFlightEventCount(); |
| 427 | 430 |
| 428 ProcessInputEventAck(event_type, ack_result); | 431 ProcessInputEventAck(event_type, ack_result, latency_info); |
| 429 } | 432 } |
| 430 | 433 |
| 431 void ImmediateInputRouter::OnMsgMoveCaretAck() { | 434 void ImmediateInputRouter::OnMsgMoveCaretAck() { |
| 432 move_caret_pending_ = false; | 435 move_caret_pending_ = false; |
| 433 if (next_move_caret_) | 436 if (next_move_caret_) |
| 434 SendMoveCaret(next_move_caret_.release()); | 437 SendMoveCaret(next_move_caret_.release()); |
| 435 } | 438 } |
| 436 | 439 |
| 437 void ImmediateInputRouter::OnSelectRangeAck() { | 440 void ImmediateInputRouter::OnSelectRangeAck() { |
| 438 select_range_pending_ = false; | 441 select_range_pending_ = false; |
| 439 if (next_selection_range_) | 442 if (next_selection_range_) |
| 440 SendSelectRange(next_selection_range_.release()); | 443 SendSelectRange(next_selection_range_.release()); |
| 441 } | 444 } |
| 442 | 445 |
| 443 void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) { | 446 void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) { |
| 444 if (has_touch_handler_ == has_handlers) | 447 if (has_touch_handler_ == has_handlers) |
| 445 return; | 448 return; |
| 446 has_touch_handler_ = has_handlers; | 449 has_touch_handler_ = has_handlers; |
| 447 if (!has_handlers) | 450 if (!has_handlers) |
| 448 touch_event_queue_->FlushQueue(); | 451 touch_event_queue_->FlushQueue(); |
| 449 client_->OnHasTouchEventHandlers(has_handlers); | 452 client_->OnHasTouchEventHandlers(has_handlers); |
| 450 } | 453 } |
| 451 | 454 |
| 452 void ImmediateInputRouter::ProcessInputEventAck(WebInputEvent::Type event_type, | 455 void ImmediateInputRouter::ProcessInputEventAck( |
| 453 InputEventAckState ack_result) { | 456 WebInputEvent::Type event_type, |
| 457 InputEventAckState ack_result, |
| 458 const ui::LatencyInfo& latency_info) { |
| 454 TRACE_EVENT1("input", "ImmediateInputRouter::ProcessInputEventAck", | 459 TRACE_EVENT1("input", "ImmediateInputRouter::ProcessInputEventAck", |
| 455 "ack", GetEventAckName(ack_result)); | 460 "ack", GetEventAckName(ack_result)); |
| 456 | 461 |
| 457 int type = static_cast<int>(event_type); | 462 int type = static_cast<int>(event_type); |
| 458 if (type < WebInputEvent::Undefined) { | 463 if (type < WebInputEvent::Undefined) { |
| 459 client_->OnUnexpectedEventAck(true); | 464 client_->OnUnexpectedEventAck(true); |
| 460 } else if (type == WebInputEvent::MouseMove) { | 465 } else if (type == WebInputEvent::MouseMove) { |
| 461 mouse_move_pending_ = false; | 466 mouse_move_pending_ = false; |
| 462 | 467 |
| 463 // now, we can send the next mouse move event | 468 // now, we can send the next mouse move event |
| 464 if (next_mouse_move_) { | 469 if (next_mouse_move_) { |
| 465 DCHECK(next_mouse_move_->event.type == WebInputEvent::MouseMove); | 470 DCHECK(next_mouse_move_->event.type == WebInputEvent::MouseMove); |
| 466 scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move | 471 scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move |
| 467 = next_mouse_move_.Pass(); | 472 = next_mouse_move_.Pass(); |
| 468 SendMouseEvent(*next_mouse_move); | 473 SendMouseEvent(*next_mouse_move); |
| 469 } | 474 } |
| 470 } else if (WebInputEvent::isKeyboardEventType(type)) { | 475 } else if (WebInputEvent::isKeyboardEventType(type)) { |
| 471 ProcessKeyboardAck(type, ack_result); | 476 ProcessKeyboardAck(type, ack_result); |
| 472 } else if (type == WebInputEvent::MouseWheel) { | 477 } else if (type == WebInputEvent::MouseWheel) { |
| 473 ProcessWheelAck(ack_result); | 478 ProcessWheelAck(ack_result); |
| 474 } else if (WebInputEvent::isTouchEventType(type)) { | 479 } else if (WebInputEvent::isTouchEventType(type)) { |
| 475 ProcessTouchAck(ack_result); | 480 ProcessTouchAck(ack_result, latency_info); |
| 476 } else if (WebInputEvent::isGestureEventType(type)) { | 481 } else if (WebInputEvent::isGestureEventType(type)) { |
| 477 ProcessGestureAck(type, ack_result); | 482 ProcessGestureAck(type, ack_result); |
| 478 } | 483 } |
| 479 | 484 |
| 480 // WARNING: |this| may be deleted at this point. | 485 // WARNING: |this| may be deleted at this point. |
| 481 | 486 |
| 482 // This is used only for testing, and the other end does not use the | 487 // This is used only for testing, and the other end does not use the |
| 483 // source object. On linux, specifying | 488 // source object. On linux, specifying |
| 484 // Source<RenderWidgetHost> results in a very strange | 489 // Source<RenderWidgetHost> results in a very strange |
| 485 // runtime error in the epilogue of the enclosing | 490 // runtime error in the epilogue of the enclosing |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 } | 542 } |
| 538 | 543 |
| 539 void ImmediateInputRouter::ProcessGestureAck(int type, | 544 void ImmediateInputRouter::ProcessGestureAck(int type, |
| 540 InputEventAckState ack_result) { | 545 InputEventAckState ack_result) { |
| 541 const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result); | 546 const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result); |
| 542 client_->OnGestureEventAck( | 547 client_->OnGestureEventAck( |
| 543 gesture_event_filter_->GetGestureEventAwaitingAck(), ack_result); | 548 gesture_event_filter_->GetGestureEventAwaitingAck(), ack_result); |
| 544 gesture_event_filter_->ProcessGestureAck(processed, type); | 549 gesture_event_filter_->ProcessGestureAck(processed, type); |
| 545 } | 550 } |
| 546 | 551 |
| 547 void ImmediateInputRouter::ProcessTouchAck(InputEventAckState ack_result) { | 552 void ImmediateInputRouter::ProcessTouchAck( |
| 553 InputEventAckState ack_result, |
| 554 const ui::LatencyInfo& latency_info) { |
| 548 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. | 555 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. |
| 549 touch_event_queue_->ProcessTouchAck(ack_result); | 556 touch_event_queue_->ProcessTouchAck(ack_result, latency_info); |
| 550 } | 557 } |
| 551 | 558 |
| 552 } // namespace content | 559 } // namespace content |
| OLD | NEW |