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 |