Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Side by Side Diff: content/browser/renderer_host/input/input_router_impl.cc

Issue 593883002: [exp] Browser-side fling. Base URL: https://chromium.googlesource.com/chromium/src.git@fling-curve-config-remove
Patch Set: . Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/renderer_host/input/input_router_impl.h ('k') | content/common/input/web_input_event_traits.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698