1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/child/fling_animator_impl_android.h"
#include "base/logging.h"
#include "third_party/WebKit/public/platform/WebFloatSize.h"
#include "third_party/WebKit/public/platform/WebGestureCurveTarget.h"
#include "ui/gfx/frame_time.h"
#include "ui/gfx/vector2d.h"
namespace content {
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
FlingAnimatorImpl::FlingAnimatorImpl()
: is_active_(false),
scroller_(GetScrollerConfig()) {}
FlingAnimatorImpl::~FlingAnimatorImpl() {}
void FlingAnimatorImpl::StartFling(const gfx::PointF& velocity) {
// No bounds on the fling. See http://webkit.org/b/96403
// Instead, use the largest possible bounds for minX/maxX/minY/maxY. The
// compositor will ignore any attempt to scroll beyond the end of the page.
DCHECK(velocity.x() || velocity.y());
if (is_active_)
CancelFling();
is_active_ = true;
scroller_.Fling(0,
0,
velocity.x(),
velocity.y(),
INT_MIN,
INT_MAX,
INT_MIN,
INT_MAX,
gfx::FrameTime::Now());
// TODO(jdduke): Initialize the fling at time 0 and use the monotonic
// time in |apply()| for updates, crbug.com/345459.
}
void FlingAnimatorImpl::CancelFling() {
if (!is_active_)
return;
is_active_ = false;
scroller_.AbortAnimation();
}
bool FlingAnimatorImpl::apply(double /* time */,
blink::WebGestureCurveTarget* target) {
// Historically, Android's Scroller used |currentAnimationTimeMillis()|,
// which is equivalent to gfx::FrameTime::Now(). In practice, this produces
// smoother results than using |time|, so continue using FrameTime::Now().
// TODO(jdduke): Use |time| upon resolution of crbug.com/345459.
if (!scroller_.ComputeScrollOffset(gfx::FrameTime::Now())) {
is_active_ = false;
return false;
}
gfx::PointF current_position(scroller_.GetCurrX(), scroller_.GetCurrY());
gfx::Vector2dF scroll_amount(current_position - last_position_);
last_position_ = current_position;
// scrollBy() could delete this curve if the animation is over, so don't touch
// any member variables after making that call.
return target->scrollBy(blink::WebFloatSize(scroll_amount),
blink::WebFloatSize(scroller_.GetCurrVelocityX(),
scroller_.GetCurrVelocityY()));
}
FlingAnimatorImpl* FlingAnimatorImpl::CreateAndroidGestureCurve(
const blink::WebFloatPoint& velocity,
const blink::WebSize&) {
FlingAnimatorImpl* gesture_curve = new FlingAnimatorImpl();
gesture_curve->StartFling(velocity);
return gesture_curve;
}
} // namespace content
|