1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/child/fling_animator_impl_android.h" 6 7#include "base/logging.h" 8#include "third_party/WebKit/public/platform/WebFloatSize.h" 9#include "third_party/WebKit/public/platform/WebGestureCurveTarget.h" 10#include "ui/gfx/frame_time.h" 11#include "ui/gfx/vector2d.h" 12 13namespace content { 14 15namespace { 16 17// Value taken directly from Android's ViewConfiguration. As the value has not 18// changed in 4+ years, and does not depend on any device-specific configuration 19// parameters, copy it directly to avoid potential JNI interop issues in the 20// render process (see crbug.com/362614). 21const float kDefaultAndroidPlatformScrollFriction = 0.015f; 22 23gfx::Scroller::Config GetScrollerConfig() { 24 gfx::Scroller::Config config; 25 config.flywheel_enabled = false; 26 config.fling_friction = kDefaultAndroidPlatformScrollFriction; 27 return config; 28} 29 30} // namespace 31 32FlingAnimatorImpl::FlingAnimatorImpl() 33 : is_active_(false), 34 scroller_(GetScrollerConfig()) {} 35 36FlingAnimatorImpl::~FlingAnimatorImpl() {} 37 38void FlingAnimatorImpl::StartFling(const gfx::PointF& velocity) { 39 // No bounds on the fling. See http://webkit.org/b/96403 40 // Instead, use the largest possible bounds for minX/maxX/minY/maxY. The 41 // compositor will ignore any attempt to scroll beyond the end of the page. 42 43 DCHECK(velocity.x() || velocity.y()); 44 if (is_active_) 45 CancelFling(); 46 47 is_active_ = true; 48 scroller_.Fling(0, 49 0, 50 velocity.x(), 51 velocity.y(), 52 INT_MIN, 53 INT_MAX, 54 INT_MIN, 55 INT_MAX, 56 base::TimeTicks()); 57} 58 59void FlingAnimatorImpl::CancelFling() { 60 if (!is_active_) 61 return; 62 63 is_active_ = false; 64 scroller_.AbortAnimation(); 65} 66 67bool FlingAnimatorImpl::apply(double time, 68 blink::WebGestureCurveTarget* target) { 69 // If the fling has yet to start, simply return and report true to prevent 70 // fling termination. 71 if (time <= 0) 72 return true; 73 74 const base::TimeTicks time_ticks = 75 base::TimeTicks() + base::TimeDelta::FromMicroseconds( 76 time * base::Time::kMicrosecondsPerSecond); 77 if (!scroller_.ComputeScrollOffset(time_ticks)) { 78 is_active_ = false; 79 return false; 80 } 81 82 gfx::PointF current_position(scroller_.GetCurrX(), scroller_.GetCurrY()); 83 gfx::Vector2dF scroll_amount(current_position - last_position_); 84 last_position_ = current_position; 85 86 // scrollBy() could delete this curve if the animation is over, so don't touch 87 // any member variables after making that call. 88 return target->scrollBy(blink::WebFloatSize(scroll_amount), 89 blink::WebFloatSize(scroller_.GetCurrVelocityX(), 90 scroller_.GetCurrVelocityY())); 91} 92 93FlingAnimatorImpl* FlingAnimatorImpl::CreateAndroidGestureCurve( 94 const blink::WebFloatPoint& velocity, 95 const blink::WebSize&) { 96 FlingAnimatorImpl* gesture_curve = new FlingAnimatorImpl(); 97 gesture_curve->StartFling(velocity); 98 return gesture_curve; 99} 100 101} // namespace content 102