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 |