| Index: content/browser/renderer_host/input/input_router_impl.cc
|
| diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc
|
| index 441f9384bb8745e05efd53d9e1e645aa94255124..e7672f097d01e3f3335e4e9f77c5699e072bedb1 100644
|
| --- a/content/browser/renderer_host/input/input_router_impl.cc
|
| +++ b/content/browser/renderer_host/input/input_router_impl.cc
|
| @@ -28,7 +28,13 @@
|
| #include "content/public/common/content_switches.h"
|
| #include "ipc/ipc_sender.h"
|
| #include "ui/events/event.h"
|
| +#include "ui/events/gestures/fling_curve.h"
|
| #include "ui/events/keycodes/keyboard_codes.h"
|
| +#include "ui/gfx/frame_time.h"
|
| +
|
| +#if defined(OS_ANDROID)
|
| +#include "ui/gfx/android/scroller.h"
|
| +#endif
|
|
|
| using base::Time;
|
| using base::TimeDelta;
|
| @@ -56,6 +62,84 @@ const char* GetEventAckName(InputEventAckState ack_result) {
|
|
|
| } // namespace
|
|
|
| +#if defined(OS_ANDROID)
|
| +namespace {
|
| +
|
| +// Value taken directly from Android's ViewConfiguration. As the value has not
|
| +// changed in 4+ years, and does not depend on any device-specific configuration
|
| +// parameters, copy it directly to avoid potential JNI interop issues in the
|
| +// render process (see crbug.com/362614).
|
| +const float kDefaultAndroidPlatformScrollFriction = 0.015f;
|
| +
|
| +gfx::Scroller::Config GetScrollerConfig() {
|
| + gfx::Scroller::Config config;
|
| + config.flywheel_enabled = false;
|
| + config.fling_friction = kDefaultAndroidPlatformScrollFriction;
|
| + return config;
|
| +}
|
| +
|
| +} // namespace
|
| +#endif // defined(OS_ANDROID)
|
| +
|
| +Flinger::Flinger(const blink::WebGestureEvent& fling_event)
|
| + : fling_event_(fling_event),
|
| +#if defined(OS_ANDROID)
|
| + scroller_(new gfx::Scroller(GetScrollerConfig())) {
|
| +#else
|
| + fling_curve_(new ui::FlingCurve(
|
| + gfx::Vector2dF(fling_event.data.flingStart.velocityX,
|
| + fling_event.data.flingStart.velocityY),
|
| + gfx::FrameTime::Now())) {
|
| +#endif
|
| + CHECK_EQ(blink::WebInputEvent::GestureFlingStart, fling_event_.type);
|
| +#if defined(OS_ANDROID)
|
| + scroller_->Fling(0.f,
|
| + 0.f,
|
| + fling_event.data.flingStart.velocityX,
|
| + fling_event.data.flingStart.velocityY,
|
| + INT_MIN,
|
| + INT_MAX,
|
| + INT_MIN,
|
| + INT_MAX,
|
| + gfx::FrameTime::Now());
|
| +#endif
|
| +}
|
| +
|
| +Flinger::~Flinger() {
|
| +}
|
| +
|
| +blink::WebGestureEvent Flinger::GetNextScrollEvent() {
|
| + gfx::Vector2dF scroll;
|
| + bool scroll_end_reached = false;
|
| +
|
| + base::TimeTicks now = gfx::FrameTime::Now();
|
| +#if defined(OS_ANDROID)
|
| + gfx::PointF pre_scroll_location(scroller_->GetCurrX(), scroller_->GetCurrY());
|
| + if (scroller_->ComputeScrollOffset(now)) {
|
| + gfx::PointF new_location(scroller_->GetCurrX(), scroller_->GetCurrY());
|
| + scroll = new_location - pre_scroll_location;
|
| + } else {
|
| + scroll_end_reached = true;
|
| + }
|
| +#else
|
| + scroll = fling_curve_->GetScrollAmountAtTime(now);
|
| + scroll_end_reached = scroll.IsZero();
|
| +#endif
|
| +
|
| + if (scroll_end_reached) {
|
| + blink::WebGestureEvent scroll_end = fling_event_;
|
| + scroll_end.type = blink::WebInputEvent::GestureScrollEnd;
|
| + return scroll_end;
|
| + }
|
| +
|
| + blink::WebGestureEvent scroll_update = fling_event_;
|
| + scroll_update.type =
|
| + blink::WebInputEvent::GestureScrollUpdateWithoutPropagation;
|
| + scroll_update.data.scrollUpdate.deltaX = scroll.x();
|
| + scroll_update.data.scrollUpdate.deltaY = scroll.y();
|
| + return scroll_update;
|
| +}
|
| +
|
| InputRouterImpl::Config::Config() {
|
| }
|
|
|
| @@ -174,6 +258,30 @@ void InputRouterImpl::SendKeyboardEvent(const NativeWebKeyboardEvent& key_event,
|
|
|
| void InputRouterImpl::SendGestureEvent(
|
| const GestureEventWithLatencyInfo& original_gesture_event) {
|
| + if (original_gesture_event.event.type ==
|
| + blink::WebInputEvent::GestureFlingStart) {
|
| + const blink::WebGestureEvent& fling_event = original_gesture_event.event;
|
| + gfx::Vector2dF velocity(fling_event.data.flingStart.velocityX,
|
| + fling_event.data.flingStart.velocityY);
|
| + if (!velocity.IsZero()) {
|
| + flinger_.reset(new Flinger(fling_event));
|
| + SendGestureEvent(GestureEventWithLatencyInfo(
|
| + flinger_->GetNextScrollEvent(), original_gesture_event.latency));
|
| + return;
|
| + }
|
| + }
|
| +
|
| + if (original_gesture_event.event.type ==
|
| + blink::WebInputEvent::GestureFlingCancel &&
|
| + flinger_) {
|
| + blink::WebGestureEvent gesture_event = flinger_->GetNextScrollEvent();
|
| + flinger_.reset();
|
| + gesture_event.type = blink::WebInputEvent::GestureScrollEnd;
|
| + SendGestureEvent(GestureEventWithLatencyInfo(
|
| + gesture_event, original_gesture_event.latency));
|
| + return;
|
| + }
|
| +
|
| input_stream_validator_.Validate(original_gesture_event.event);
|
|
|
| GestureEventWithLatencyInfo gesture_event(original_gesture_event);
|
| @@ -296,6 +404,21 @@ void InputRouterImpl::OnGestureEventAck(
|
| InputEventAckState ack_result) {
|
| touch_event_queue_.OnGestureEventAck(event, ack_result);
|
| ack_handler_->OnGestureEventAck(event, ack_result);
|
| +
|
| + if (flinger_ &&
|
| + event.event.type ==
|
| + blink::WebInputEvent::GestureScrollUpdateWithoutPropagation) {
|
| + const blink::WebGestureEvent& acked_event = event.event;
|
| + blink::WebGestureEvent fling_update = flinger_->GetNextScrollEvent();
|
| + if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED &&
|
| + (std::abs(acked_event.data.scrollUpdate.deltaX) > 0.1f ||
|
| + std::abs(acked_event.data.scrollUpdate.deltaY) > 0.1f)) {
|
| + fling_update.type = blink::WebInputEvent::GestureScrollEnd;
|
| + }
|
| + if (fling_update.type == blink::WebInputEvent::GestureScrollEnd)
|
| + flinger_.reset();
|
| + SendGestureEvent(GestureEventWithLatencyInfo(fling_update, event.latency));
|
| + }
|
| }
|
|
|
| bool InputRouterImpl::SendSelectRange(scoped_ptr<IPC::Message> message) {
|
| @@ -456,7 +579,8 @@ void InputRouterImpl::OnInputEventAck(
|
|
|
| if (ack.overscroll) {
|
| DCHECK(ack.type == WebInputEvent::MouseWheel ||
|
| - ack.type == WebInputEvent::GestureScrollUpdate);
|
| + ack.type == WebInputEvent::GestureScrollUpdate ||
|
| + ack.type == WebInputEvent::GestureScrollUpdateWithoutPropagation);
|
| OnDidOverscroll(*ack.overscroll);
|
| }
|
|
|
| @@ -479,6 +603,13 @@ void InputRouterImpl::OnInputEventAck(
|
|
|
| void InputRouterImpl::OnDidOverscroll(const DidOverscrollParams& params) {
|
| client_->DidOverscroll(params);
|
| + if (flinger_) {
|
| + blink::WebGestureEvent gesture_event = flinger_->GetNextScrollEvent();
|
| + flinger_.reset();
|
| + gesture_event.type = blink::WebInputEvent::GestureScrollEnd;
|
| + SendGestureEvent(
|
| + GestureEventWithLatencyInfo(gesture_event, ui::LatencyInfo()));
|
| + }
|
| }
|
|
|
| void InputRouterImpl::OnMsgMoveCaretAck() {
|
|
|