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