| 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 if (!gesture_event_queue_.ShouldForward(gesture_event)) |
| 188 !gesture_event_queue_.ShouldForward(gesture_event)) { | |
| 189 OverscrollController* controller = client_->GetOverscrollController(); | |
| 190 if (controller) | |
| 191 controller->DiscardingGestureEvent(gesture_event.event); | |
| 192 return; | 187 return; |
| 193 } | |
| 194 | 188 |
| 195 SendGestureEventImmediately(gesture_event); | 189 SendGestureEventImmediately(gesture_event); |
| 196 } | 190 } |
| 197 | 191 |
| 198 void InputRouterImpl::SendTouchEvent( | 192 void InputRouterImpl::SendTouchEvent( |
| 199 const TouchEventWithLatencyInfo& touch_event) { | 193 const TouchEventWithLatencyInfo& touch_event) { |
| 200 touch_event_queue_.QueueEvent(touch_event); | 194 touch_event_queue_.QueueEvent(touch_event); |
| 201 } | 195 } |
| 202 | 196 |
| 203 // Forwards MouseEvent without passing it through | 197 // Forwards MouseEvent without passing it through |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 touch_action_filter_.ResetTouchAction(); | 286 touch_action_filter_.ResetTouchAction(); |
| 293 UpdateTouchAckTimeoutEnabled(); | 287 UpdateTouchAckTimeoutEnabled(); |
| 294 } | 288 } |
| 295 ack_handler_->OnTouchEventAck(event, ack_result); | 289 ack_handler_->OnTouchEventAck(event, ack_result); |
| 296 } | 290 } |
| 297 | 291 |
| 298 void InputRouterImpl::OnGestureEventAck( | 292 void InputRouterImpl::OnGestureEventAck( |
| 299 const GestureEventWithLatencyInfo& event, | 293 const GestureEventWithLatencyInfo& event, |
| 300 InputEventAckState ack_result) { | 294 InputEventAckState ack_result) { |
| 301 touch_event_queue_.OnGestureEventAck(event, ack_result); | 295 touch_event_queue_.OnGestureEventAck(event, ack_result); |
| 302 ProcessAckForOverscroll(event.event, ack_result); | |
| 303 ack_handler_->OnGestureEventAck(event, ack_result); | 296 ack_handler_->OnGestureEventAck(event, ack_result); |
| 304 } | 297 } |
| 305 | 298 |
| 306 bool InputRouterImpl::SendSelectRange(scoped_ptr<IPC::Message> message) { | 299 bool InputRouterImpl::SendSelectRange(scoped_ptr<IPC::Message> message) { |
| 307 DCHECK(message->type() == InputMsg_SelectRange::ID); | 300 DCHECK(message->type() == InputMsg_SelectRange::ID); |
| 308 if (select_range_pending_) { | 301 if (select_range_pending_) { |
| 309 next_selection_range_ = message.Pass(); | 302 next_selection_range_ = message.Pass(); |
| 310 return true; | 303 return true; |
| 311 } | 304 } |
| 312 | 305 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 340 | 333 |
| 341 // Any input event cancels a pending mouse move event. | 334 // Any input event cancels a pending mouse move event. |
| 342 next_mouse_move_.reset(); | 335 next_mouse_move_.reset(); |
| 343 | 336 |
| 344 OfferToHandlers(input_event, latency_info, is_keyboard_shortcut); | 337 OfferToHandlers(input_event, latency_info, is_keyboard_shortcut); |
| 345 } | 338 } |
| 346 | 339 |
| 347 void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, | 340 void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, |
| 348 const ui::LatencyInfo& latency_info, | 341 const ui::LatencyInfo& latency_info, |
| 349 bool is_keyboard_shortcut) { | 342 bool is_keyboard_shortcut) { |
| 350 if (OfferToOverscrollController(input_event, latency_info)) | |
| 351 return; | |
| 352 | |
| 353 if (OfferToClient(input_event, latency_info)) | 343 if (OfferToClient(input_event, latency_info)) |
| 354 return; | 344 return; |
| 355 | 345 |
| 356 OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); | 346 OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); |
| 357 | 347 |
| 358 // Touch events should always indicate in the event whether they are | 348 // Touch events should always indicate in the event whether they are |
| 359 // cancelable (respect ACK disposition) or not. | 349 // cancelable (respect ACK disposition) or not. |
| 360 bool ignores_ack = WebInputEventTraits::IgnoresAckDisposition(input_event); | 350 bool ignores_ack = WebInputEventTraits::IgnoresAckDisposition(input_event); |
| 361 if (WebInputEvent::isTouchEventType(input_event.type)) { | 351 if (WebInputEvent::isTouchEventType(input_event.type)) { |
| 362 DCHECK(!ignores_ack == | 352 DCHECK(!ignores_ack == |
| 363 static_cast<const blink::WebTouchEvent&>(input_event).cancelable); | 353 static_cast<const blink::WebTouchEvent&>(input_event).cancelable); |
| 364 } | 354 } |
| 365 | 355 |
| 366 // 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. |
| 367 if (ignores_ack) { | 357 if (ignores_ack) { |
| 368 ProcessInputEventAck(input_event.type, | 358 ProcessInputEventAck(input_event.type, |
| 369 INPUT_EVENT_ACK_STATE_IGNORED, | 359 INPUT_EVENT_ACK_STATE_IGNORED, |
| 370 latency_info, | 360 latency_info, |
| 371 IGNORING_DISPOSITION); | 361 IGNORING_DISPOSITION); |
| 372 } | 362 } |
| 373 } | 363 } |
| 374 | 364 |
| 375 bool InputRouterImpl::OfferToOverscrollController( | |
| 376 const WebInputEvent& input_event, | |
| 377 const ui::LatencyInfo& latency_info) { | |
| 378 OverscrollController* controller = client_->GetOverscrollController(); | |
| 379 if (!controller) | |
| 380 return false; | |
| 381 | |
| 382 OverscrollController::Disposition disposition = | |
| 383 controller->DispatchEvent(input_event, latency_info); | |
| 384 | |
| 385 bool consumed = disposition == OverscrollController::CONSUMED; | |
| 386 | |
| 387 if (disposition == OverscrollController::SHOULD_FORWARD_TO_GESTURE_QUEUE) { | |
| 388 DCHECK(WebInputEvent::isGestureEventType(input_event.type)); | |
| 389 const blink::WebGestureEvent& gesture_event = | |
| 390 static_cast<const blink::WebGestureEvent&>(input_event); | |
| 391 // An ACK is expected for the event, so mark it as consumed. | |
| 392 consumed = !gesture_event_queue_.ShouldForward( | |
| 393 GestureEventWithLatencyInfo(gesture_event, latency_info)); | |
| 394 } | |
| 395 | |
| 396 if (consumed) { | |
| 397 InputEventAckState overscroll_ack = | |
| 398 WebInputEvent::isTouchEventType(input_event.type) ? | |
| 399 INPUT_EVENT_ACK_STATE_NOT_CONSUMED : INPUT_EVENT_ACK_STATE_CONSUMED; | |
| 400 ProcessInputEventAck(input_event.type, | |
| 401 overscroll_ack, | |
| 402 latency_info, | |
| 403 OVERSCROLL_CONTROLLER); | |
| 404 // WARNING: |this| may be deleted at this point. | |
| 405 } | |
| 406 | |
| 407 return consumed; | |
| 408 } | |
| 409 | |
| 410 bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event, | 365 bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event, |
| 411 const ui::LatencyInfo& latency_info) { | 366 const ui::LatencyInfo& latency_info) { |
| 412 bool consumed = false; | 367 bool consumed = false; |
| 413 | 368 |
| 414 InputEventAckState filter_ack = | 369 InputEventAckState filter_ack = |
| 415 client_->FilterInputEvent(input_event, latency_info); | 370 client_->FilterInputEvent(input_event, latency_info); |
| 416 switch (filter_ack) { | 371 switch (filter_ack) { |
| 417 case INPUT_EVENT_ACK_STATE_CONSUMED: | 372 case INPUT_EVENT_ACK_STATE_CONSUMED: |
| 418 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: | 373 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: |
| 419 // Send the ACK and early exit. | 374 // Send the ACK and early exit. |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 | 598 |
| 644 if (current_wheel_event_.synthesized_from_pinch) { | 599 if (current_wheel_event_.synthesized_from_pinch) { |
| 645 // Ack the GesturePinchUpdate event that generated this wheel event. | 600 // Ack the GesturePinchUpdate event that generated this wheel event. |
| 646 ProcessInputEventAck(WebInputEvent::GesturePinchUpdate, | 601 ProcessInputEventAck(WebInputEvent::GesturePinchUpdate, |
| 647 ack_result, | 602 ack_result, |
| 648 current_wheel_event_.event.latency, | 603 current_wheel_event_.event.latency, |
| 649 current_ack_source_); | 604 current_ack_source_); |
| 650 } else { | 605 } else { |
| 651 // Process the unhandled wheel event here before calling SendWheelEvent() | 606 // Process the unhandled wheel event here before calling SendWheelEvent() |
| 652 // since it will mutate current_wheel_event_. | 607 // since it will mutate current_wheel_event_. |
| 653 ProcessAckForOverscroll(current_wheel_event_.event.event, ack_result); | |
| 654 ack_handler_->OnWheelEventAck(current_wheel_event_.event, ack_result); | 608 ack_handler_->OnWheelEventAck(current_wheel_event_.event, ack_result); |
| 655 } | 609 } |
| 656 | 610 |
| 657 // Mark the wheel event complete only after the ACKs have been handled above. | 611 // Mark the wheel event complete only after the ACKs have been handled above. |
| 658 // For example, ACKing the GesturePinchUpdate could cause another | 612 // For example, ACKing the GesturePinchUpdate could cause another |
| 659 // GesturePinchUpdate to be sent, which should queue a wheel event rather than | 613 // GesturePinchUpdate to be sent, which should queue a wheel event rather than |
| 660 // send it immediately. | 614 // send it immediately. |
| 661 mouse_wheel_pending_ = false; | 615 mouse_wheel_pending_ = false; |
| 662 | 616 |
| 663 // Send the next (coalesced or synthetic) mouse wheel event. | 617 // Send the next (coalesced or synthetic) mouse wheel event. |
| 664 if (!coalesced_mouse_wheel_events_.empty()) { | 618 if (!coalesced_mouse_wheel_events_.empty()) { |
| 665 QueuedWheelEvent next_wheel_event = coalesced_mouse_wheel_events_.front(); | 619 QueuedWheelEvent next_wheel_event = coalesced_mouse_wheel_events_.front(); |
| 666 coalesced_mouse_wheel_events_.pop_front(); | 620 coalesced_mouse_wheel_events_.pop_front(); |
| 667 SendWheelEvent(next_wheel_event); | 621 SendWheelEvent(next_wheel_event); |
| 668 } | 622 } |
| 669 } | 623 } |
| 670 | 624 |
| 671 void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type, | 625 void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type, |
| 672 InputEventAckState ack_result, | 626 InputEventAckState ack_result, |
| 673 const ui::LatencyInfo& latency) { | 627 const ui::LatencyInfo& latency) { |
| 674 // If |ack_result| originated from the overscroll controller, only | 628 if (!gesture_event_queue_.ExpectingGestureAck()) |
| 675 // feed |gesture_event_queue_| the ack if it was expecting one. | |
| 676 if (current_ack_source_ == OVERSCROLL_CONTROLLER && | |
| 677 !gesture_event_queue_.ExpectingGestureAck()) { | |
| 678 return; | 629 return; |
| 679 } | |
| 680 | 630 |
| 681 // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. | 631 // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. |
| 682 gesture_event_queue_.ProcessGestureAck(ack_result, type, latency); | 632 gesture_event_queue_.ProcessGestureAck(ack_result, type, latency); |
| 683 } | 633 } |
| 684 | 634 |
| 685 void InputRouterImpl::ProcessTouchAck( | 635 void InputRouterImpl::ProcessTouchAck( |
| 686 InputEventAckState ack_result, | 636 InputEventAckState ack_result, |
| 687 const ui::LatencyInfo& latency) { | 637 const ui::LatencyInfo& latency) { |
| 688 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. | 638 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. |
| 689 touch_event_queue_.ProcessTouchAck(ack_result, latency); | 639 touch_event_queue_.ProcessTouchAck(ack_result, latency); |
| 690 } | 640 } |
| 691 | 641 |
| 692 void InputRouterImpl::ProcessAckForOverscroll(const WebInputEvent& event, | |
| 693 InputEventAckState ack_result) { | |
| 694 // Acks sent from the overscroll controller need not be fed back into the | |
| 695 // overscroll controller. | |
| 696 if (current_ack_source_ == OVERSCROLL_CONTROLLER) | |
| 697 return; | |
| 698 | |
| 699 OverscrollController* controller = client_->GetOverscrollController(); | |
| 700 if (!controller) | |
| 701 return; | |
| 702 | |
| 703 controller->ReceivedEventACK( | |
| 704 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); | |
| 705 } | |
| 706 | |
| 707 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { | 642 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { |
| 708 // Mobile sites tend to be well-behaved with respect to touch handling, so | 643 // Mobile sites tend to be well-behaved with respect to touch handling, so |
| 709 // they have less need for the touch timeout fallback. | 644 // they have less need for the touch timeout fallback. |
| 710 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; | 645 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; |
| 711 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; | 646 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; |
| 712 | 647 |
| 713 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves | 648 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves |
| 714 // little purpose. It's also a strong signal that touch handling is critical | 649 // little purpose. It's also a strong signal that touch handling is critical |
| 715 // to page functionality, so the timeout could do more harm than good. | 650 // to page functionality, so the timeout could do more harm than good. |
| 716 const bool touch_action_none = | 651 const bool touch_action_none = |
| (...skipping 19 matching lines...) Expand all Loading... |
| 736 bool InputRouterImpl::HasPendingEvents() const { | 671 bool InputRouterImpl::HasPendingEvents() const { |
| 737 return !touch_event_queue_.empty() || | 672 return !touch_event_queue_.empty() || |
| 738 !gesture_event_queue_.empty() || | 673 !gesture_event_queue_.empty() || |
| 739 !key_queue_.empty() || | 674 !key_queue_.empty() || |
| 740 mouse_move_pending_ || | 675 mouse_move_pending_ || |
| 741 mouse_wheel_pending_ || | 676 mouse_wheel_pending_ || |
| 742 select_range_pending_ || | 677 select_range_pending_ || |
| 743 move_caret_pending_; | 678 move_caret_pending_; |
| 744 } | 679 } |
| 745 | 680 |
| 746 bool InputRouterImpl::IsInOverscrollGesture() const { | |
| 747 OverscrollController* controller = client_->GetOverscrollController(); | |
| 748 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; | |
| 749 } | |
| 750 | |
| 751 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent() | 681 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent() |
| 752 : synthesized_from_pinch(false) { | 682 : synthesized_from_pinch(false) { |
| 753 } | 683 } |
| 754 | 684 |
| 755 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( | 685 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( |
| 756 const MouseWheelEventWithLatencyInfo& event, | 686 const MouseWheelEventWithLatencyInfo& event, |
| 757 bool synthesized_from_pinch) | 687 bool synthesized_from_pinch) |
| 758 : event(event), synthesized_from_pinch(synthesized_from_pinch) { | 688 : event(event), synthesized_from_pinch(synthesized_from_pinch) { |
| 759 } | 689 } |
| 760 | 690 |
| 761 InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { | 691 InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { |
| 762 } | 692 } |
| 763 | 693 |
| 764 } // namespace content | 694 } // namespace content |
| OLD | NEW |