• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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 package android.animation.cts;
17 
18 import android.animation.Animator;
19 import android.animation.AnimatorListenerAdapter;
20 import android.animation.ObjectAnimator;
21 import android.animation.ValueAnimator;
22 import android.test.ActivityInstrumentationTestCase2;
23 import android.view.animation.AccelerateInterpolator;
24 import android.view.animation.LinearInterpolator;
25 
26 import java.util.concurrent.CountDownLatch;
27 import java.util.concurrent.TimeUnit;
28 
29 public class ValueAnimatorTest extends
30         ActivityInstrumentationTestCase2<AnimationActivity> {
31     private AnimationActivity mActivity;
32     private ValueAnimator mValueAnimator;
33     private long mDuration = 2000;
34 
ValueAnimatorTest()35     public ValueAnimatorTest() {
36         super(AnimationActivity.class);
37     }
38 
39     @Override
setUp()40     protected void setUp() throws Exception {
41         super.setUp();
42         setActivityInitialTouchMode(false);
43         mActivity = getActivity();
44         mValueAnimator = mActivity.createAnimatorWithDuration(mDuration);
45     }
46 
testDuration()47     public void testDuration() throws Throwable {
48         final long duration = 2000;
49         ValueAnimator valueAnimatorLocal = mActivity.createAnimatorWithDuration(duration);
50         startAnimation(valueAnimatorLocal);
51         assertEquals(duration, valueAnimatorLocal.getDuration());
52     }
53 
testIsRunning()54     public void testIsRunning() throws Throwable {
55         assertFalse(mValueAnimator.isRunning());
56         startAnimation(mValueAnimator);
57         ValueAnimator valueAnimatorReturned = mActivity.view.bounceYAnimator;
58         assertTrue(valueAnimatorReturned.isRunning());
59     }
60 
testIsStarted()61     public void testIsStarted() throws Throwable {
62         assertFalse(mValueAnimator.isRunning());
63         assertFalse(mValueAnimator.isStarted());
64         long startDelay = 10000;
65         mValueAnimator.setStartDelay(startDelay);
66         startAnimation(mValueAnimator);
67         assertFalse(mValueAnimator.isRunning());
68         assertTrue(mValueAnimator.isStarted());
69     }
70 
testRepeatMode()71     public void testRepeatMode() throws Throwable {
72         ValueAnimator mValueAnimator = mActivity.createAnimatorWithRepeatMode(
73             ValueAnimator.RESTART);
74         startAnimation(mValueAnimator);
75         assertEquals(ValueAnimator.RESTART, mValueAnimator.getRepeatMode());
76     }
77 
testRepeatCount()78     public void testRepeatCount() throws Throwable {
79         int repeatCount = 2;
80         ValueAnimator mValueAnimator = mActivity.createAnimatorWithRepeatCount(repeatCount);
81         startAnimation(mValueAnimator);
82         assertEquals(repeatCount, mValueAnimator.getRepeatCount());
83     }
84 
testStartDelay()85     public void testStartDelay() {
86         long startDelay = 1000;
87         mValueAnimator.setStartDelay(startDelay);
88         assertEquals(startDelay, mValueAnimator.getStartDelay());
89     }
90 
testGetCurrentPlayTime()91     public void testGetCurrentPlayTime() throws Throwable {
92         startAnimation(mValueAnimator);
93         Thread.sleep(100);
94         long currentPlayTime = mValueAnimator.getCurrentPlayTime();
95         assertTrue(currentPlayTime  >  0);
96     }
97 
98     /**
99      * Test for equality within some epsilon. This accounts for minor differences
100      * due to floating-point accuracy.
101      */
assertRoughlyEqual(float expected, float actual)102     private void assertRoughlyEqual(float expected, float actual) {
103         final float epsilon = .001f;
104         assertTrue(actual > (expected - epsilon) && actual < (expected + epsilon));
105     }
106 
testSetCurrentPlayTime()107     public void testSetCurrentPlayTime() throws Throwable {
108         final ValueAnimator anim = ValueAnimator.ofFloat(0, 100).setDuration(mDuration);
109         final ValueAnimator delayedAnim = ValueAnimator.ofFloat(0, 100).setDuration(mDuration);
110         delayedAnim.setStartDelay(mDuration);
111         final long proposedCurrentPlayTime = mDuration / 2;
112         runTestOnUiThread(new Runnable() {
113             @Override
114             public void run() {
115                 anim.setCurrentPlayTime(mDuration / 2);
116                 long currentPlayTime = anim.getCurrentPlayTime();
117                 float currentFraction = anim.getAnimatedFraction();
118                 float currentValue = (Float) anim.getAnimatedValue();
119                 assertEquals(proposedCurrentPlayTime, currentPlayTime);
120                 assertRoughlyEqual(.5f, currentFraction);
121                 assertRoughlyEqual(50, currentValue);
122 
123                 delayedAnim.setCurrentPlayTime(mDuration / 2);
124                 currentPlayTime = delayedAnim.getCurrentPlayTime();
125                 currentFraction = delayedAnim.getAnimatedFraction();
126                 currentValue = (Float) delayedAnim.getAnimatedValue();
127                 assertEquals(proposedCurrentPlayTime, currentPlayTime);
128                 assertRoughlyEqual(.5f, currentFraction);
129                 assertRoughlyEqual(50, currentValue);
130             }
131         });
132         // Now make sure that it's still true a little later, to test that we're
133         // getting a result based on the seek time, not the wall clock time
134         Thread.sleep(100);
135         long currentPlayTime = anim.getCurrentPlayTime();
136         float currentFraction = anim.getAnimatedFraction();
137         float currentValue = (Float) anim.getAnimatedValue();
138         assertEquals(proposedCurrentPlayTime, currentPlayTime);
139         assertRoughlyEqual(.5f, currentFraction);
140         assertRoughlyEqual(50, currentValue);
141 
142         currentPlayTime = delayedAnim.getCurrentPlayTime();
143         currentFraction = delayedAnim.getAnimatedFraction();
144         currentValue = (Float) delayedAnim.getAnimatedValue();
145         assertEquals(proposedCurrentPlayTime, currentPlayTime);
146         assertRoughlyEqual(.5f, currentFraction);
147         assertRoughlyEqual(50, currentValue);
148 
149         // Finally, start() the delayed animation and check that the play time was
150         // not affected by playing during the delay
151         runTestOnUiThread(new Runnable() {
152             @Override
153             public void run() {
154                 delayedAnim.start();
155                 long currentPlayTime = delayedAnim.getCurrentPlayTime();
156                 float currentFraction = delayedAnim.getAnimatedFraction();
157                 float currentValue = (Float) delayedAnim.getAnimatedValue();
158                 assertEquals(proposedCurrentPlayTime, currentPlayTime);
159                 assertRoughlyEqual(.5f, currentFraction);
160                 assertRoughlyEqual(50, currentValue);
161             }
162         });
163 
164         Thread.sleep(100);
165         currentPlayTime = delayedAnim.getCurrentPlayTime();
166         currentFraction = delayedAnim.getAnimatedFraction();
167         currentValue = (Float) delayedAnim.getAnimatedValue();
168         assertEquals(proposedCurrentPlayTime, currentPlayTime);
169         assertRoughlyEqual(.5f, currentFraction);
170         assertRoughlyEqual(50, currentValue);
171 
172         runTestOnUiThread(new Runnable() {
173             @Override
174             public void run() {
175                 delayedAnim.cancel();
176             }
177         });
178     }
179 
testSetCurrentPlayTimeAfterStart()180     public void testSetCurrentPlayTimeAfterStart() throws Throwable {
181         // This test sets current play time right after start() is called on a non-delayed animation
182         final long duration = 100;
183         final float seekFraction = 0.2f;
184         final CountDownLatch frameUpdateLatch = new CountDownLatch(1);
185         final CountDownLatch endLatch = new CountDownLatch(1);
186 
187         final ValueAnimator anim  = ValueAnimator.ofFloat(0, 1).setDuration(duration);
188         anim.setInterpolator(null);
189         anim.addListener(new AnimatorListenerAdapter() {
190             @Override
191             public void onAnimationEnd(Animator animation) {
192                 super.onAnimationEnd(animation);
193                 endLatch.countDown();
194             }
195         });
196         runTestOnUiThread(new Runnable() {
197             @Override
198             public void run() {
199                 anim.start();
200                 anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
201                     float fractionOnFirstFrame = -1f;
202                     @Override
203                     public void onAnimationUpdate(ValueAnimator animation) {
204                         if (fractionOnFirstFrame < 0) {
205                             // First frame:
206                             fractionOnFirstFrame = animation.getAnimatedFraction();
207                             assertRoughlyEqual(seekFraction, fractionOnFirstFrame);
208                             frameUpdateLatch.countDown();
209                         } else {
210                             assertTrue(animation.getAnimatedFraction() >= fractionOnFirstFrame);
211                         }
212                     }
213                 });
214                 long currentPlayTime = (long) (seekFraction * (float) duration);
215                 anim.setCurrentPlayTime(currentPlayTime);
216             }
217         });
218         assertTrue(frameUpdateLatch.await(100, TimeUnit.MILLISECONDS));
219         assertTrue(endLatch.await(200, TimeUnit.MILLISECONDS));
220     }
221 
testSetCurrentFraction()222     public void testSetCurrentFraction() throws Throwable {
223         final ValueAnimator anim = ValueAnimator.ofFloat(0, 100).setDuration(mDuration);
224         final long proposedCurrentPlayTime = mDuration / 2;
225         runTestOnUiThread(new Runnable() {
226             @Override
227             public void run() {
228                 anim.setCurrentFraction(.5f);
229                 long currentPlayTime = anim.getCurrentPlayTime();
230                 float currentFraction = anim.getAnimatedFraction();
231                 float currentValue = (Float) anim.getAnimatedValue();
232                 assertEquals(proposedCurrentPlayTime, currentPlayTime);
233                 assertRoughlyEqual(.5f, currentFraction);
234                 assertRoughlyEqual(50, currentValue);
235             }
236         });
237         // Now make sure that it's still true a little later, to test that we're
238         // getting a result based on the seek time, not the wall clock time
239         Thread.sleep(100);
240         long currentPlayTime = anim.getCurrentPlayTime();
241         float currentFraction = anim.getAnimatedFraction();
242         float currentValue = (Float) anim.getAnimatedValue();
243         assertEquals(proposedCurrentPlayTime, currentPlayTime);
244         assertRoughlyEqual(.5f, currentFraction);
245         assertRoughlyEqual(50, currentValue);
246     }
247 
testReverseRightAfterStart()248     public void testReverseRightAfterStart() throws Throwable {
249         runTestOnUiThread(new Runnable() {
250             @Override
251             public void run() {
252                 // Reverse() right after start() should trigger immediate end() at fraction 0.
253                 final ValueAnimator anim = ValueAnimator.ofFloat(0, 100).setDuration(mDuration);
254                 anim.start();
255                 assertTrue(anim.isStarted());
256                 anim.reverse();
257                 assertFalse(anim.isStarted());
258                 assertEquals(0f, anim.getAnimatedFraction());
259             }
260         });
261     }
262 
testGetFrameDelay()263     public void testGetFrameDelay() throws Throwable {
264         final long frameDelay = 10;
265         runTestOnUiThread(new Runnable() {
266             @Override
267             public void run() {
268                 mValueAnimator.setFrameDelay(frameDelay);
269             }
270         });
271         startAnimation(mValueAnimator);
272         Thread.sleep(100);
273         runTestOnUiThread(new Runnable() {
274             @Override
275             public void run() {
276                 long actualFrameDelay = mValueAnimator.getFrameDelay();
277                 assertEquals(frameDelay, actualFrameDelay);
278             }
279         });
280     }
281 
testSetInterpolator()282     public void testSetInterpolator() throws Throwable {
283         AccelerateInterpolator interpolator = new AccelerateInterpolator();
284         ValueAnimator mValueAnimator = mActivity.createAnimatorWithInterpolator(interpolator);
285         startAnimation(mValueAnimator);
286         assertTrue(interpolator.equals(mValueAnimator.getInterpolator()));
287     }
288 
testCancel()289     public void testCancel() throws Throwable {
290         startAnimation(mValueAnimator);
291         Thread.sleep(100);
292         cancelAnimation(mValueAnimator);
293         assertFalse(mValueAnimator.isRunning());
294     }
295 
testEnd()296     public void testEnd() throws Throwable {
297         Object object = mActivity.view.newBall;
298         String property = "y";
299         float startY = mActivity.mStartY;
300         float endY = mActivity.mStartY + mActivity.mDeltaY;
301         ObjectAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
302         objAnimator.setDuration(mDuration);
303         objAnimator.setRepeatCount(ValueAnimator.INFINITE);
304         objAnimator.setInterpolator(new AccelerateInterpolator());
305         objAnimator.setRepeatMode(ValueAnimator.REVERSE);
306         startAnimation(objAnimator);
307         Thread.sleep(100);
308         endAnimation(objAnimator);
309         float y = mActivity.view.newBall.getY();
310         assertEquals(y, endY);
311     }
312 
testGetAnimatedFraction()313     public void testGetAnimatedFraction() throws Throwable {
314         ValueAnimator objAnimator = getAnimator();
315         startAnimation(objAnimator);
316         assertNotNull(objAnimator);
317         float[] fractions = getValue(objAnimator, 10, "getAnimatedFraction()", 200l, null);
318         for(int j = 0; j < 9; j++){
319             assertTrue(fractions[j] >= 0.0);
320             assertTrue(fractions[j] <= 1.0);
321             assertTrue(errorMessage(fractions), fractions[j + 1] >= fractions[j]);
322         }
323     }
324 
testGetAnimatedValue()325     public void testGetAnimatedValue() throws Throwable {
326         ValueAnimator objAnimator = getAnimator();
327         startAnimation(objAnimator);
328         assertNotNull(objAnimator);
329         float[] animatedValues = getValue(objAnimator, 10, "getAnimatedValue()", 200l, null);
330 
331         for(int j = 0; j < 9; j++){
332             assertTrue(errorMessage(animatedValues), animatedValues[j + 1] >= animatedValues[j]);
333         }
334     }
testGetAnimatedValue_PropertyName()335     public void testGetAnimatedValue_PropertyName() throws Throwable {
336         String property = "y";
337 
338         ValueAnimator objAnimator = getAnimator();
339         startAnimation(objAnimator);
340         assertNotNull(objAnimator);
341         float[] animatedValues = getValue(objAnimator, 10, "getAnimatedValue(property)", 200l,
342             property);
343         for(int j = 0; j < 9; j++){
344             assertTrue(errorMessage(animatedValues), animatedValues[j + 1] >= animatedValues[j]);
345         }
346     }
347 
testOfFloat()348     public void testOfFloat() throws Throwable {
349         float start = 0.0f;
350         float end = 1.0f;
351         float[] values = {start, end};
352         final ValueAnimator valueAnimatorLocal = ValueAnimator.ofFloat(values);
353         valueAnimatorLocal.setDuration(mDuration);
354         valueAnimatorLocal.setRepeatCount(ValueAnimator.INFINITE);
355         valueAnimatorLocal.setInterpolator(new AccelerateInterpolator());
356         valueAnimatorLocal.setRepeatMode(ValueAnimator.RESTART);
357 
358         this.runTestOnUiThread(new Runnable(){
359             public void run() {
360                 valueAnimatorLocal.start();
361             }
362         });
363         Thread.sleep(100);
364         boolean isRunning = valueAnimatorLocal.isRunning();
365         assertTrue(isRunning);
366 
367         Float animatedValue = (Float) valueAnimatorLocal.getAnimatedValue();
368         assertTrue(animatedValue >= start);
369         assertTrue(animatedValue <= end);
370     }
371 
testOfInt()372     public void testOfInt() throws Throwable {
373         int start = 0;
374         int end = 10;
375         int[] values = {start, end};
376         final ValueAnimator valueAnimatorLocal = ValueAnimator.ofInt(values);
377         valueAnimatorLocal.setDuration(mDuration);
378         valueAnimatorLocal.setRepeatCount(ValueAnimator.INFINITE);
379         valueAnimatorLocal.setInterpolator(new AccelerateInterpolator());
380         valueAnimatorLocal.setRepeatMode(ValueAnimator.RESTART);
381 
382         this.runTestOnUiThread(new Runnable(){
383             public void run() {
384                 valueAnimatorLocal.start();
385             }
386         });
387         Thread.sleep(100);
388         boolean isRunning = valueAnimatorLocal.isRunning();
389         assertTrue(isRunning);
390 
391         Integer animatedValue = (Integer) valueAnimatorLocal.getAnimatedValue();
392         assertTrue(animatedValue >= start);
393         assertTrue(animatedValue <= end);
394     }
395 
testNoDelayOnSeekAnimation()396     public void testNoDelayOnSeekAnimation() throws Throwable {
397         ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
398         animator.setInterpolator(new LinearInterpolator());
399         animator.setStartDelay(1000);
400         animator.setDuration(300);
401         animator.setCurrentPlayTime(150);
402         EventWatcher watcher = new EventWatcher();
403         animator.addListener(watcher);
404         runTestOnUiThread(new Runnable() {
405             @Override
406             public void run() {
407                 animator.start();
408             }
409         });
410         assertTrue(watcher.start.await(0, TimeUnit.MILLISECONDS));
411         assertTrue(((Float)animator.getAnimatedValue()) >= 0.5f);
412         assertTrue(animator.getAnimatedFraction() >= 0.5f);
413         runTestOnUiThread(new Runnable() {
414             @Override
415             public void run() {
416                 animator.cancel();
417             }
418         });
419     }
420 
getAnimator()421     private ValueAnimator getAnimator() {
422         Object object = mActivity.view.newBall;
423         String property = "y";
424         float startY = mActivity.mStartY;
425         float endY = mActivity.mStartY + mActivity.mDeltaY;
426         ValueAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
427         objAnimator.setDuration(mDuration);
428         objAnimator.setRepeatCount(ValueAnimator.INFINITE);
429         objAnimator.setInterpolator(new AccelerateInterpolator());
430         objAnimator.setRepeatMode(ValueAnimator.REVERSE);
431         return objAnimator;
432     }
433 
getValue(ValueAnimator animator, int n, String methodName, long sleepTime, String property)434     private float[] getValue(ValueAnimator animator, int n, String methodName,
435             long sleepTime, String property) throws InterruptedException {
436         float[] values = new float[n];
437         for(int i = 0; i < n; i++){
438             Thread.sleep(sleepTime);
439             float value = 0.0f;
440             if(methodName.equals("getAnimatedFraction()")) {
441                 value = animator.getAnimatedFraction();
442             }else if(methodName.equals("getAnimatedValue()")) {
443               value = ((Float)animator.getAnimatedValue()).floatValue();
444             }else if(methodName.equals("getAnimatedValue(property)")) {
445               value = ((Float)animator.getAnimatedValue(property)).floatValue();
446             }
447             values[i] = value;
448         }
449         return values;
450     }
451 
startAnimation(final ValueAnimator animator)452     private void startAnimation(final ValueAnimator animator) throws Throwable {
453         this.runTestOnUiThread(new Runnable() {
454             public void run() {
455                 mActivity.startAnimation(animator);
456             }
457         });
458     }
459 
endAnimation(final ValueAnimator animator)460     private void endAnimation(final ValueAnimator animator) throws Throwable {
461         this.runTestOnUiThread(new Runnable() {
462             public void run() {
463                 animator.end();
464             }
465         });
466     }
467 
cancelAnimation(final ValueAnimator animator)468     private void cancelAnimation(final ValueAnimator animator) throws Throwable {
469         this.runTestOnUiThread(new Runnable() {
470             public void run() {
471                 animator.cancel();
472             }
473         });
474     }
475 
errorMessage(float[] values)476     private String errorMessage(float[] values) {
477         StringBuilder message = new StringBuilder();
478         for (int i = 0; i < values.length; i++) {
479             message.append(values[i]).append(" ");
480         }
481         return message.toString();
482     }
483 
484     class EventWatcher implements Animator.AnimatorListener {
485         public CountDownLatch start = new CountDownLatch(1);
486         public CountDownLatch end = new CountDownLatch(1);
487         public CountDownLatch cancel = new CountDownLatch(1);
488         public CountDownLatch repeat = new CountDownLatch(1);
489 
onAnimationCancel(Animator animation)490         public void onAnimationCancel(Animator animation) {
491             cancel.countDown();
492         }
493 
onAnimationEnd(Animator animation)494         public void onAnimationEnd(Animator animation) {
495             end.countDown();
496         }
497 
onAnimationRepeat(Animator animation)498         public void onAnimationRepeat(Animator animation) {
499             repeat.countDown();
500         }
501 
onAnimationStart(Animator animation)502         public void onAnimationStart(Animator animation) {
503             start.countDown();
504         }
505     }
506 }
507