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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 | 599 |
645 if (current_wheel_event_.synthesized_from_pinch) { | 600 if (current_wheel_event_.synthesized_from_pinch) { |
646 // Ack the GesturePinchUpdate event that generated this wheel event. | 601 // Ack the GesturePinchUpdate event that generated this wheel event. |
647 ProcessInputEventAck(WebInputEvent::GesturePinchUpdate, | 602 ProcessInputEventAck(WebInputEvent::GesturePinchUpdate, |
648 ack_result, | 603 ack_result, |
649 current_wheel_event_.event.latency, | 604 current_wheel_event_.event.latency, |
650 current_ack_source_); | 605 current_ack_source_); |
651 } else { | 606 } else { |
652 // Process the unhandled wheel event here before calling SendWheelEvent() | 607 // Process the unhandled wheel event here before calling SendWheelEvent() |
653 // since it will mutate current_wheel_event_. | 608 // since it will mutate current_wheel_event_. |
654 ProcessAckForOverscroll(current_wheel_event_.event.event, ack_result); | |
655 ack_handler_->OnWheelEventAck(current_wheel_event_.event, ack_result); | 609 ack_handler_->OnWheelEventAck(current_wheel_event_.event, ack_result); |
656 } | 610 } |
657 | 611 |
658 // Mark the wheel event complete only after the ACKs have been handled above. | 612 // Mark the wheel event complete only after the ACKs have been handled above. |
659 // For example, ACKing the GesturePinchUpdate could cause another | 613 // For example, ACKing the GesturePinchUpdate could cause another |
660 // GesturePinchUpdate to be sent, which should queue a wheel event rather than | 614 // GesturePinchUpdate to be sent, which should queue a wheel event rather than |
661 // send it immediately. | 615 // send it immediately. |
662 mouse_wheel_pending_ = false; | 616 mouse_wheel_pending_ = false; |
663 | 617 |
664 // Send the next (coalesced or synthetic) mouse wheel event. | 618 // Send the next (coalesced or synthetic) mouse wheel event. |
665 if (!coalesced_mouse_wheel_events_.empty()) { | 619 if (!coalesced_mouse_wheel_events_.empty()) { |
666 QueuedWheelEvent next_wheel_event = coalesced_mouse_wheel_events_.front(); | 620 QueuedWheelEvent next_wheel_event = coalesced_mouse_wheel_events_.front(); |
667 coalesced_mouse_wheel_events_.pop_front(); | 621 coalesced_mouse_wheel_events_.pop_front(); |
668 SendWheelEvent(next_wheel_event); | 622 SendWheelEvent(next_wheel_event); |
669 } | 623 } |
670 } | 624 } |
671 | 625 |
672 void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type, | 626 void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type, |
673 InputEventAckState ack_result, | 627 InputEventAckState ack_result, |
674 const ui::LatencyInfo& latency) { | 628 const ui::LatencyInfo& latency) { |
675 // If |ack_result| originated from the overscroll controller, only | 629 if (!gesture_event_queue_.ExpectingGestureAck()) |
676 // feed |gesture_event_queue_| the ack if it was expecting one. | |
677 if (current_ack_source_ == OVERSCROLL_CONTROLLER && | |
678 !gesture_event_queue_.ExpectingGestureAck()) { | |
679 return; | 630 return; |
680 } | |
681 | 631 |
682 // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. | 632 // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. |
683 gesture_event_queue_.ProcessGestureAck(ack_result, type, latency); | 633 gesture_event_queue_.ProcessGestureAck(ack_result, type, latency); |
684 } | 634 } |
685 | 635 |
686 void InputRouterImpl::ProcessTouchAck( | 636 void InputRouterImpl::ProcessTouchAck( |
687 InputEventAckState ack_result, | 637 InputEventAckState ack_result, |
688 const ui::LatencyInfo& latency) { | 638 const ui::LatencyInfo& latency) { |
689 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. | 639 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. |
690 touch_event_queue_.ProcessTouchAck(ack_result, latency); | 640 touch_event_queue_.ProcessTouchAck(ack_result, latency); |
691 } | 641 } |
692 | 642 |
693 void InputRouterImpl::ProcessAckForOverscroll(const WebInputEvent& event, | |
694 InputEventAckState ack_result) { | |
695 // Acks sent from the overscroll controller need not be fed back into the | |
696 // overscroll controller. | |
697 if (current_ack_source_ == OVERSCROLL_CONTROLLER) | |
698 return; | |
699 | |
700 OverscrollController* controller = client_->GetOverscrollController(); | |
701 if (!controller) | |
702 return; | |
703 | |
704 controller->ReceivedEventACK( | |
705 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); | |
706 } | |
707 | |
708 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { | 643 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { |
709 // Mobile sites tend to be well-behaved with respect to touch handling, so | 644 // Mobile sites tend to be well-behaved with respect to touch handling, so |
710 // they have less need for the touch timeout fallback. | 645 // they have less need for the touch timeout fallback. |
711 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; | 646 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; |
712 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; | 647 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; |
713 | 648 |
714 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves | 649 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves |
715 // little purpose. It's also a strong signal that touch handling is critical | 650 // little purpose. It's also a strong signal that touch handling is critical |
716 // to page functionality, so the timeout could do more harm than good. | 651 // to page functionality, so the timeout could do more harm than good. |
717 const bool touch_action_none = | 652 const bool touch_action_none = |
(...skipping 19 matching lines...) Expand all Loading... |
737 bool InputRouterImpl::HasPendingEvents() const { | 672 bool InputRouterImpl::HasPendingEvents() const { |
738 return !touch_event_queue_.empty() || | 673 return !touch_event_queue_.empty() || |
739 !gesture_event_queue_.empty() || | 674 !gesture_event_queue_.empty() || |
740 !key_queue_.empty() || | 675 !key_queue_.empty() || |
741 mouse_move_pending_ || | 676 mouse_move_pending_ || |
742 mouse_wheel_pending_ || | 677 mouse_wheel_pending_ || |
743 select_range_pending_ || | 678 select_range_pending_ || |
744 move_caret_pending_; | 679 move_caret_pending_; |
745 } | 680 } |
746 | 681 |
747 bool InputRouterImpl::IsInOverscrollGesture() const { | |
748 OverscrollController* controller = client_->GetOverscrollController(); | |
749 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; | |
750 } | |
751 | |
752 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent() | 682 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent() |
753 : synthesized_from_pinch(false) { | 683 : synthesized_from_pinch(false) { |
754 } | 684 } |
755 | 685 |
756 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( | 686 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( |
757 const MouseWheelEventWithLatencyInfo& event, | 687 const MouseWheelEventWithLatencyInfo& event, |
758 bool synthesized_from_pinch) | 688 bool synthesized_from_pinch) |
759 : event(event), synthesized_from_pinch(synthesized_from_pinch) { | 689 : event(event), synthesized_from_pinch(synthesized_from_pinch) { |
760 } | 690 } |
761 | 691 |
762 InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { | 692 InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { |
763 } | 693 } |
764 | 694 |
765 } // namespace content | 695 } // namespace content |
OLD | NEW |