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 13 namespace content { 14 15 namespace { 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). 21 const float kDefaultAndroidPlatformScrollFriction = 0.015f; 22 23 gfx::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 32 FlingAnimatorImpl::FlingAnimatorImpl() 33 : is_active_(false), 34 scroller_(GetScrollerConfig()) {} 35 36 FlingAnimatorImpl::~FlingAnimatorImpl() {} 37 38 void 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 59 void FlingAnimatorImpl::CancelFling() { 60 if (!is_active_) 61 return; 62 63 is_active_ = false; 64 scroller_.AbortAnimation(); 65 } 66 67 bool 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 93 FlingAnimatorImpl* 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