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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 InputAckHandler* ack_handler, | 135 InputAckHandler* ack_handler, |
136 int routing_id) | 136 int routing_id) |
137 : sender_(sender), | 137 : sender_(sender), |
138 client_(client), | 138 client_(client), |
139 ack_handler_(ack_handler), | 139 ack_handler_(ack_handler), |
140 routing_id_(routing_id), | 140 routing_id_(routing_id), |
141 select_range_pending_(false), | 141 select_range_pending_(false), |
142 move_caret_pending_(false), | 142 move_caret_pending_(false), |
143 mouse_move_pending_(false), | 143 mouse_move_pending_(false), |
144 mouse_wheel_pending_(false), | 144 mouse_wheel_pending_(false), |
145 touch_ack_timeout_enabled_(false), | 145 touch_ack_timeout_supported_(false), |
146 touch_ack_timeout_delay_ms_(std::numeric_limits<size_t>::max()), | 146 touch_ack_timeout_delay_ms_(std::numeric_limits<size_t>::max()), |
147 current_view_flags_(0), | |
147 current_ack_source_(ACK_SOURCE_NONE), | 148 current_ack_source_(ACK_SOURCE_NONE), |
148 gesture_event_queue_(new GestureEventQueue(this, this)) { | 149 gesture_event_queue_(new GestureEventQueue(this, this)) { |
149 DCHECK(sender); | 150 DCHECK(sender); |
150 DCHECK(client); | 151 DCHECK(client); |
151 DCHECK(ack_handler); | 152 DCHECK(ack_handler); |
152 touch_event_queue_.reset(new TouchEventQueue( | 153 touch_event_queue_.reset(new TouchEventQueue( |
153 this, GetTouchScrollingMode(), GetTouchMoveSlopSuppressionLengthDips())); | 154 this, GetTouchScrollingMode(), GetTouchMoveSlopSuppressionLengthDips())); |
154 touch_ack_timeout_enabled_ = | 155 touch_ack_timeout_supported_ = |
155 GetTouchAckTimeoutDelayMs(&touch_ack_timeout_delay_ms_); | 156 GetTouchAckTimeoutDelayMs(&touch_ack_timeout_delay_ms_); |
156 touch_event_queue_->SetAckTimeoutEnabled(touch_ack_timeout_enabled_, | 157 UpdateTouchAckTimeoutEnabled(); |
157 touch_ack_timeout_delay_ms_); | |
158 } | 158 } |
159 | 159 |
160 InputRouterImpl::~InputRouterImpl() {} | 160 InputRouterImpl::~InputRouterImpl() {} |
161 | 161 |
162 void InputRouterImpl::Flush() {} | 162 void InputRouterImpl::Flush() {} |
163 | 163 |
164 bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) { | 164 bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) { |
165 DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart); | 165 DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart); |
166 switch (message->type()) { | 166 switch (message->type()) { |
167 // Check for types that require an ACK. | 167 // Check for types that require an ACK. |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 return; | 280 return; |
281 } | 281 } |
282 mouse_move_pending_ = true; | 282 mouse_move_pending_ = true; |
283 } | 283 } |
284 | 284 |
285 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false); | 285 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false); |
286 } | 286 } |
287 | 287 |
288 void InputRouterImpl::SendTouchEventImmediately( | 288 void InputRouterImpl::SendTouchEventImmediately( |
289 const TouchEventWithLatencyInfo& touch_event) { | 289 const TouchEventWithLatencyInfo& touch_event) { |
290 if (WebTouchEventTraits::IsTouchSequenceStart(touch_event.event)) | 290 if (WebTouchEventTraits::IsTouchSequenceStart(touch_event.event)) { |
291 touch_action_filter_.ResetTouchAction(); | 291 touch_action_filter_.ResetTouchAction(); |
292 UpdateTouchAckTimeoutEnabled(); | |
293 } | |
292 | 294 |
293 FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false); | 295 FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false); |
294 } | 296 } |
295 | 297 |
296 void InputRouterImpl::SendGestureEventImmediately( | 298 void InputRouterImpl::SendGestureEventImmediately( |
297 const GestureEventWithLatencyInfo& gesture_event) { | 299 const GestureEventWithLatencyInfo& gesture_event) { |
298 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); | 300 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); |
299 } | 301 } |
300 | 302 |
301 const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const { | 303 const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const { |
302 if (key_queue_.empty()) | 304 if (key_queue_.empty()) |
303 return NULL; | 305 return NULL; |
304 return &key_queue_.front(); | 306 return &key_queue_.front(); |
305 } | 307 } |
306 | 308 |
307 bool InputRouterImpl::ShouldForwardTouchEvent() const { | 309 bool InputRouterImpl::ShouldForwardTouchEvent() const { |
308 // Always send a touch event if the renderer has a touch-event handler. | 310 // Always send a touch event if the renderer has a touch-event handler. |
309 return touch_event_queue_->has_handlers(); | 311 return touch_event_queue_->has_handlers(); |
310 } | 312 } |
311 | 313 |
312 void InputRouterImpl::OnViewUpdated(int view_flags) { | 314 void InputRouterImpl::OnViewUpdated(int view_flags) { |
313 bool fixed_page_scale = (view_flags & FIXED_PAGE_SCALE) != 0; | 315 current_view_flags_ = view_flags; |
314 bool mobile_viewport = (view_flags & MOBILE_VIEWPORT) != 0; | 316 |
315 touch_event_queue_->SetAckTimeoutEnabled( | 317 // A fixed page scale or mobile viewport should disable the touch ack timeout. |
316 touch_ack_timeout_enabled_ && !(fixed_page_scale || mobile_viewport), | 318 UpdateTouchAckTimeoutEnabled(); |
317 touch_ack_timeout_delay_ms_); | |
318 } | 319 } |
319 | 320 |
320 bool InputRouterImpl::OnMessageReceived(const IPC::Message& message) { | 321 bool InputRouterImpl::OnMessageReceived(const IPC::Message& message) { |
321 bool handled = true; | 322 bool handled = true; |
322 bool message_is_ok = true; | 323 bool message_is_ok = true; |
323 IPC_BEGIN_MESSAGE_MAP_EX(InputRouterImpl, message, message_is_ok) | 324 IPC_BEGIN_MESSAGE_MAP_EX(InputRouterImpl, message, message_is_ok) |
324 IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck) | 325 IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck) |
325 IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck) | 326 IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck) |
326 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck) | 327 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck) |
327 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers, | 328 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers, |
328 OnHasTouchEventHandlers) | 329 OnHasTouchEventHandlers) |
329 IPC_MESSAGE_HANDLER(InputHostMsg_SetTouchAction, | 330 IPC_MESSAGE_HANDLER(InputHostMsg_SetTouchAction, |
330 OnSetTouchAction) | 331 OnSetTouchAction) |
331 IPC_MESSAGE_UNHANDLED(handled = false) | 332 IPC_MESSAGE_UNHANDLED(handled = false) |
332 IPC_END_MESSAGE_MAP() | 333 IPC_END_MESSAGE_MAP() |
333 | 334 |
334 if (!message_is_ok) | 335 if (!message_is_ok) |
335 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); | 336 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); |
336 | 337 |
337 return handled; | 338 return handled; |
338 } | 339 } |
339 | 340 |
340 void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event, | 341 void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event, |
341 InputEventAckState ack_result) { | 342 InputEventAckState ack_result) { |
342 // Touchstart events sent to the renderer indicate a new touch sequence, but | 343 // Touchstart events sent to the renderer indicate a new touch sequence, but |
343 // in some cases we may filter out sending the touchstart - catch those here. | 344 // in some cases we may filter out sending the touchstart - catch those here. |
344 if (WebTouchEventTraits::IsTouchSequenceStart(event.event) && | 345 if (WebTouchEventTraits::IsTouchSequenceStart(event.event) && |
345 ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) { | 346 ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) { |
346 touch_action_filter_.ResetTouchAction(); | 347 touch_action_filter_.ResetTouchAction(); |
348 UpdateTouchAckTimeoutEnabled(); | |
347 } | 349 } |
348 ack_handler_->OnTouchEventAck(event, ack_result); | 350 ack_handler_->OnTouchEventAck(event, ack_result); |
349 } | 351 } |
350 | 352 |
351 void InputRouterImpl::OnGestureEventAck( | 353 void InputRouterImpl::OnGestureEventAck( |
352 const GestureEventWithLatencyInfo& event, | 354 const GestureEventWithLatencyInfo& event, |
353 InputEventAckState ack_result) { | 355 InputEventAckState ack_result) { |
354 touch_event_queue_->OnGestureEventAck(event, ack_result); | 356 touch_event_queue_->OnGestureEventAck(event, ack_result); |
355 ProcessAckForOverscroll(event.event, ack_result); | 357 ProcessAckForOverscroll(event.event, ack_result); |
356 ack_handler_->OnGestureEventAck(event, ack_result); | 358 ack_handler_->OnGestureEventAck(event, ack_result); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 } | 554 } |
553 | 555 |
554 void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) { | 556 void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) { |
555 TRACE_EVENT1("input", "InputRouterImpl::OnHasTouchEventHandlers", | 557 TRACE_EVENT1("input", "InputRouterImpl::OnHasTouchEventHandlers", |
556 "has_handlers", has_handlers); | 558 "has_handlers", has_handlers); |
557 | 559 |
558 touch_event_queue_->OnHasTouchEventHandlers(has_handlers); | 560 touch_event_queue_->OnHasTouchEventHandlers(has_handlers); |
559 client_->OnHasTouchEventHandlers(has_handlers); | 561 client_->OnHasTouchEventHandlers(has_handlers); |
560 } | 562 } |
561 | 563 |
562 void InputRouterImpl::OnSetTouchAction( | 564 void InputRouterImpl::OnSetTouchAction(TouchAction touch_action) { |
563 content::TouchAction touch_action) { | |
564 // Synthetic touchstart events should get filtered out in RenderWidget. | 565 // Synthetic touchstart events should get filtered out in RenderWidget. |
565 DCHECK(touch_event_queue_->IsPendingAckTouchStart()); | 566 DCHECK(touch_event_queue_->IsPendingAckTouchStart()); |
566 | 567 |
567 touch_action_filter_.OnSetTouchAction(touch_action); | 568 touch_action_filter_.OnSetTouchAction(touch_action); |
569 | |
570 // TOUCH_ACTION_NONE should disable the touch ack timeout. | |
571 UpdateTouchAckTimeoutEnabled(); | |
568 } | 572 } |
569 | 573 |
570 void InputRouterImpl::ProcessInputEventAck( | 574 void InputRouterImpl::ProcessInputEventAck( |
571 WebInputEvent::Type event_type, | 575 WebInputEvent::Type event_type, |
572 InputEventAckState ack_result, | 576 InputEventAckState ack_result, |
573 const ui::LatencyInfo& latency_info, | 577 const ui::LatencyInfo& latency_info, |
574 AckSource ack_source) { | 578 AckSource ack_source) { |
575 TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck", | 579 TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck", |
576 "type", WebInputEventTraits::GetName(event_type), | 580 "type", WebInputEventTraits::GetName(event_type), |
577 "ack", GetEventAckName(ack_result)); | 581 "ack", GetEventAckName(ack_result)); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
767 SendGestureEvent(MakeGestureEvent( | 771 SendGestureEvent(MakeGestureEvent( |
768 WebInputEvent::GestureScrollEnd, mouse_event.timeStampSeconds, | 772 WebInputEvent::GestureScrollEnd, mouse_event.timeStampSeconds, |
769 x, y, 0, event.latency)); | 773 x, y, 0, event.latency)); |
770 } | 774 } |
771 break; | 775 break; |
772 case WebMouseEvent::ButtonNone: | 776 case WebMouseEvent::ButtonNone: |
773 break; | 777 break; |
774 } | 778 } |
775 } | 779 } |
776 | 780 |
781 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { | |
782 if (!touch_ack_timeout_supported_) { | |
783 touch_event_queue_->SetAckTimeoutEnabled(false, 0); | |
784 return; | |
785 } | |
786 | |
787 // Mobile sites tend to be well-behaved with respect to touch handling, so | |
788 // they have less need for the touch timeout fallback. | |
789 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; | |
790 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; | |
791 | |
792 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves | |
793 // little purpose. It's also a strong signal that touch handling is critical | |
Rick Byers
2014/03/05 21:24:23
nit: I believe chromium checkstyle will complain a
jdduke (slow)
2014/03/06 00:15:25
Done.
| |
794 // to page functionality, so the timeout could do more harm than good. | |
795 const bool touch_action_none = | |
796 touch_action_filter_.allowed_touch_action() == TOUCH_ACTION_NONE; | |
797 | |
798 const bool touch_ack_timeout_enabled = !fixed_page_scale && | |
799 !mobile_viewport && | |
800 !touch_action_none; | |
801 touch_event_queue_->SetAckTimeoutEnabled(touch_ack_timeout_enabled, | |
802 touch_ack_timeout_delay_ms_); | |
803 } | |
804 | |
777 bool InputRouterImpl::IsInOverscrollGesture() const { | 805 bool InputRouterImpl::IsInOverscrollGesture() const { |
778 OverscrollController* controller = client_->GetOverscrollController(); | 806 OverscrollController* controller = client_->GetOverscrollController(); |
779 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; | 807 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; |
780 } | 808 } |
781 | 809 |
782 } // namespace content | 810 } // namespace content |
OLD | NEW |