Skip to content

Commit 9ef0f0d

Browse files
Jean-Baptiste QueruAndroid Code Review
authored andcommitted
Merge "New test in FrameworkTest for the VelocityTracker class"
2 parents ecfb185 + ade63a0 commit 9ef0f0d

File tree

1 file changed

+285
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)