| 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" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "content/browser/renderer_host/input/gesture_event_queue.h" | 13 #include "content/browser/renderer_host/input/gesture_event_queue.h" |
| 14 #include "content/browser/renderer_host/input/input_ack_handler.h" | 14 #include "content/browser/renderer_host/input/input_ack_handler.h" |
| 15 #include "content/browser/renderer_host/input/input_router_client.h" | 15 #include "content/browser/renderer_host/input/input_router_client.h" |
| 16 #include "content/browser/renderer_host/input/touch_event_queue.h" | 16 #include "content/browser/renderer_host/input/touch_event_queue.h" |
| 17 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
r.h" | 17 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
r.h" |
| 18 #include "content/browser/renderer_host/overscroll_controller.h" | |
| 19 #include "content/common/content_constants_internal.h" | 18 #include "content/common/content_constants_internal.h" |
| 20 #include "content/common/edit_command.h" | 19 #include "content/common/edit_command.h" |
| 21 #include "content/common/input/input_event_ack_state.h" | 20 #include "content/common/input/input_event_ack_state.h" |
| 22 #include "content/common/input/touch_action.h" | 21 #include "content/common/input/touch_action.h" |
| 23 #include "content/common/input/web_touch_event_traits.h" | 22 #include "content/common/input/web_touch_event_traits.h" |
| 24 #include "content/common/input_messages.h" | 23 #include "content/common/input_messages.h" |
| 25 #include "content/common/view_messages.h" | 24 #include "content/common/view_messages.h" |
| 26 #include "content/public/browser/notification_service.h" | 25 #include "content/public/browser/notification_service.h" |
| 27 #include "content/public/browser/notification_types.h" | 26 #include "content/public/browser/notification_types.h" |
| 28 #include "content/public/browser/user_metrics.h" | 27 #include "content/public/browser/user_metrics.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 const GestureEventWithLatencyInfo& original_gesture_event) { | 176 const GestureEventWithLatencyInfo& original_gesture_event) { |
| 178 event_stream_validator_.OnEvent(original_gesture_event.event); | 177 event_stream_validator_.OnEvent(original_gesture_event.event); |
| 179 GestureEventWithLatencyInfo gesture_event(original_gesture_event); | 178 GestureEventWithLatencyInfo gesture_event(original_gesture_event); |
| 180 | 179 |
| 181 if (touch_action_filter_.FilterGestureEvent(&gesture_event.event)) | 180 if (touch_action_filter_.FilterGestureEvent(&gesture_event.event)) |
| 182 return; | 181 return; |
| 183 | 182 |
| 184 if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen) | 183 if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen) |
| 185 touch_event_queue_.OnGestureScrollEvent(gesture_event); | 184 touch_event_queue_.OnGestureScrollEvent(gesture_event); |
| 186 | 185 |
| 187 if (!IsInOverscrollGesture() && | 186 // TODO(jdduke): Determine behavior for discarded 0-velocity touchpad fling. |
| 188 !gesture_event_queue_.ShouldForward(gesture_event)) { | 187 if (!gesture_event_queue_.ShouldForward(gesture_event)) |
| 189 OverscrollController* controller = client_->GetOverscrollController(); | |
| 190 if (controller) | |
| 191 controller->DiscardingGestureEvent(gesture_event.event); | |
| 192 return; | 188 return; |
| 193 } | |
| 194 | 189 |
| 195 SendGestureEventImmediately(gesture_event); | 190 SendGestureEventImmediately(gesture_event); |
| 196 } | 191 } |
| 197 | 192 |
| 198 void InputRouterImpl::SendTouchEvent( | 193 void InputRouterImpl::SendTouchEvent( |
| 199 const TouchEventWithLatencyInfo& touch_event) { | 194 const TouchEventWithLatencyInfo& touch_event) { |
| 200 touch_event_queue_.QueueEvent(touch_event); | 195 touch_event_queue_.QueueEvent(touch_event); |
| 201 } | 196 } |
| 202 | 197 |
| 203 // Forwards MouseEvent without passing it through | 198 // Forwards MouseEvent without passing it through |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 touch_action_filter_.ResetTouchAction(); | 286 touch_action_filter_.ResetTouchAction(); |
| 292 UpdateTouchAckTimeoutEnabled(); | 287 UpdateTouchAckTimeoutEnabled(); |
| 293 } | 288 } |
| 294 ack_handler_->OnTouchEventAck(event, ack_result); | 289 ack_handler_->OnTouchEventAck(event, ack_result); |
| 295 } | 290 } |
| 296 | 291 |
| 297 void InputRouterImpl::OnGestureEventAck( | 292 void InputRouterImpl::OnGestureEventAck( |
| 298 const GestureEventWithLatencyInfo& event, | 293 const GestureEventWithLatencyInfo& event, |
| 299 InputEventAckState ack_result) { | 294 InputEventAckState ack_result) { |
| 300 touch_event_queue_.OnGestureEventAck(event, ack_result); | 295 touch_event_queue_.OnGestureEventAck(event, ack_result); |
| 301 ProcessAckForOverscroll(event.event, ack_result); | |
| 302 ack_handler_->OnGestureEventAck(event, ack_result); | 296 ack_handler_->OnGestureEventAck(event, ack_result); |
| 303 } | 297 } |
| 304 | 298 |
| 305 bool InputRouterImpl::SendSelectRange(scoped_ptr<IPC::Message> message) { | 299 bool InputRouterImpl::SendSelectRange(scoped_ptr<IPC::Message> message) { |
| 306 DCHECK(message->type() == InputMsg_SelectRange::ID); | 300 DCHECK(message->type() == InputMsg_SelectRange::ID); |
| 307 if (select_range_pending_) { | 301 if (select_range_pending_) { |
| 308 next_selection_range_ = message.Pass(); | 302 next_selection_range_ = message.Pass(); |
| 309 return true; | 303 return true; |
| 310 } | 304 } |
| 311 | 305 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 339 | 333 |
| 340 // Any input event cancels a pending mouse move event. | 334 // Any input event cancels a pending mouse move event. |
| 341 next_mouse_move_.reset(); | 335 next_mouse_move_.reset(); |
| 342 | 336 |
| 343 OfferToHandlers(input_event, latency_info, is_keyboard_shortcut); | 337 OfferToHandlers(input_event, latency_info, is_keyboard_shortcut); |
| 344 } | 338 } |
| 345 | 339 |
| 346 void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, | 340 void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, |
| 347 const ui::LatencyInfo& latency_info, | 341 const ui::LatencyInfo& latency_info, |
| 348 bool is_keyboard_shortcut) { | 342 bool is_keyboard_shortcut) { |
| 349 if (OfferToOverscrollController(input_event, latency_info)) | |
| 350 return; | |
| 351 | |
| 352 if (OfferToClient(input_event, latency_info)) | 343 if (OfferToClient(input_event, latency_info)) |
| 353 return; | 344 return; |
| 354 | 345 |
| 355 OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); | 346 OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); |
| 356 | 347 |
| 357 // Touch events should always indicate in the event whether they are | 348 // Touch events should always indicate in the event whether they are |
| 358 // cancelable (respect ACK disposition) or not. | 349 // cancelable (respect ACK disposition) or not. |
| 359 bool ignores_ack = WebInputEventTraits::IgnoresAckDisposition(input_event); | 350 bool ignores_ack = WebInputEventTraits::IgnoresAckDisposition(input_event); |
| 360 if (WebInputEvent::isTouchEventType(input_event.type)) { | 351 if (WebInputEvent::isTouchEventType(input_event.type)) { |
| 361 DCHECK(!ignores_ack == | 352 DCHECK(!ignores_ack == |
| 362 static_cast<const blink::WebTouchEvent&>(input_event).cancelable); | 353 static_cast<const blink::WebTouchEvent&>(input_event).cancelable); |
| 363 } | 354 } |
| 364 | 355 |
| 365 // If we don't care about the ack disposition, send the ack immediately. | 356 // If we don't care about the ack disposition, send the ack immediately. |
| 366 if (ignores_ack) { | 357 if (ignores_ack) { |
| 367 ProcessInputEventAck(input_event.type, | 358 ProcessInputEventAck(input_event.type, |
| 368 INPUT_EVENT_ACK_STATE_IGNORED, | 359 INPUT_EVENT_ACK_STATE_IGNORED, |
| 369 latency_info, | 360 latency_info, |
| 370 IGNORING_DISPOSITION); | 361 IGNORING_DISPOSITION); |
| 371 } | 362 } |
| 372 } | 363 } |
| 373 | 364 |
| 374 bool InputRouterImpl::OfferToOverscrollController( | |
| 375 const WebInputEvent& input_event, | |
| 376 const ui::LatencyInfo& latency_info) { | |
| 377 OverscrollController* controller = client_->GetOverscrollController(); | |
| 378 if (!controller) | |
| 379 return false; | |
| 380 | |
| 381 OverscrollController::Disposition disposition = | |
| 382 controller->DispatchEvent(input_event, latency_info); | |
| 383 | |
| 384 bool consumed = disposition == OverscrollController::CONSUMED; | |
| 385 | |
| 386 if (disposition == OverscrollController::SHOULD_FORWARD_TO_GESTURE_QUEUE) { | |
| 387 DCHECK(WebInputEvent::isGestureEventType(input_event.type)); | |
| 388 const blink::WebGestureEvent& gesture_event = | |
| 389 static_cast<const blink::WebGestureEvent&>(input_event); | |
| 390 // An ACK is expected for the event, so mark it as consumed. | |
| 391 consumed = !gesture_event_queue_.ShouldForward( | |
| 392 GestureEventWithLatencyInfo(gesture_event, latency_info)); | |
| 393 } | |
| 394 | |
| 395 if (consumed) { | |
| 396 InputEventAckState overscroll_ack = | |
| 397 WebInputEvent::isTouchEventType(input_event.type) ? | |
| 398 INPUT_EVENT_ACK_STATE_NOT_CONSUMED : INPUT_EVENT_ACK_STATE_CONSUMED; | |
| 399 ProcessInputEventAck(input_event.type, | |
| 400 overscroll_ack, | |
| 401 latency_info, | |
| 402 OVERSCROLL_CONTROLLER); | |
| 403 // WARNING: |this| may be deleted at this point. | |
| 404 } | |
| 405 | |
| 406 return consumed; | |
| 407 } | |
| 408 | |
| 409 bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event, | 365 bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event, |
| 410 const ui::LatencyInfo& latency_info) { | 366 const ui::LatencyInfo& latency_info) { |
| 411 bool consumed = false; | 367 bool consumed = false; |
| 412 | 368 |
| 413 InputEventAckState filter_ack = | 369 InputEventAckState filter_ack = |
| 414 client_->FilterInputEvent(input_event, latency_info); | 370 client_->FilterInputEvent(input_event, latency_info); |
| 415 switch (filter_ack) { | 371 switch (filter_ack) { |
| 416 case INPUT_EVENT_ACK_STATE_CONSUMED: | 372 case INPUT_EVENT_ACK_STATE_CONSUMED: |
| 417 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: | 373 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: |
| 418 // Send the ACK and early exit. | 374 // Send the ACK and early exit. |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 | 580 |
| 625 if (current_wheel_event_.synthesized_from_pinch) { | 581 if (current_wheel_event_.synthesized_from_pinch) { |
| 626 // Ack the GesturePinchUpdate event that generated this wheel event. | 582 // Ack the GesturePinchUpdate event that generated this wheel event. |
| 627 ProcessInputEventAck(WebInputEvent::GesturePinchUpdate, | 583 ProcessInputEventAck(WebInputEvent::GesturePinchUpdate, |
| 628 ack_result, | 584 ack_result, |
| 629 current_wheel_event_.event.latency, | 585 current_wheel_event_.event.latency, |
| 630 current_ack_source_); | 586 current_ack_source_); |
| 631 } else { | 587 } else { |
| 632 // Process the unhandled wheel event here before calling SendWheelEvent() | 588 // Process the unhandled wheel event here before calling SendWheelEvent() |
| 633 // since it will mutate current_wheel_event_. | 589 // since it will mutate current_wheel_event_. |
| 634 ProcessAckForOverscroll(current_wheel_event_.event.event, ack_result); | |
| 635 ack_handler_->OnWheelEventAck(current_wheel_event_.event, ack_result); | 590 ack_handler_->OnWheelEventAck(current_wheel_event_.event, ack_result); |
| 636 } | 591 } |
| 637 | 592 |
| 638 // Mark the wheel event complete only after the ACKs have been handled above. | 593 // Mark the wheel event complete only after the ACKs have been handled above. |
| 639 // For example, ACKing the GesturePinchUpdate could cause another | 594 // For example, ACKing the GesturePinchUpdate could cause another |
| 640 // GesturePinchUpdate to be sent, which should queue a wheel event rather than | 595 // GesturePinchUpdate to be sent, which should queue a wheel event rather than |
| 641 // send it immediately. | 596 // send it immediately. |
| 642 mouse_wheel_pending_ = false; | 597 mouse_wheel_pending_ = false; |
| 643 | 598 |
| 644 // Send the next (coalesced or synthetic) mouse wheel event. | 599 // Send the next (coalesced or synthetic) mouse wheel event. |
| 645 if (!coalesced_mouse_wheel_events_.empty()) { | 600 if (!coalesced_mouse_wheel_events_.empty()) { |
| 646 QueuedWheelEvent next_wheel_event = coalesced_mouse_wheel_events_.front(); | 601 QueuedWheelEvent next_wheel_event = coalesced_mouse_wheel_events_.front(); |
| 647 coalesced_mouse_wheel_events_.pop_front(); | 602 coalesced_mouse_wheel_events_.pop_front(); |
| 648 SendWheelEvent(next_wheel_event); | 603 SendWheelEvent(next_wheel_event); |
| 649 } | 604 } |
| 650 } | 605 } |
| 651 | 606 |
| 652 void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type, | 607 void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type, |
| 653 InputEventAckState ack_result, | 608 InputEventAckState ack_result, |
| 654 const ui::LatencyInfo& latency) { | 609 const ui::LatencyInfo& latency) { |
| 655 // If |ack_result| originated from the overscroll controller, only | 610 if (!gesture_event_queue_.ExpectingGestureAck()) |
| 656 // feed |gesture_event_queue_| the ack if it was expecting one. | |
| 657 if (current_ack_source_ == OVERSCROLL_CONTROLLER && | |
| 658 !gesture_event_queue_.ExpectingGestureAck()) { | |
| 659 return; | 611 return; |
| 660 } | |
| 661 | 612 |
| 662 // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. | 613 // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. |
| 663 gesture_event_queue_.ProcessGestureAck(ack_result, type, latency); | 614 gesture_event_queue_.ProcessGestureAck(ack_result, type, latency); |
| 664 } | 615 } |
| 665 | 616 |
| 666 void InputRouterImpl::ProcessTouchAck( | 617 void InputRouterImpl::ProcessTouchAck( |
| 667 InputEventAckState ack_result, | 618 InputEventAckState ack_result, |
| 668 const ui::LatencyInfo& latency) { | 619 const ui::LatencyInfo& latency) { |
| 669 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. | 620 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. |
| 670 touch_event_queue_.ProcessTouchAck(ack_result, latency); | 621 touch_event_queue_.ProcessTouchAck(ack_result, latency); |
| 671 } | 622 } |
| 672 | 623 |
| 673 void InputRouterImpl::ProcessAckForOverscroll(const WebInputEvent& event, | |
| 674 InputEventAckState ack_result) { | |
| 675 // Acks sent from the overscroll controller need not be fed back into the | |
| 676 // overscroll controller. | |
| 677 if (current_ack_source_ == OVERSCROLL_CONTROLLER) | |
| 678 return; | |
| 679 | |
| 680 OverscrollController* controller = client_->GetOverscrollController(); | |
| 681 if (!controller) | |
| 682 return; | |
| 683 | |
| 684 controller->ReceivedEventACK( | |
| 685 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); | |
| 686 } | |
| 687 | |
| 688 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { | 624 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { |
| 689 // Mobile sites tend to be well-behaved with respect to touch handling, so | 625 // Mobile sites tend to be well-behaved with respect to touch handling, so |
| 690 // they have less need for the touch timeout fallback. | 626 // they have less need for the touch timeout fallback. |
| 691 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; | 627 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; |
| 692 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; | 628 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; |
| 693 | 629 |
| 694 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves | 630 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves |
| 695 // little purpose. It's also a strong signal that touch handling is critical | 631 // little purpose. It's also a strong signal that touch handling is critical |
| 696 // to page functionality, so the timeout could do more harm than good. | 632 // to page functionality, so the timeout could do more harm than good. |
| 697 const bool touch_action_none = | 633 const bool touch_action_none = |
| (...skipping 19 matching lines...) Expand all Loading... |
| 717 bool InputRouterImpl::HasPendingEvents() const { | 653 bool InputRouterImpl::HasPendingEvents() const { |
| 718 return !touch_event_queue_.empty() || | 654 return !touch_event_queue_.empty() || |
| 719 !gesture_event_queue_.empty() || | 655 !gesture_event_queue_.empty() || |
| 720 !key_queue_.empty() || | 656 !key_queue_.empty() || |
| 721 mouse_move_pending_ || | 657 mouse_move_pending_ || |
| 722 mouse_wheel_pending_ || | 658 mouse_wheel_pending_ || |
| 723 select_range_pending_ || | 659 select_range_pending_ || |
| 724 move_caret_pending_; | 660 move_caret_pending_; |
| 725 } | 661 } |
| 726 | 662 |
| 727 bool InputRouterImpl::IsInOverscrollGesture() const { | |
| 728 OverscrollController* controller = client_->GetOverscrollController(); | |
| 729 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; | |
| 730 } | |
| 731 | |
| 732 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent() | 663 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent() |
| 733 : synthesized_from_pinch(false) { | 664 : synthesized_from_pinch(false) { |
| 734 } | 665 } |
| 735 | 666 |
| 736 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( | 667 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( |
| 737 const MouseWheelEventWithLatencyInfo& event, | 668 const MouseWheelEventWithLatencyInfo& event, |
| 738 bool synthesized_from_pinch) | 669 bool synthesized_from_pinch) |
| 739 : event(event), synthesized_from_pinch(synthesized_from_pinch) { | 670 : event(event), synthesized_from_pinch(synthesized_from_pinch) { |
| 740 } | 671 } |
| 741 | 672 |
| 742 InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { | 673 InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { |
| 743 } | 674 } |
| 744 | 675 |
| 745 } // namespace content | 676 } // namespace content |
| OLD | NEW |