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