| 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/immediate_input_router.h" | 5 #include "content/browser/renderer_host/input/immediate_input_router.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 "content/browser/renderer_host/input/gesture_event_filter.h" | 10 #include "content/browser/renderer_host/input/gesture_event_filter.h" |
| 11 #include "content/browser/renderer_host/input/input_ack_handler.h" | 11 #include "content/browser/renderer_host/input/input_ack_handler.h" |
| 12 #include "content/browser/renderer_host/input/input_router_client.h" | 12 #include "content/browser/renderer_host/input/input_router_client.h" |
| 13 #include "content/browser/renderer_host/input/touch_event_queue.h" | 13 #include "content/browser/renderer_host/input/touch_event_queue.h" |
| 14 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
r.h" | 14 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
r.h" |
| 15 #include "content/browser/renderer_host/overscroll_controller.h" | 15 #include "content/browser/renderer_host/overscroll_controller.h" |
| 16 #include "content/common/content_constants_internal.h" | 16 #include "content/common/content_constants_internal.h" |
| 17 #include "content/common/edit_command.h" | 17 #include "content/common/edit_command.h" |
| 18 #include "content/common/input/web_input_event_traits.h" | 18 #include "content/common/input/web_input_event_traits.h" |
| 19 #include "content/common/input_messages.h" | 19 #include "content/common/input_messages.h" |
| 20 #include "content/common/view_messages.h" | 20 #include "content/common/view_messages.h" |
| 21 #include "content/port/common/input_event_ack_state.h" | 21 #include "content/port/common/input_event_ack_state.h" |
| 22 #include "content/public/browser/notification_service.h" | 22 #include "content/public/browser/notification_service.h" |
| 23 #include "content/public/browser/notification_types.h" | 23 #include "content/public/browser/notification_types.h" |
| 24 #include "content/public/browser/user_metrics.h" | 24 #include "content/public/browser/user_metrics.h" |
| 25 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
| 26 #include "content/public/common/touch_action.h" |
| 26 #include "ipc/ipc_sender.h" | 27 #include "ipc/ipc_sender.h" |
| 27 #include "ui/events/event.h" | 28 #include "ui/events/event.h" |
| 28 #include "ui/events/keycodes/keyboard_codes.h" | 29 #include "ui/events/keycodes/keyboard_codes.h" |
| 29 | 30 |
| 30 using base::Time; | 31 using base::Time; |
| 31 using base::TimeDelta; | 32 using base::TimeDelta; |
| 32 using base::TimeTicks; | 33 using base::TimeTicks; |
| 33 using WebKit::WebGestureEvent; | 34 using WebKit::WebGestureEvent; |
| 34 using WebKit::WebInputEvent; | 35 using WebKit::WebInputEvent; |
| 35 using WebKit::WebKeyboardEvent; | 36 using WebKit::WebKeyboardEvent; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 int routing_id) | 79 int routing_id) |
| 79 : sender_(sender), | 80 : sender_(sender), |
| 80 client_(client), | 81 client_(client), |
| 81 ack_handler_(ack_handler), | 82 ack_handler_(ack_handler), |
| 82 routing_id_(routing_id), | 83 routing_id_(routing_id), |
| 83 select_range_pending_(false), | 84 select_range_pending_(false), |
| 84 move_caret_pending_(false), | 85 move_caret_pending_(false), |
| 85 mouse_move_pending_(false), | 86 mouse_move_pending_(false), |
| 86 mouse_wheel_pending_(false), | 87 mouse_wheel_pending_(false), |
| 87 has_touch_handler_(false), | 88 has_touch_handler_(false), |
| 89 drop_scroll_gesture_events_(false), |
| 90 allowed_touch_action_(content::TOUCH_ACTION_AUTO), |
| 88 current_ack_source_(ACK_SOURCE_NONE), | 91 current_ack_source_(ACK_SOURCE_NONE), |
| 89 touch_event_queue_(new TouchEventQueue(this)), | 92 touch_event_queue_(new TouchEventQueue(this)), |
| 90 gesture_event_filter_(new GestureEventFilter(this, this)) { | 93 gesture_event_filter_(new GestureEventFilter(this, this)) { |
| 91 DCHECK(sender); | 94 DCHECK(sender); |
| 92 DCHECK(client); | 95 DCHECK(client); |
| 93 DCHECK(ack_handler); | 96 DCHECK(ack_handler); |
| 94 } | 97 } |
| 95 | 98 |
| 96 ImmediateInputRouter::~ImmediateInputRouter() { | 99 ImmediateInputRouter::~ImmediateInputRouter() { |
| 97 } | 100 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); | 176 HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); |
| 174 | 177 |
| 175 gesture_event_filter_->FlingHasBeenHalted(); | 178 gesture_event_filter_->FlingHasBeenHalted(); |
| 176 | 179 |
| 177 // Only forward the non-native portions of our event. | 180 // Only forward the non-native portions of our event. |
| 178 FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut); | 181 FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut); |
| 179 } | 182 } |
| 180 | 183 |
| 181 void ImmediateInputRouter::SendGestureEvent( | 184 void ImmediateInputRouter::SendGestureEvent( |
| 182 const GestureEventWithLatencyInfo& gesture_event) { | 185 const GestureEventWithLatencyInfo& gesture_event) { |
| 183 HandleGestureScroll(gesture_event); | 186 if (FilterTouchAction(gesture_event)) |
| 187 return; |
| 184 | 188 |
| 185 if (!IsInOverscrollGesture() && | 189 if (!IsInOverscrollGesture() && |
| 186 !gesture_event_filter_->ShouldForward(gesture_event)) { | 190 !gesture_event_filter_->ShouldForward(gesture_event)) { |
| 187 OverscrollController* controller = client_->GetOverscrollController(); | 191 OverscrollController* controller = client_->GetOverscrollController(); |
| 188 if (controller) | 192 if (controller) |
| 189 controller->DiscardingGestureEvent(gesture_event.event); | 193 controller->DiscardingGestureEvent(gesture_event.event); |
| 190 return; | 194 return; |
| 191 } | 195 } |
| 192 | 196 |
| 193 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); | 197 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 220 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false); | 224 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency, false); |
| 221 } | 225 } |
| 222 | 226 |
| 223 void ImmediateInputRouter::SendTouchEventImmediately( | 227 void ImmediateInputRouter::SendTouchEventImmediately( |
| 224 const TouchEventWithLatencyInfo& touch_event) { | 228 const TouchEventWithLatencyInfo& touch_event) { |
| 225 FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false); | 229 FilterAndSendWebInputEvent(touch_event.event, touch_event.latency, false); |
| 226 } | 230 } |
| 227 | 231 |
| 228 void ImmediateInputRouter::SendGestureEventImmediately( | 232 void ImmediateInputRouter::SendGestureEventImmediately( |
| 229 const GestureEventWithLatencyInfo& gesture_event) { | 233 const GestureEventWithLatencyInfo& gesture_event) { |
| 230 HandleGestureScroll(gesture_event); | 234 if (FilterTouchAction(gesture_event)) |
| 235 return; |
| 231 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); | 236 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); |
| 232 } | 237 } |
| 233 | 238 |
| 234 const NativeWebKeyboardEvent* | 239 const NativeWebKeyboardEvent* |
| 235 ImmediateInputRouter::GetLastKeyboardEvent() const { | 240 ImmediateInputRouter::GetLastKeyboardEvent() const { |
| 236 if (key_queue_.empty()) | 241 if (key_queue_.empty()) |
| 237 return NULL; | 242 return NULL; |
| 238 return &key_queue_.front(); | 243 return &key_queue_.front(); |
| 239 } | 244 } |
| 240 | 245 |
| 241 bool ImmediateInputRouter::ShouldForwardTouchEvent() const { | 246 bool ImmediateInputRouter::ShouldForwardTouchEvent() const { |
| 242 // Always send a touch event if the renderer has a touch-event handler. It is | 247 // Always send a touch event if the renderer has a touch-event handler. It is |
| 243 // possible that a renderer stops listening to touch-events while there are | 248 // possible that a renderer stops listening to touch-events while there are |
| 244 // still events in the touch-queue. In such cases, the new events should still | 249 // still events in the touch-queue. In such cases, the new events should still |
| 245 // get into the queue. | 250 // get into the queue. |
| 246 return has_touch_handler_ || !touch_event_queue_->empty(); | 251 return has_touch_handler_ || !touch_event_queue_->empty(); |
| 247 } | 252 } |
| 248 | 253 |
| 249 bool ImmediateInputRouter::OnMessageReceived(const IPC::Message& message) { | 254 bool ImmediateInputRouter::OnMessageReceived(const IPC::Message& message) { |
| 250 bool handled = true; | 255 bool handled = true; |
| 251 bool message_is_ok = true; | 256 bool message_is_ok = true; |
| 252 IPC_BEGIN_MESSAGE_MAP_EX(ImmediateInputRouter, message, message_is_ok) | 257 IPC_BEGIN_MESSAGE_MAP_EX(ImmediateInputRouter, message, message_is_ok) |
| 253 IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck) | 258 IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck) |
| 254 IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck) | 259 IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck) |
| 255 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck) | 260 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck) |
| 256 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers, | 261 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers, |
| 257 OnHasTouchEventHandlers) | 262 OnHasTouchEventHandlers) |
| 263 IPC_MESSAGE_HANDLER(ViewHostMsg_SetTouchAction, |
| 264 OnSetTouchAction) |
| 258 IPC_MESSAGE_UNHANDLED(handled = false) | 265 IPC_MESSAGE_UNHANDLED(handled = false) |
| 259 IPC_END_MESSAGE_MAP() | 266 IPC_END_MESSAGE_MAP() |
| 260 | 267 |
| 261 if (!message_is_ok) | 268 if (!message_is_ok) |
| 262 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); | 269 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); |
| 263 | 270 |
| 264 return handled; | 271 return handled; |
| 265 } | 272 } |
| 266 | 273 |
| 267 void ImmediateInputRouter::OnTouchEventAck( | 274 void ImmediateInputRouter::OnTouchEventAck( |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 | 462 |
| 456 void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) { | 463 void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) { |
| 457 if (has_touch_handler_ == has_handlers) | 464 if (has_touch_handler_ == has_handlers) |
| 458 return; | 465 return; |
| 459 has_touch_handler_ = has_handlers; | 466 has_touch_handler_ = has_handlers; |
| 460 if (!has_handlers) | 467 if (!has_handlers) |
| 461 touch_event_queue_->FlushQueue(); | 468 touch_event_queue_->FlushQueue(); |
| 462 client_->OnHasTouchEventHandlers(has_handlers); | 469 client_->OnHasTouchEventHandlers(has_handlers); |
| 463 } | 470 } |
| 464 | 471 |
| 472 void ImmediateInputRouter::OnSetTouchAction( |
| 473 int touch_id, |
| 474 content::TouchAction touchAction) |
| 475 { |
| 476 // Don't process touch-action messages for synthetic touches we know |
| 477 // nothing about. |
| 478 if (!touch_event_queue_->IsTouchStartPendingAck(touch_id)) |
| 479 return; |
| 480 |
| 481 // For multiple fingers, we take the intersection of the touch actions for |
| 482 // all fingers that have gone down during this action. |
| 483 // TODO(rbyers): Get some agreed upon multi-finger semantic for touch-action |
| 484 // included in the pointer events specification. crbug.com/241964 |
| 485 if (touchAction == content::TOUCH_ACTION_NONE) |
| 486 allowed_touch_action_ = content::TOUCH_ACTION_NONE; |
| 487 } |
| 488 |
| 465 void ImmediateInputRouter::ProcessInputEventAck( | 489 void ImmediateInputRouter::ProcessInputEventAck( |
| 466 WebInputEvent::Type event_type, | 490 WebInputEvent::Type event_type, |
| 467 InputEventAckState ack_result, | 491 InputEventAckState ack_result, |
| 468 const ui::LatencyInfo& latency_info, | 492 const ui::LatencyInfo& latency_info, |
| 469 AckSource ack_source) { | 493 AckSource ack_source) { |
| 470 TRACE_EVENT2("input", "ImmediateInputRouter::ProcessInputEventAck", | 494 TRACE_EVENT2("input", "ImmediateInputRouter::ProcessInputEventAck", |
| 471 "type", WebInputEventTraits::GetName(event_type), | 495 "type", WebInputEventTraits::GetName(event_type), |
| 472 "ack", GetEventAckName(ack_result)); | 496 "ack", GetEventAckName(ack_result)); |
| 473 | 497 |
| 474 // Note: The keyboard ack must be treated carefully, as it may result in | 498 // Note: The keyboard ack must be treated carefully, as it may result in |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 return; | 608 return; |
| 585 | 609 |
| 586 OverscrollController* controller = client_->GetOverscrollController(); | 610 OverscrollController* controller = client_->GetOverscrollController(); |
| 587 if (!controller) | 611 if (!controller) |
| 588 return; | 612 return; |
| 589 | 613 |
| 590 controller->ReceivedEventACK( | 614 controller->ReceivedEventACK( |
| 591 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); | 615 event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); |
| 592 } | 616 } |
| 593 | 617 |
| 594 void ImmediateInputRouter::HandleGestureScroll( | 618 bool ImmediateInputRouter::FilterTouchAction( |
| 595 const GestureEventWithLatencyInfo& gesture_event) { | 619 const GestureEventWithLatencyInfo& gesture_event) { |
| 620 |
| 621 // Filter for allowable touch actions first (eg. before the TouchEventQueue |
| 622 // can decide to send a touch cancel event). |
| 623 // TODO: Does this belong in GestureEventFilter, even though the filtering |
| 624 // happens at a different stage from the other filters there? |
| 625 // TODO(rbyers): Add touch-action control over for pinch. crbug.com/247566. |
| 626 switch(gesture_event.event.type) { |
| 627 case WebInputEvent::GestureScrollBegin: |
| 628 if (allowed_touch_action_ == TOUCH_ACTION_NONE) |
| 629 drop_scroll_gesture_events_ = true; |
| 630 // FALL THROUGH |
| 631 case WebInputEvent::GestureScrollUpdate: |
| 632 case WebInputEvent::GestureScrollUpdateWithoutPropagation: |
| 633 if (drop_scroll_gesture_events_) |
| 634 return true; |
| 635 break; |
| 636 |
| 637 case WebInputEvent::GestureScrollEnd: |
| 638 case WebInputEvent::GestureFlingStart: |
| 639 allowed_touch_action_ = content::TOUCH_ACTION_AUTO; |
| 640 if (drop_scroll_gesture_events_) { |
| 641 drop_scroll_gesture_events_ = false; |
| 642 return true; |
| 643 } |
| 644 break; |
| 645 |
| 646 default: |
| 647 break; |
| 648 } |
| 649 |
| 650 // This touch action is permitted, allow it to cancel in-progress touches. |
| 596 touch_event_queue_->OnGestureScrollEvent(gesture_event); | 651 touch_event_queue_->OnGestureScrollEvent(gesture_event); |
| 652 return false; |
| 597 } | 653 } |
| 598 | 654 |
| 599 void ImmediateInputRouter::SimulateTouchGestureWithMouse( | 655 void ImmediateInputRouter::SimulateTouchGestureWithMouse( |
| 600 const MouseEventWithLatencyInfo& event) { | 656 const MouseEventWithLatencyInfo& event) { |
| 601 const WebMouseEvent& mouse_event = event.event; | 657 const WebMouseEvent& mouse_event = event.event; |
| 602 int x = mouse_event.x, y = mouse_event.y; | 658 int x = mouse_event.x, y = mouse_event.y; |
| 603 float dx = mouse_event.movementX, dy = mouse_event.movementY; | 659 float dx = mouse_event.movementX, dy = mouse_event.movementY; |
| 604 static int startX = 0, startY = 0; | 660 static int startX = 0, startY = 0; |
| 605 | 661 |
| 606 switch (mouse_event.button) { | 662 switch (mouse_event.button) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 break; | 731 break; |
| 676 } | 732 } |
| 677 } | 733 } |
| 678 | 734 |
| 679 bool ImmediateInputRouter::IsInOverscrollGesture() const { | 735 bool ImmediateInputRouter::IsInOverscrollGesture() const { |
| 680 OverscrollController* controller = client_->GetOverscrollController(); | 736 OverscrollController* controller = client_->GetOverscrollController(); |
| 681 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; | 737 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; |
| 682 } | 738 } |
| 683 | 739 |
| 684 } // namespace content | 740 } // namespace content |
| OLD | NEW |