| 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" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "content/common/input/touch_action.h" | 21 #include "content/common/input/touch_action.h" |
| 22 #include "content/common/input/web_touch_event_traits.h" | 22 #include "content/common/input/web_touch_event_traits.h" |
| 23 #include "content/common/input_messages.h" | 23 #include "content/common/input_messages.h" |
| 24 #include "content/common/view_messages.h" | 24 #include "content/common/view_messages.h" |
| 25 #include "content/public/browser/notification_service.h" | 25 #include "content/public/browser/notification_service.h" |
| 26 #include "content/public/browser/notification_types.h" | 26 #include "content/public/browser/notification_types.h" |
| 27 #include "content/public/browser/user_metrics.h" | 27 #include "content/public/browser/user_metrics.h" |
| 28 #include "content/public/common/content_switches.h" | 28 #include "content/public/common/content_switches.h" |
| 29 #include "ipc/ipc_sender.h" | 29 #include "ipc/ipc_sender.h" |
| 30 #include "ui/events/event.h" | 30 #include "ui/events/event.h" |
| 31 #include "ui/events/gestures/fling_curve.h" |
| 31 #include "ui/events/keycodes/keyboard_codes.h" | 32 #include "ui/events/keycodes/keyboard_codes.h" |
| 33 #include "ui/gfx/frame_time.h" |
| 34 |
| 35 #if defined(OS_ANDROID) |
| 36 #include "ui/gfx/android/scroller.h" |
| 37 #endif |
| 32 | 38 |
| 33 using base::Time; | 39 using base::Time; |
| 34 using base::TimeDelta; | 40 using base::TimeDelta; |
| 35 using base::TimeTicks; | 41 using base::TimeTicks; |
| 36 using blink::WebGestureEvent; | 42 using blink::WebGestureEvent; |
| 37 using blink::WebInputEvent; | 43 using blink::WebInputEvent; |
| 38 using blink::WebKeyboardEvent; | 44 using blink::WebKeyboardEvent; |
| 39 using blink::WebMouseEvent; | 45 using blink::WebMouseEvent; |
| 40 using blink::WebMouseWheelEvent; | 46 using blink::WebMouseWheelEvent; |
| 41 | 47 |
| 42 namespace content { | 48 namespace content { |
| 43 namespace { | 49 namespace { |
| 44 | 50 |
| 45 const char* GetEventAckName(InputEventAckState ack_result) { | 51 const char* GetEventAckName(InputEventAckState ack_result) { |
| 46 switch(ack_result) { | 52 switch(ack_result) { |
| 47 case INPUT_EVENT_ACK_STATE_UNKNOWN: return "UNKNOWN"; | 53 case INPUT_EVENT_ACK_STATE_UNKNOWN: return "UNKNOWN"; |
| 48 case INPUT_EVENT_ACK_STATE_CONSUMED: return "CONSUMED"; | 54 case INPUT_EVENT_ACK_STATE_CONSUMED: return "CONSUMED"; |
| 49 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED"; | 55 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED"; |
| 50 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS"; | 56 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS"; |
| 51 case INPUT_EVENT_ACK_STATE_IGNORED: return "IGNORED"; | 57 case INPUT_EVENT_ACK_STATE_IGNORED: return "IGNORED"; |
| 52 } | 58 } |
| 53 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName."; | 59 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName."; |
| 54 return ""; | 60 return ""; |
| 55 } | 61 } |
| 56 | 62 |
| 57 } // namespace | 63 } // namespace |
| 58 | 64 |
| 65 #if defined(OS_ANDROID) |
| 66 namespace { |
| 67 |
| 68 // Value taken directly from Android's ViewConfiguration. As the value has not |
| 69 // changed in 4+ years, and does not depend on any device-specific configuration |
| 70 // parameters, copy it directly to avoid potential JNI interop issues in the |
| 71 // render process (see crbug.com/362614). |
| 72 const float kDefaultAndroidPlatformScrollFriction = 0.015f; |
| 73 |
| 74 gfx::Scroller::Config GetScrollerConfig() { |
| 75 gfx::Scroller::Config config; |
| 76 config.flywheel_enabled = false; |
| 77 config.fling_friction = kDefaultAndroidPlatformScrollFriction; |
| 78 return config; |
| 79 } |
| 80 |
| 81 } // namespace |
| 82 #endif // defined(OS_ANDROID) |
| 83 |
| 84 Flinger::Flinger(const blink::WebGestureEvent& fling_event) |
| 85 : fling_event_(fling_event), |
| 86 #if defined(OS_ANDROID) |
| 87 scroller_(new gfx::Scroller(GetScrollerConfig())) { |
| 88 #else |
| 89 fling_curve_(new ui::FlingCurve( |
| 90 gfx::Vector2dF(fling_event.data.flingStart.velocityX, |
| 91 fling_event.data.flingStart.velocityY), |
| 92 gfx::FrameTime::Now())) { |
| 93 #endif |
| 94 CHECK_EQ(blink::WebInputEvent::GestureFlingStart, fling_event_.type); |
| 95 #if defined(OS_ANDROID) |
| 96 scroller_->Fling(0.f, |
| 97 0.f, |
| 98 fling_event.data.flingStart.velocityX, |
| 99 fling_event.data.flingStart.velocityY, |
| 100 INT_MIN, |
| 101 INT_MAX, |
| 102 INT_MIN, |
| 103 INT_MAX, |
| 104 gfx::FrameTime::Now()); |
| 105 #endif |
| 106 } |
| 107 |
| 108 Flinger::~Flinger() { |
| 109 } |
| 110 |
| 111 blink::WebGestureEvent Flinger::GetNextScrollEvent() { |
| 112 gfx::Vector2dF scroll; |
| 113 bool scroll_end_reached = false; |
| 114 |
| 115 base::TimeTicks now = gfx::FrameTime::Now(); |
| 116 #if defined(OS_ANDROID) |
| 117 gfx::PointF pre_scroll_location(scroller_->GetCurrX(), scroller_->GetCurrY()); |
| 118 if (scroller_->ComputeScrollOffset(now)) { |
| 119 gfx::PointF new_location(scroller_->GetCurrX(), scroller_->GetCurrY()); |
| 120 scroll = new_location - pre_scroll_location; |
| 121 } else { |
| 122 scroll_end_reached = true; |
| 123 } |
| 124 #else |
| 125 scroll = fling_curve_->GetScrollAmountAtTime(now); |
| 126 scroll_end_reached = scroll.IsZero(); |
| 127 #endif |
| 128 |
| 129 if (scroll_end_reached) { |
| 130 blink::WebGestureEvent scroll_end = fling_event_; |
| 131 scroll_end.type = blink::WebInputEvent::GestureScrollEnd; |
| 132 return scroll_end; |
| 133 } |
| 134 |
| 135 blink::WebGestureEvent scroll_update = fling_event_; |
| 136 scroll_update.type = |
| 137 blink::WebInputEvent::GestureScrollUpdateWithoutPropagation; |
| 138 scroll_update.data.scrollUpdate.deltaX = scroll.x(); |
| 139 scroll_update.data.scrollUpdate.deltaY = scroll.y(); |
| 140 return scroll_update; |
| 141 } |
| 142 |
| 59 InputRouterImpl::Config::Config() { | 143 InputRouterImpl::Config::Config() { |
| 60 } | 144 } |
| 61 | 145 |
| 62 InputRouterImpl::InputRouterImpl(IPC::Sender* sender, | 146 InputRouterImpl::InputRouterImpl(IPC::Sender* sender, |
| 63 InputRouterClient* client, | 147 InputRouterClient* client, |
| 64 InputAckHandler* ack_handler, | 148 InputAckHandler* ack_handler, |
| 65 int routing_id, | 149 int routing_id, |
| 66 const Config& config) | 150 const Config& config) |
| 67 : sender_(sender), | 151 : sender_(sender), |
| 68 client_(client), | 152 client_(client), |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 LOCAL_HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); | 251 LOCAL_HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); |
| 168 | 252 |
| 169 gesture_event_queue_.FlingHasBeenHalted(); | 253 gesture_event_queue_.FlingHasBeenHalted(); |
| 170 | 254 |
| 171 // Only forward the non-native portions of our event. | 255 // Only forward the non-native portions of our event. |
| 172 FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut); | 256 FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut); |
| 173 } | 257 } |
| 174 | 258 |
| 175 void InputRouterImpl::SendGestureEvent( | 259 void InputRouterImpl::SendGestureEvent( |
| 176 const GestureEventWithLatencyInfo& original_gesture_event) { | 260 const GestureEventWithLatencyInfo& original_gesture_event) { |
| 261 if (original_gesture_event.event.type == |
| 262 blink::WebInputEvent::GestureFlingStart) { |
| 263 const blink::WebGestureEvent& fling_event = original_gesture_event.event; |
| 264 gfx::Vector2dF velocity(fling_event.data.flingStart.velocityX, |
| 265 fling_event.data.flingStart.velocityY); |
| 266 if (!velocity.IsZero()) { |
| 267 flinger_.reset(new Flinger(fling_event)); |
| 268 SendGestureEvent(GestureEventWithLatencyInfo( |
| 269 flinger_->GetNextScrollEvent(), original_gesture_event.latency)); |
| 270 return; |
| 271 } |
| 272 } |
| 273 |
| 274 if (original_gesture_event.event.type == |
| 275 blink::WebInputEvent::GestureFlingCancel && |
| 276 flinger_) { |
| 277 blink::WebGestureEvent gesture_event = flinger_->GetNextScrollEvent(); |
| 278 flinger_.reset(); |
| 279 gesture_event.type = blink::WebInputEvent::GestureScrollEnd; |
| 280 SendGestureEvent(GestureEventWithLatencyInfo( |
| 281 gesture_event, original_gesture_event.latency)); |
| 282 return; |
| 283 } |
| 284 |
| 177 input_stream_validator_.Validate(original_gesture_event.event); | 285 input_stream_validator_.Validate(original_gesture_event.event); |
| 178 | 286 |
| 179 GestureEventWithLatencyInfo gesture_event(original_gesture_event); | 287 GestureEventWithLatencyInfo gesture_event(original_gesture_event); |
| 180 | 288 |
| 181 if (touch_action_filter_.FilterGestureEvent(&gesture_event.event)) | 289 if (touch_action_filter_.FilterGestureEvent(&gesture_event.event)) |
| 182 return; | 290 return; |
| 183 | 291 |
| 184 if (gesture_event.event.sourceDevice == blink::WebGestureDeviceTouchscreen) | 292 if (gesture_event.event.sourceDevice == blink::WebGestureDeviceTouchscreen) |
| 185 touch_event_queue_.OnGestureScrollEvent(gesture_event); | 293 touch_event_queue_.OnGestureScrollEvent(gesture_event); |
| 186 | 294 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 UpdateTouchAckTimeoutEnabled(); | 397 UpdateTouchAckTimeoutEnabled(); |
| 290 } | 398 } |
| 291 ack_handler_->OnTouchEventAck(event, ack_result); | 399 ack_handler_->OnTouchEventAck(event, ack_result); |
| 292 } | 400 } |
| 293 | 401 |
| 294 void InputRouterImpl::OnGestureEventAck( | 402 void InputRouterImpl::OnGestureEventAck( |
| 295 const GestureEventWithLatencyInfo& event, | 403 const GestureEventWithLatencyInfo& event, |
| 296 InputEventAckState ack_result) { | 404 InputEventAckState ack_result) { |
| 297 touch_event_queue_.OnGestureEventAck(event, ack_result); | 405 touch_event_queue_.OnGestureEventAck(event, ack_result); |
| 298 ack_handler_->OnGestureEventAck(event, ack_result); | 406 ack_handler_->OnGestureEventAck(event, ack_result); |
| 407 |
| 408 if (flinger_ && |
| 409 event.event.type == |
| 410 blink::WebInputEvent::GestureScrollUpdateWithoutPropagation) { |
| 411 const blink::WebGestureEvent& acked_event = event.event; |
| 412 blink::WebGestureEvent fling_update = flinger_->GetNextScrollEvent(); |
| 413 if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED && |
| 414 (std::abs(acked_event.data.scrollUpdate.deltaX) > 0.1f || |
| 415 std::abs(acked_event.data.scrollUpdate.deltaY) > 0.1f)) { |
| 416 fling_update.type = blink::WebInputEvent::GestureScrollEnd; |
| 417 } |
| 418 if (fling_update.type == blink::WebInputEvent::GestureScrollEnd) |
| 419 flinger_.reset(); |
| 420 SendGestureEvent(GestureEventWithLatencyInfo(fling_update, event.latency)); |
| 421 } |
| 299 } | 422 } |
| 300 | 423 |
| 301 bool InputRouterImpl::SendSelectRange(scoped_ptr<IPC::Message> message) { | 424 bool InputRouterImpl::SendSelectRange(scoped_ptr<IPC::Message> message) { |
| 302 DCHECK(message->type() == InputMsg_SelectRange::ID); | 425 DCHECK(message->type() == InputMsg_SelectRange::ID); |
| 303 if (select_range_pending_) { | 426 if (select_range_pending_) { |
| 304 next_selection_range_ = message.Pass(); | 427 next_selection_range_ = message.Pass(); |
| 305 return true; | 428 return true; |
| 306 } | 429 } |
| 307 | 430 |
| 308 select_range_pending_ = true; | 431 select_range_pending_ = true; |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 void InputRouterImpl::OnInputEventAck( | 572 void InputRouterImpl::OnInputEventAck( |
| 450 const InputHostMsg_HandleInputEvent_ACK_Params& ack) { | 573 const InputHostMsg_HandleInputEvent_ACK_Params& ack) { |
| 451 client_->DecrementInFlightEventCount(); | 574 client_->DecrementInFlightEventCount(); |
| 452 | 575 |
| 453 // Log the time delta for processing an input event. | 576 // Log the time delta for processing an input event. |
| 454 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; | 577 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; |
| 455 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta); | 578 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta); |
| 456 | 579 |
| 457 if (ack.overscroll) { | 580 if (ack.overscroll) { |
| 458 DCHECK(ack.type == WebInputEvent::MouseWheel || | 581 DCHECK(ack.type == WebInputEvent::MouseWheel || |
| 459 ack.type == WebInputEvent::GestureScrollUpdate); | 582 ack.type == WebInputEvent::GestureScrollUpdate || |
| 583 ack.type == WebInputEvent::GestureScrollUpdateWithoutPropagation); |
| 460 OnDidOverscroll(*ack.overscroll); | 584 OnDidOverscroll(*ack.overscroll); |
| 461 } | 585 } |
| 462 | 586 |
| 463 ProcessInputEventAck(ack.type, ack.state, ack.latency, RENDERER); | 587 ProcessInputEventAck(ack.type, ack.state, ack.latency, RENDERER); |
| 464 // WARNING: |this| may be deleted at this point. | 588 // WARNING: |this| may be deleted at this point. |
| 465 | 589 |
| 466 // This is used only for testing, and the other end does not use the | 590 // This is used only for testing, and the other end does not use the |
| 467 // source object. On linux, specifying | 591 // source object. On linux, specifying |
| 468 // Source<RenderWidgetHost> results in a very strange | 592 // Source<RenderWidgetHost> results in a very strange |
| 469 // runtime error in the epilogue of the enclosing | 593 // runtime error in the epilogue of the enclosing |
| 470 // (ProcessInputEventAck) method, but not on other platforms; using | 594 // (ProcessInputEventAck) method, but not on other platforms; using |
| 471 // 'void' instead is just as safe (since NotificationSource | 595 // 'void' instead is just as safe (since NotificationSource |
| 472 // is not actually typesafe) and avoids this error. | 596 // is not actually typesafe) and avoids this error. |
| 473 int type = static_cast<int>(ack.type); | 597 int type = static_cast<int>(ack.type); |
| 474 NotificationService::current()->Notify( | 598 NotificationService::current()->Notify( |
| 475 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK, | 599 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK, |
| 476 Source<void>(this), | 600 Source<void>(this), |
| 477 Details<int>(&type)); | 601 Details<int>(&type)); |
| 478 } | 602 } |
| 479 | 603 |
| 480 void InputRouterImpl::OnDidOverscroll(const DidOverscrollParams& params) { | 604 void InputRouterImpl::OnDidOverscroll(const DidOverscrollParams& params) { |
| 481 client_->DidOverscroll(params); | 605 client_->DidOverscroll(params); |
| 606 if (flinger_) { |
| 607 blink::WebGestureEvent gesture_event = flinger_->GetNextScrollEvent(); |
| 608 flinger_.reset(); |
| 609 gesture_event.type = blink::WebInputEvent::GestureScrollEnd; |
| 610 SendGestureEvent( |
| 611 GestureEventWithLatencyInfo(gesture_event, ui::LatencyInfo())); |
| 612 } |
| 482 } | 613 } |
| 483 | 614 |
| 484 void InputRouterImpl::OnMsgMoveCaretAck() { | 615 void InputRouterImpl::OnMsgMoveCaretAck() { |
| 485 move_caret_pending_ = false; | 616 move_caret_pending_ = false; |
| 486 if (next_move_caret_) | 617 if (next_move_caret_) |
| 487 SendMoveCaret(next_move_caret_.Pass()); | 618 SendMoveCaret(next_move_caret_.Pass()); |
| 488 } | 619 } |
| 489 | 620 |
| 490 void InputRouterImpl::OnSelectRangeAck() { | 621 void InputRouterImpl::OnSelectRangeAck() { |
| 491 select_range_pending_ = false; | 622 select_range_pending_ = false; |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( | 821 InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( |
| 691 const MouseWheelEventWithLatencyInfo& event, | 822 const MouseWheelEventWithLatencyInfo& event, |
| 692 bool synthesized_from_pinch) | 823 bool synthesized_from_pinch) |
| 693 : event(event), synthesized_from_pinch(synthesized_from_pinch) { | 824 : event(event), synthesized_from_pinch(synthesized_from_pinch) { |
| 694 } | 825 } |
| 695 | 826 |
| 696 InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { | 827 InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { |
| 697 } | 828 } |
| 698 | 829 |
| 699 } // namespace content | 830 } // namespace content |
| OLD | NEW |