1ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle/*
2ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * Copyright (C) 2010 The Android Open Source Project
3ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle *
4ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * Licensed under the Apache License, Version 2.0 (the "License");
5ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * you may not use this file except in compliance with the License.
6ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * You may obtain a copy of the License at
7ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle *
8ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle *      http://www.apache.org/licenses/LICENSE-2.0
9ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle *
10ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * Unless required by applicable law or agreed to in writing, software
11ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * distributed under the License is distributed on an "AS IS" BASIS,
12ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * See the License for the specific language governing permissions and
14ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * limitations under the License.
15ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle */
16ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
17ade63a0555f2afa760329038024fc819715b0e72Marc Capdeviellepackage com.android.frameworktest.view;
18ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
19ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielleimport junit.framework.Assert;
20ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
21ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielleimport android.test.InstrumentationTestCase;
22ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielleimport android.test.suitebuilder.annotation.MediumTest;
23ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielleimport android.view.MotionEvent;
24ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielleimport android.view.VelocityTracker;
25ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielleimport android.view.animation.AccelerateInterpolator;
26ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielleimport android.view.animation.DecelerateInterpolator;
27ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielleimport android.view.animation.Interpolator;
28ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielleimport android.view.animation.LinearInterpolator;
29ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
30ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle/**
31ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * Exercises {@link android.view.VelocityTracker} to compute correct velocity.<br>
32ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * To launch this test, use :<br>
33ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle * <code>./development/testrunner/runtest.py framework -c com.android.frameworktest.view.VelocityTest</code>
34ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle */
35ade63a0555f2afa760329038024fc819715b0e72Marc Capdeviellepublic class VelocityTest extends InstrumentationTestCase {
36ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
37ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
38ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testInitialCondiditions() {
39ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
40ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertNotNull(vt);
41ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
42ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
43ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
44ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    /**
45ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * Test that {@link android.view.VelocityTracker}.clear() clears
46ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * the previous values after a call to computeCurrentVelocity()
47ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     */
48ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
49ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testClear() {
50ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
51ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
52ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 10, t, 300);
53ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
54ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertFalse("Velocity should not be null", vt.getXVelocity() == 0.0f);
55ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertFalse("Velocity should not be null", vt.getYVelocity() == 0.0f);
56ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.clear();
57ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
58ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEquals(0.0f, vt.getXVelocity());
59ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEquals(0.0f, vt.getYVelocity());
60ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
61ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
62ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
63ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
64ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testDragAcceleration () {
65ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
66ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
67ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 15, t, 400, new AccelerateInterpolator());
68ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1000);
69ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertGreater(250.0f, vt.getXVelocity());
70ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertGreater(250.0f, vt.getYVelocity());
71ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
72ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
73ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
74ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
75ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testDragDeceleration () {
76ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
77ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
78ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 15, t, 400, new DecelerateInterpolator());
79ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1000);
80ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertLower(250.0f, vt.getXVelocity());
81ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertLower(250.0f, vt.getYVelocity());
82ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
83ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
84ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
85ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
86ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testDragLinearHorizontal() {
87ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
88ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
89ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        // 100px in 400ms => 250px/s
90ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 200, 200, 15, t, 400);
91ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1000);
92ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEquals(0.0f, vt.getYVelocity());
93ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEqualFuzzy(250.0f, vt.getXVelocity(), 4f);
94ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
95ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
96ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
97ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
98ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testDragLinearVertical() {
99ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
100ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
101ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        // 100px in 400ms => 250px/s
102ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 200, 200, 100, 200, 15, t, 400);
103ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1000);
104ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEquals(0.0f, vt.getXVelocity());
105ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEqualFuzzy(250.0f, vt.getYVelocity(), 4f);
106ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
107ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
108ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
109ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    /**
110ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * Test dragging with two points only
111ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * (velocity must be an exact value)
112ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     */
113ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
114ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testDragWith2Points () {
115ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
116ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
117ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        // 100px, 2 steps, 100ms => 1000px/s
118ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 2, t, 100);
119ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1000);
120ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEquals(1000.0f, vt.getXVelocity());
121ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEquals(1000.0f, vt.getYVelocity());
122ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
123ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
124ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
125ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    /**
126ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * Velocity is independent of the number of points used during
127ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * the same interval
128ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     */
129ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
130ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testStabilityInNbPoints () {
131ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
132ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
133ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 10, t, 400); // 10 steps over 400ms
134ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
135ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float firstX = vt.getXVelocity();
136ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float firstY = vt.getYVelocity();
137ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.clear();
138ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 20, t, 400); // 20 steps over 400ms
139ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
140ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float secondX = vt.getXVelocity();
141ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float secondY = vt.getYVelocity();
142ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEqualFuzzy(firstX, secondX, 0.1f);
143ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEqualFuzzy(firstY, secondY, 0.1f);
144ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
145ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
146ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
147ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    /**
148ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * Velocity is independent of the time when the events occurs,
149ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * it only depends on delays between the events.
150ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     */
151ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
152ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testStabilityInTime () {
153ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
154ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
155ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 10, t, 400);
156ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
157ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float firstX = vt.getXVelocity();
158ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float firstY = vt.getYVelocity();
159ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.clear();
160ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 10, t + 3600*1000, 400); // on hour later
161ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
162ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float secondX = vt.getXVelocity();
163ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float secondY = vt.getYVelocity();
164ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEqualFuzzy(firstX, secondX, 0.1f);
165ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEqualFuzzy(firstY, secondY, 0.1f);
166ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
167ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
168ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
169ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    /**
170ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * Velocity is independent of the position of the events,
171ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * it only depends on their relative distance.
172ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     */
173ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
174ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testStabilityInSpace () {
175ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
176ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
177ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 10, t, 400);
178ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
179ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float firstX = vt.getXVelocity();
180ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float firstY = vt.getYVelocity();
181ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.clear();
182ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 200, 300, 200, 300, 10, t, 400); // 100px further
183ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
184ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float secondX = vt.getXVelocity();
185ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float secondY = vt.getYVelocity();
186ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEqualFuzzy(firstX, secondX, 0.1f);
187ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEqualFuzzy(firstY, secondY, 0.1f);
188ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
189ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
190ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
191ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    /**
192ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * Test that calls to {@link android.view.VelocityTracker}.computeCurrentVelocity()
193ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * will output same values when using the same data.
194ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     */
195ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
196ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testStabilityOfComputation() {
197ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
198ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
199ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 10, t, 300);
200ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
201ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float firstX = vt.getXVelocity();
202ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float firstY = vt.getYVelocity();
203ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
204ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float secondX = vt.getXVelocity();
205ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float secondY = vt.getYVelocity();
206ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEquals(firstX, secondX);
207ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEquals(firstY, secondY);
208ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
209ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
210ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
211ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    /**
212ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * Test the units parameter of {@link android.view.VelocityTracker}.computeCurrentVelocity()
213ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     */
214ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    @MediumTest
215ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    public void testStabilityOfUnits() {
216ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        long t = System.currentTimeMillis();
217ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        VelocityTracker vt = VelocityTracker.obtain();
218ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, 100, 200, 100, 200, 10, t, 300);
219ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1);
220ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float firstX = vt.getXVelocity();
221ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float firstY = vt.getYVelocity();
222ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.computeCurrentVelocity(1000);
223ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float secondX = vt.getXVelocity();
224ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float secondY = vt.getYVelocity();
225ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEqualFuzzy(firstX, secondX / 1000.0f, 0.1f);
226ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        assertEqualFuzzy(firstY, secondY / 1000.0f, 0.1f);
227ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.recycle();
228ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
229ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
230ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    /**
231ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * Simulate a drag by giving directly MotionEvents to
232ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * the VelocityTracker using a linear interpolator
233ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     */
234ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps,
235ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle            long startime, int duration) {
236ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        drag(vt, startX, endX, startY, endY, steps, startime, duration, new LinearInterpolator());
237ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
238ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
239ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    /**
240ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * Simulate a drag by giving directly MotionEvents to
241ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * the VelocityTracker using a given interpolator
242ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     */
243ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps,
244ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle            long startime, int duration, Interpolator interpolator) {
245ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        addMotionEvent(vt, startX, startY, startime, MotionEvent.ACTION_DOWN);
246ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        float dt = duration / (float)steps;
247ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        int distX = endX - startX;
248ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        int distY = endY - startY;
249ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        for (int i=1; i<steps-1; i++) {
250ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle            float ii = interpolator.getInterpolation(i / (float)steps);
251ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle            int x = (int) (startX + distX * ii);
252ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle            int y = (int) (startY + distY * ii);
253ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle            long time = startime + (int) (i * dt);
254ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle            addMotionEvent(vt, x, y, time, MotionEvent.ACTION_MOVE);
255ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        }
256ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        addMotionEvent(vt, endX, endY, startime + duration, MotionEvent.ACTION_UP);
257ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
258ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
259ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    private void addMotionEvent(VelocityTracker vt, int x, int y, long time, int action) {
260ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        MotionEvent me = MotionEvent.obtain(time, time, action, x, y, 0);
261ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        vt.addMovement(me);
262ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        me.recycle();
263ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
264ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
265ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    /**
266ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * Float imprecision of the average computations and filtering
267ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     * (removing last MotionEvent for N > 3) implies that tests
268ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     *  accepts some approximated values.
269ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle     */
270ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    private void assertEqualFuzzy(float expected, float actual, float threshold) {
271ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        boolean fuzzyEqual = actual >= expected - threshold && actual <= expected + threshold;
272ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        Assert.assertTrue("Expected: <"+expected+"> but was: <"+actual+
273ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle                "> while accepting a variation of: <"+threshold+">", fuzzyEqual);
274ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
275ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
276ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    private void assertGreater(float minExpected, float actual) {
277ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        Assert.assertTrue("Expected: minimum <"+minExpected+"> but was: <"+actual+">",
278ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle                actual > minExpected);
279ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
280ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle
281ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    private void assertLower(float maxExpected, float actual) {
282ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle        Assert.assertTrue("Expected: maximum <"+maxExpected+"> but was: <"+actual+">",
283ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle                actual < maxExpected);
284ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle    }
285ade63a0555f2afa760329038024fc819715b0e72Marc Capdevielle}
286