| 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 "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "content/common/view_messages.h" | 22 #include "content/common/view_messages.h" |
| 23 #include "content/port/common/input_event_ack_state.h" | 23 #include "content/port/common/input_event_ack_state.h" |
| 24 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
| 25 #include "content/public/browser/notification_types.h" | 25 #include "content/public/browser/notification_types.h" |
| 26 #include "content/public/browser/user_metrics.h" | 26 #include "content/public/browser/user_metrics.h" |
| 27 #include "content/public/common/content_switches.h" | 27 #include "content/public/common/content_switches.h" |
| 28 #include "ipc/ipc_sender.h" | 28 #include "ipc/ipc_sender.h" |
| 29 #include "ui/events/event.h" | 29 #include "ui/events/event.h" |
| 30 #include "ui/events/keycodes/keyboard_codes.h" | 30 #include "ui/events/keycodes/keyboard_codes.h" |
| 31 | 31 |
| 32 #if defined(OS_ANDROID) |
| 33 #include "ui/gfx/android/view_configuration.h" |
| 34 #include "ui/gfx/screen.h" |
| 35 #else |
| 36 #include "ui/events/gestures/gesture_configuration.h" |
| 37 #endif |
| 38 |
| 32 using base::Time; | 39 using base::Time; |
| 33 using base::TimeDelta; | 40 using base::TimeDelta; |
| 34 using base::TimeTicks; | 41 using base::TimeTicks; |
| 35 using blink::WebGestureEvent; | 42 using blink::WebGestureEvent; |
| 36 using blink::WebInputEvent; | 43 using blink::WebInputEvent; |
| 37 using blink::WebKeyboardEvent; | 44 using blink::WebKeyboardEvent; |
| 38 using blink::WebMouseEvent; | 45 using blink::WebMouseEvent; |
| 39 using blink::WebMouseWheelEvent; | 46 using blink::WebMouseWheelEvent; |
| 40 | 47 |
| 41 namespace content { | 48 namespace content { |
| 42 namespace { | 49 namespace { |
| 43 | 50 |
| 51 // TODO(jdduke): Instead of relying on command line flags or conditional |
| 52 // conditional compilation here, we should instead use an InputRouter::Settings |
| 53 // construct, supplied and customized by the RenderWidgetHostView. See |
| 54 // crbug.com/343917. |
| 55 bool GetTouchAckTimeoutDelay(base::TimeDelta* touch_ack_timeout_delay) { |
| 56 CommandLine* parsed_command_line = CommandLine::ForCurrentProcess(); |
| 57 if (!parsed_command_line->HasSwitch(switches::kTouchAckTimeoutDelayMs)) |
| 58 return false; |
| 59 |
| 60 std::string timeout_string = parsed_command_line->GetSwitchValueASCII( |
| 61 switches::kTouchAckTimeoutDelayMs); |
| 62 size_t timeout_ms; |
| 63 if (!base::StringToSizeT(timeout_string, &timeout_ms)) |
| 64 return false; |
| 65 |
| 66 *touch_ack_timeout_delay = base::TimeDelta::FromMilliseconds(timeout_ms); |
| 67 return true; |
| 68 } |
| 69 |
| 70 #if defined(OS_ANDROID) |
| 71 double GetTouchMoveSlopSuppressionLengthDips() { |
| 72 const double touch_slop_length_pixels = |
| 73 static_cast<double>(gfx::ViewConfiguration::GetTouchSlopInPixels()); |
| 74 const double device_scale_factor = |
| 75 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor(); |
| 76 return touch_slop_length_pixels / device_scale_factor; |
| 77 } |
| 78 #elif defined(USE_AURA) |
| 79 double GetTouchMoveSlopSuppressionLengthDips() { |
| 80 return ui::GestureConfiguration::max_touch_move_in_pixels_for_click(); |
| 81 } |
| 82 #else |
| 83 double GetTouchMoveSlopSuppressionLengthDips() { |
| 84 return 0; |
| 85 } |
| 86 #endif |
| 87 |
| 88 TouchEventQueue::TouchScrollingMode GetTouchScrollingMode() { |
| 89 std::string modeString = CommandLine::ForCurrentProcess()-> |
| 90 GetSwitchValueASCII(switches::kTouchScrollingMode); |
| 91 if (modeString == switches::kTouchScrollingModeAsyncTouchmove) |
| 92 return TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE; |
| 93 if (modeString == switches::kTouchScrollingModeSyncTouchmove) |
| 94 return TouchEventQueue::TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE; |
| 95 if (modeString == switches::kTouchScrollingModeTouchcancel) |
| 96 return TouchEventQueue::TOUCH_SCROLLING_MODE_TOUCHCANCEL; |
| 97 if (modeString != "") |
| 98 LOG(ERROR) << "Invalid --touch-scrolling-mode option: " << modeString; |
| 99 return TouchEventQueue::TOUCH_SCROLLING_MODE_DEFAULT; |
| 100 } |
| 101 |
| 44 const char* GetEventAckName(InputEventAckState ack_result) { | 102 const char* GetEventAckName(InputEventAckState ack_result) { |
| 45 switch(ack_result) { | 103 switch(ack_result) { |
| 46 case INPUT_EVENT_ACK_STATE_UNKNOWN: return "UNKNOWN"; | 104 case INPUT_EVENT_ACK_STATE_UNKNOWN: return "UNKNOWN"; |
| 47 case INPUT_EVENT_ACK_STATE_CONSUMED: return "CONSUMED"; | 105 case INPUT_EVENT_ACK_STATE_CONSUMED: return "CONSUMED"; |
| 48 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED"; | 106 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED"; |
| 49 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS"; | 107 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS"; |
| 50 case INPUT_EVENT_ACK_STATE_IGNORED: return "IGNORED"; | 108 case INPUT_EVENT_ACK_STATE_IGNORED: return "IGNORED"; |
| 51 } | 109 } |
| 52 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName."; | 110 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName."; |
| 53 return ""; | 111 return ""; |
| 54 } | 112 } |
| 55 | 113 |
| 56 } // namespace | 114 } // namespace |
| 57 | 115 |
| 58 InputRouterImpl::Config::Config() { | |
| 59 } | |
| 60 | |
| 61 InputRouterImpl::InputRouterImpl(IPC::Sender* sender, | 116 InputRouterImpl::InputRouterImpl(IPC::Sender* sender, |
| 62 InputRouterClient* client, | 117 InputRouterClient* client, |
| 63 InputAckHandler* ack_handler, | 118 InputAckHandler* ack_handler, |
| 64 int routing_id, | 119 int routing_id) |
| 65 const Config& config) | |
| 66 : sender_(sender), | 120 : sender_(sender), |
| 67 client_(client), | 121 client_(client), |
| 68 ack_handler_(ack_handler), | 122 ack_handler_(ack_handler), |
| 69 routing_id_(routing_id), | 123 routing_id_(routing_id), |
| 70 select_range_pending_(false), | 124 select_range_pending_(false), |
| 71 move_caret_pending_(false), | 125 move_caret_pending_(false), |
| 72 mouse_move_pending_(false), | 126 mouse_move_pending_(false), |
| 73 mouse_wheel_pending_(false), | 127 mouse_wheel_pending_(false), |
| 128 touch_ack_timeout_supported_(false), |
| 74 current_view_flags_(0), | 129 current_view_flags_(0), |
| 75 current_ack_source_(ACK_SOURCE_NONE), | 130 current_ack_source_(ACK_SOURCE_NONE), |
| 76 flush_requested_(false), | 131 flush_requested_(false), |
| 77 touch_event_queue_(this, config.touch_config), | 132 touch_event_queue_(this, |
| 78 gesture_event_queue_(this, this, config.gesture_config) { | 133 GetTouchScrollingMode(), |
| 134 GetTouchMoveSlopSuppressionLengthDips()), |
| 135 gesture_event_queue_(this, this) { |
| 79 DCHECK(sender); | 136 DCHECK(sender); |
| 80 DCHECK(client); | 137 DCHECK(client); |
| 81 DCHECK(ack_handler); | 138 DCHECK(ack_handler); |
| 139 touch_ack_timeout_supported_ = |
| 140 GetTouchAckTimeoutDelay(&touch_ack_timeout_delay_); |
| 82 UpdateTouchAckTimeoutEnabled(); | 141 UpdateTouchAckTimeoutEnabled(); |
| 83 } | 142 } |
| 84 | 143 |
| 85 InputRouterImpl::~InputRouterImpl() {} | 144 InputRouterImpl::~InputRouterImpl() {} |
| 86 | 145 |
| 87 void InputRouterImpl::Flush() { | 146 void InputRouterImpl::Flush() { |
| 88 flush_requested_ = true; | 147 flush_requested_ = true; |
| 89 SignalFlushedIfNecessary(); | 148 SignalFlushedIfNecessary(); |
| 90 } | 149 } |
| 91 | 150 |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 | 696 |
| 638 OverscrollController* controller = client_->GetOverscrollController(); | 697 OverscrollController* controller = client_->GetOverscrollController(); |
| 639 if (!controller) | 698 if (!controller) |
| 640 return; | 699 return; |
| 641 | 700 |
| 642 controller->ReceivedEventACK( | 701 controller->ReceivedEventACK( |
| 643 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); | 702 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); |
| 644 } | 703 } |
| 645 | 704 |
| 646 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { | 705 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { |
| 706 if (!touch_ack_timeout_supported_) { |
| 707 touch_event_queue_.SetAckTimeoutEnabled(false, base::TimeDelta()); |
| 708 return; |
| 709 } |
| 710 |
| 647 // Mobile sites tend to be well-behaved with respect to touch handling, so | 711 // Mobile sites tend to be well-behaved with respect to touch handling, so |
| 648 // they have less need for the touch timeout fallback. | 712 // they have less need for the touch timeout fallback. |
| 649 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; | 713 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; |
| 650 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; | 714 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; |
| 651 | 715 |
| 652 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves | 716 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves |
| 653 // little purpose. It's also a strong signal that touch handling is critical | 717 // little purpose. It's also a strong signal that touch handling is critical |
| 654 // to page functionality, so the timeout could do more harm than good. | 718 // to page functionality, so the timeout could do more harm than good. |
| 655 const bool touch_action_none = | 719 const bool touch_action_none = |
| 656 touch_action_filter_.allowed_touch_action() == TOUCH_ACTION_NONE; | 720 touch_action_filter_.allowed_touch_action() == TOUCH_ACTION_NONE; |
| 657 | 721 |
| 658 const bool touch_ack_timeout_enabled = !fixed_page_scale && | 722 const bool touch_ack_timeout_enabled = !fixed_page_scale && |
| 659 !mobile_viewport && | 723 !mobile_viewport && |
| 660 !touch_action_none; | 724 !touch_action_none; |
| 661 touch_event_queue_.SetAckTimeoutEnabled(touch_ack_timeout_enabled); | 725 touch_event_queue_.SetAckTimeoutEnabled(touch_ack_timeout_enabled, |
| 726 touch_ack_timeout_delay_); |
| 662 } | 727 } |
| 663 | 728 |
| 664 void InputRouterImpl::SignalFlushedIfNecessary() { | 729 void InputRouterImpl::SignalFlushedIfNecessary() { |
| 665 if (!flush_requested_) | 730 if (!flush_requested_) |
| 666 return; | 731 return; |
| 667 | 732 |
| 668 if (HasPendingEvents()) | 733 if (HasPendingEvents()) |
| 669 return; | 734 return; |
| 670 | 735 |
| 671 flush_requested_ = false; | 736 flush_requested_ = false; |
| 672 client_->DidFlush(); | 737 client_->DidFlush(); |
| 673 } | 738 } |
| 674 | 739 |
| 675 bool InputRouterImpl::HasPendingEvents() const { | 740 bool InputRouterImpl::HasPendingEvents() const { |
| 676 return !touch_event_queue_.empty() || | 741 return !touch_event_queue_.empty() || |
| 677 !gesture_event_queue_.empty() || | 742 !gesture_event_queue_.empty() || |
| 678 !key_queue_.empty() || | 743 !key_queue_.empty() || |
| 679 mouse_move_pending_ || | 744 mouse_move_pending_ || |
| 680 mouse_wheel_pending_ || | 745 mouse_wheel_pending_ || |
| 681 select_range_pending_ || | 746 select_range_pending_ || |
| 682 move_caret_pending_; | 747 move_caret_pending_; |
| 683 } | 748 } |
| 684 | 749 |
| 685 bool InputRouterImpl::IsInOverscrollGesture() const { | 750 bool InputRouterImpl::IsInOverscrollGesture() const { |
| 686 OverscrollController* controller = client_->GetOverscrollController(); | 751 OverscrollController* controller = client_->GetOverscrollController(); |
| 687 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; | 752 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; |
| 688 } | 753 } |
| 689 | 754 |
| 690 } // namespace content | 755 } // namespace content |
| OLD | NEW |