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 |