Home | History | Annotate | Download | only in animation
      1 package android.animation;
      2 
      3 import com.android.frameworks.coretests.R;
      4 
      5 import android.test.ActivityInstrumentationTestCase2;
      6 import android.test.UiThreadTest;
      7 import android.test.suitebuilder.annotation.SmallTest;
      8 import android.view.View;
      9 
     10 import java.util.ArrayList;
     11 
     12 public class AnimatorSetActivityTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> {
     13 
     14     private static final long POLL_INTERVAL = 100; // ms
     15     private AnimatorSetActivity mActivity;
     16     private ObjectAnimator a1,a2,a3;
     17     private ValueAnimator a4,a5;
     18 
     19     public AnimatorSetActivityTest() {
     20         super(AnimatorSetActivity.class);
     21     }
     22 
     23     static class MyListener implements Animator.AnimatorListener {
     24         boolean startIsCalled = false;
     25         boolean endIsCalled = false;
     26         boolean cancelIsCalled = false;
     27 
     28         @Override
     29         public void onAnimationStart(Animator animation) {
     30             startIsCalled = true;
     31         }
     32 
     33         @Override
     34         public void onAnimationEnd(Animator animation) {
     35             endIsCalled = true;
     36         }
     37 
     38         @Override
     39         public void onAnimationCancel(Animator animation) {
     40             cancelIsCalled = true;
     41         }
     42 
     43         @Override
     44         public void onAnimationRepeat(Animator animation) {
     45 
     46         }
     47     }
     48 
     49     @Override
     50     public void setUp() throws Exception {
     51         super.setUp();
     52         mActivity = getActivity();
     53 
     54         View square1 = mActivity.findViewById(R.id.square1);
     55         View square2 = mActivity.findViewById(R.id.square2);
     56         View square3 = mActivity.findViewById(R.id.square3);
     57         a1 = ObjectAnimator.ofFloat(square1, View.TRANSLATION_X, 0f, 500f, 0f).setDuration(250);
     58         a2 = ObjectAnimator.ofFloat(square2, View.ALPHA, 1f, 0f).setDuration(350);
     59         a3 = ObjectAnimator.ofFloat(square3, View.ROTATION, 0, 90).setDuration(450);
     60         a4 = ValueAnimator.ofInt(100, 200).setDuration(450);
     61         a5 = ValueAnimator.ofFloat(10f, 5f).setDuration(850);
     62     }
     63 
     64     @Override
     65     public void tearDown() throws Exception {
     66         mActivity = null;
     67         a1 = null;
     68         a2 = null;
     69         a3 = null;
     70         a4 = null;
     71         a5 = null;
     72         super.tearDown();
     73     }
     74 
     75     @SmallTest
     76     public void testGetChildAnimations() {
     77         AnimatorSet s1 = new AnimatorSet();
     78         s1.playTogether(a1, a2, a3);
     79         ArrayList<Animator> children = s1.getChildAnimations();
     80         assertEquals(3, children.size());
     81         assertTrue(children.contains(a1));
     82         assertTrue(children.contains(a2));
     83         assertTrue(children.contains(a3));
     84 
     85         AnimatorSet s2 = new AnimatorSet();
     86         s2.playSequentially(a1, a2, a3);
     87         children = s2.getChildAnimations();
     88         assertEquals(3, children.size());
     89         assertTrue(children.contains(a1));
     90         assertTrue(children.contains(a2));
     91         assertTrue(children.contains(a3));
     92 
     93         AnimatorSet s3 = new AnimatorSet();
     94         s3.play(a1).before(a2).after(s1).with(s2).after(a3);
     95         ArrayList<Animator> s3Children = s3.getChildAnimations();
     96         assertNotNull(s3Children);
     97         assertEquals(5, s3Children.size());
     98         assertTrue(s3Children.contains(a1));
     99         assertTrue(s3Children.contains(a2));
    100         assertTrue(s3Children.contains(a3));
    101         assertTrue(s3Children.contains(s1));
    102         assertTrue(s3Children.contains(s2));
    103 
    104         AnimatorSet s4 = new AnimatorSet();
    105         s4.playSequentially(s3Children);
    106         ArrayList<Animator> s4Children = s4.getChildAnimations();
    107         assertNotNull(s4Children);
    108         assertEquals(s3Children.size(), s4Children.size());
    109         for (int i = 0; i < s3Children.size(); i++) {
    110             Animator child = s3Children.get(i);
    111             assertTrue(s4Children.contains(child));
    112         }
    113     }
    114 
    115     @SmallTest
    116     public void testTotalDuration() {
    117         ArrayList<Animator> list = getAnimatorList();
    118 
    119         // Run animations sequentially and test the total duration against sum of durations.
    120         AnimatorSet s1 = new AnimatorSet();
    121         s1.playSequentially(list);
    122         long totalDuration = 0;
    123         for (int i = 0; i < list.size(); i++) {
    124             Animator anim = list.get(i);
    125             anim.setStartDelay(0);
    126             totalDuration += list.get(i).getDuration();
    127         }
    128         assertEquals(totalDuration, s1.getTotalDuration());
    129 
    130         // Add delay to set, and test total duration
    131         s1.setStartDelay(200);
    132         assertEquals(totalDuration + 200, s1.getTotalDuration());
    133 
    134         a1.setStartDelay(100);
    135         assertEquals(totalDuration + 200 + 100, s1.getTotalDuration());
    136 
    137         // Run animations simultaneously, test the total duration against the longest duration
    138         AnimatorSet s2 = new AnimatorSet();
    139         s2.playTogether(list);
    140         long maxDuration = 0;
    141         for (int i = 0; i < list.size(); i++) {
    142             long duration = list.get(i).getDuration();
    143             list.get(i).setStartDelay(100);
    144             maxDuration = maxDuration > (duration + 100) ? maxDuration : (duration + 100);
    145         }
    146         assertEquals(maxDuration, s2.getTotalDuration());
    147 
    148         // Form a cycle in the AnimatorSet and test the total duration
    149         AnimatorSet s3 = new AnimatorSet();
    150         s3.play(a1).before(a2).after(a3);
    151         s3.play(a1).after(a2).with(a4);
    152         assertEquals(AnimatorSet.DURATION_INFINITE, s3.getTotalDuration());
    153 
    154         // Put all the animators in a cycle
    155         AnimatorSet s4 = new AnimatorSet();
    156         s4.play(a1).after(a2);
    157         s4.play(a2).after(a1);
    158         assertEquals(AnimatorSet.DURATION_INFINITE, s4.getTotalDuration());
    159 
    160         // No cycle in the set, run a2, a1, a3 in sequence, and a2, a4, a5 together
    161         AnimatorSet s5 = new AnimatorSet();
    162         s5.play(a1).after(a2).before(a3);
    163         s5.play(a2).with(a4).with(a5);
    164         long duration = a1.getDuration() + a1.getStartDelay() + a2.getDuration() + a2
    165                 .getStartDelay() + a3.getDuration() + a3.getStartDelay();
    166         long a4Duration = a4.getDuration() + a4.getStartDelay();
    167         long a5Duration = a5.getDuration() + a5.getStartDelay();
    168         duration = Math.max(duration, a4Duration);
    169         duration = Math.max(duration, a5Duration);
    170         assertEquals(duration, s5.getTotalDuration());
    171 
    172         // Change one animator to repeat infinitely and test the total time
    173         a3.setRepeatCount(ValueAnimator.INFINITE);
    174         assertEquals(AnimatorSet.DURATION_INFINITE, s5.getTotalDuration());
    175 
    176     }
    177 
    178     @SmallTest
    179     public void testGetDuration() {
    180         AnimatorSet s = new AnimatorSet();
    181         assertTrue(s.getDuration() < 0);
    182         s.play(a1).before(a2).before(a3).after(a4).after(a5);
    183         assertTrue(s.getDuration() < 0);
    184 
    185         long duration = 200;
    186         s.setDuration(duration);
    187         assertEquals(duration, s.getDuration());
    188 
    189     }
    190 
    191     @SmallTest
    192     @UiThreadTest
    193     public void testSetDuration() {
    194         AnimatorSet s = getSequentialSet();
    195         assertTrue(s.getDuration() < 0);
    196 
    197         long duration = 300;
    198         s.setDuration(duration);
    199         assertEquals(duration, s.getDuration());
    200 
    201         s.start();
    202         assertEquals(duration, s.getDuration());
    203         assertEquals(duration, a1.getDuration());
    204         assertEquals(duration, a2.getDuration());
    205         assertEquals(duration, a3.getDuration());
    206         assertEquals(duration, a4.getDuration());
    207         assertEquals(duration, a5.getDuration());
    208     }
    209 
    210     @SmallTest
    211     public void testAddListener() throws InterruptedException {
    212         // Verify that the listener is added to the list of listeners in the AnimatorSet
    213         // and that newly added listener gets callback for lifecycle events of the animator
    214         final AnimatorSet s = new AnimatorSet();
    215         s.play(a1).before(a2).before(a3).after(a4).after(a5);
    216         final MyListener listener = new MyListener();
    217         if (s.getListeners() != null) {
    218             assertFalse(s.getListeners().contains(listener));
    219         }
    220         s.addListener(listener);
    221         assertTrue(s.getListeners().contains(listener));
    222 
    223         assertFalse(listener.startIsCalled);
    224         assertFalse(listener.endIsCalled);
    225 
    226         try {
    227             runTestOnUiThread(new Runnable() {
    228                 @Override
    229                 public void run() {
    230                     s.start();
    231                     assertTrue(listener.startIsCalled);
    232                     assertFalse(listener.endIsCalled);
    233                 }
    234             });
    235         } catch (Throwable throwable) {
    236             throwable.printStackTrace();
    237         }
    238 
    239         Thread.sleep(s.getTotalDuration() + 200);
    240         assertTrue(listener.startIsCalled);
    241         assertTrue(listener.endIsCalled);
    242     }
    243 
    244     @SmallTest
    245     public void testRemoveListener() throws Throwable {
    246         final AnimatorSet s = new AnimatorSet();
    247         s.playTogether(a1, a2, a3, a4);
    248         MyListener listener = new MyListener();
    249         s.addListener(listener);
    250         runTestOnUiThread(new Runnable() {
    251             @Override
    252             public void run() {
    253                 s.start();
    254             }
    255         });
    256 
    257         Thread.sleep(s.getTotalDuration() + 100);
    258         assertTrue(listener.startIsCalled);
    259         assertTrue(listener.endIsCalled);
    260 
    261         s.removeListener(listener);
    262         if (s.getListeners() != null) {
    263             assertFalse(s.getListeners().contains(listener));
    264         }
    265         listener.startIsCalled = false;
    266         listener.endIsCalled = false;
    267 
    268         runTestOnUiThread(new Runnable() {
    269             @Override
    270             public void run() {
    271                 s.start();
    272             }
    273         });
    274         Thread.sleep(s.getTotalDuration() + 100);
    275         assertFalse(listener.startIsCalled);
    276         assertFalse(listener.endIsCalled);
    277     }
    278 
    279     @SmallTest
    280     public void testEnd() throws Throwable {
    281         // End animator set
    282         final AnimatorSet s = new AnimatorSet();
    283         s.play(a1).before(a2).after(a3).with(a4);
    284         final MyListener listener = new MyListener();
    285         s.addListener(listener);
    286         assertFalse(listener.endIsCalled);
    287         runTestOnUiThread(new Runnable() {
    288             @Override
    289             public void run() {
    290                 s.start();
    291                 assertTrue(s.isStarted());
    292                 assertTrue(listener.startIsCalled);
    293                 assertFalse(listener.endIsCalled);
    294             }
    295         });
    296 
    297         Thread.sleep(a2.getTotalDuration());
    298 
    299         runTestOnUiThread(new Runnable() {
    300             @Override
    301             public void run() {
    302                 s.end();
    303                 assertTrue(listener.startIsCalled);
    304                 assertTrue(listener.endIsCalled);
    305                 assertFalse(s.isRunning());
    306                 assertFalse(s.isStarted());
    307 
    308                 assertFalse(a1.isStarted());
    309                 assertFalse(a2.isStarted());
    310                 assertFalse(a3.isStarted());
    311                 assertFalse(a4.isStarted());
    312             }
    313         });
    314 
    315     }
    316 
    317     @SmallTest
    318     public void testStart() throws Throwable {
    319         final AnimatorSet s = new AnimatorSet();
    320         ArrayList<Animator> animators = getAnimatorList();
    321 
    322         s.playSequentially(animators);
    323         final MyListener l = new MyListener();
    324         s.addListener(l);
    325 
    326         ArrayList<MyListener> listeners = new ArrayList<>(animators.size());
    327         for (int i = 0; i < animators.size(); i++) {
    328             MyListener listener = new MyListener();
    329             listeners.add(listener);
    330             animators.get(i).addListener(listener);
    331         }
    332 
    333         // Check the state before calling start()
    334         assertFalse(l.startIsCalled);
    335         assertFalse(l.endIsCalled);
    336         for (int i = 0; i < listeners.size(); i++) {
    337             assertFalse(l.startIsCalled);
    338             assertFalse(l.endIsCalled);
    339         }
    340 
    341         runTestOnUiThread(new Runnable() {
    342             @Override
    343             public void run() {
    344                 s.start();
    345                 assertTrue(l.startIsCalled);
    346             }
    347         });
    348 
    349         long timeout = s.getTotalDuration() * 2;
    350         long wait = 0;
    351 
    352         while (wait < timeout) {
    353             if (l.endIsCalled) {
    354                 break;
    355             }
    356             Thread.sleep(200);
    357             wait += 200;
    358         }
    359 
    360         // Now the set should finished
    361         assertTrue(l.startIsCalled);
    362         assertTrue(l.endIsCalled);
    363         for (int i = 0; i < listeners.size(); i++) {
    364             assertTrue(listeners.get(i).startIsCalled);
    365             assertTrue(listeners.get(i).endIsCalled);
    366         }
    367     }
    368 
    369     @SmallTest
    370     public void testCancel() throws Throwable {
    371         // Check whether cancel would trigger onAnimationCanceled and cancel all the unfinished
    372         // animations
    373         final AnimatorSet s = new AnimatorSet();
    374         final ArrayList<Animator> animators = getAnimatorList();
    375 
    376         s.playTogether(animators);
    377         final MyListener l = new MyListener();
    378         s.addListener(l);
    379 
    380         final ArrayList<MyListener> listeners = new ArrayList<>(5);
    381         for (int i = 0; i < animators.size(); i++) {
    382             MyListener listener = new MyListener();
    383             listeners.add(listener);
    384             animators.get(i).addListener(listener);
    385         }
    386 
    387         // Check the state before calling start()
    388         assertFalse(l.startIsCalled);
    389         assertFalse(l.cancelIsCalled);
    390         assertFalse(l.endIsCalled);
    391         for (int i = 0; i < listeners.size(); i++) {
    392             assertFalse(l.startIsCalled);
    393             assertFalse(l.cancelIsCalled);
    394             assertFalse(l.endIsCalled);
    395         }
    396 
    397         runTestOnUiThread(new Runnable() {
    398             @Override
    399             public void run() {
    400                 s.start();
    401             }
    402         });
    403 
    404         Thread.sleep(a1.getTotalDuration());
    405         runTestOnUiThread(new Runnable() {
    406             @Override
    407             public void run() {
    408                 assertTrue(s.isStarted());
    409                 ArrayList<Integer> runningAnimIds = new ArrayList<Integer>();
    410                 for (int i = 0; i < animators.size(); i++) {
    411                     if (animators.get(i).isStarted()) {
    412                         runningAnimIds.add(i);
    413                     }
    414                 }
    415                 s.cancel();
    416                 assertTrue(l.startIsCalled);
    417                 assertTrue(l.cancelIsCalled);
    418                 assertTrue(l.endIsCalled);
    419 
    420                 for (int i = 0; i < listeners.size(); i++) {
    421                     assertTrue(listeners.get(i).startIsCalled);
    422                     if (runningAnimIds.contains(i)) {
    423                         assertTrue(listeners.get(i).cancelIsCalled);
    424                     }
    425                     assertTrue(listeners.get(i).endIsCalled);
    426                 }
    427             }
    428         });
    429 
    430     }
    431 
    432     @SmallTest
    433     public void testIsRunning() throws Throwable {
    434         final AnimatorSet s = new AnimatorSet();
    435         final long startDelay = 500;
    436         s.play(a1).before(a2).after(a3).with(a4);
    437         s.play(a3).after(a5);
    438         s.setStartDelay(startDelay);
    439         MyListener listener = new MyListener();
    440         s.addListener(listener);
    441         runTestOnUiThread(new Runnable() {
    442             @Override
    443             public void run() {
    444                 s.start();
    445             }
    446         });
    447 
    448         while (!listener.endIsCalled) {
    449             boolean passedStartDelay = a1.isStarted() || a2.isStarted() || a3.isStarted() ||
    450                     a4.isStarted() || a5.isStarted();
    451             assertEquals(passedStartDelay, s.isRunning());
    452             Thread.sleep(50);
    453         }
    454         assertFalse(s.isRunning());
    455     }
    456 
    457     @SmallTest
    458     public void testPauseAndResume() throws Throwable {
    459         final AnimatorSet set = getSequentialSet();
    460         runTestOnUiThread(new Runnable() {
    461             @Override
    462             public void run() {
    463                 // Calling pause before start should have no effect, per documentation
    464                 set.pause();
    465                 set.start();
    466                 assertFalse(set.isPaused());
    467             }
    468         });
    469 
    470         while (!a2.isStarted()) {
    471             Thread.sleep(50);
    472         }
    473         runTestOnUiThread(new Runnable() {
    474             @Override
    475             public void run() {
    476                 assertFalse(set.isPaused());
    477                 set.pause();
    478                 assertTrue(set.isPaused());
    479                 set.resume();
    480                 assertFalse(set.isPaused());
    481             }
    482         });
    483     }
    484 
    485     @SmallTest
    486     public void testClone() throws Throwable {
    487         // Set up an AnimatorSet and two clones, add one listener to each. When the clones animate,
    488         // listeners of both the clone and the animator being cloned should receive animation
    489         // lifecycle events.
    490         final AnimatorSet s1 = getSequentialSet();
    491 
    492         // Record animators that called their listeners for the corresponding event.
    493         final ArrayList<Animator> startedAnimators = new ArrayList<>();
    494         final ArrayList<Animator> canceledAnimators = new ArrayList<>();
    495         final ArrayList<Animator> endedAnimators = new ArrayList<>();
    496 
    497         final MyListener l1 = new MyListener() {
    498             @Override
    499             public void onAnimationStart(Animator anim) {
    500                 super.onAnimationStart(anim);
    501                 startedAnimators.add(anim);
    502             }
    503 
    504             @Override
    505             public void onAnimationCancel(Animator anim) {
    506                 super.onAnimationCancel(anim);
    507                 canceledAnimators.add(anim);
    508             }
    509 
    510             @Override
    511             public void onAnimationEnd(Animator anim) {
    512                 super.onAnimationEnd(anim);
    513                 endedAnimators.add(anim);
    514             }
    515 
    516         };
    517         s1.addListener(l1);
    518 
    519         // Start the animation, and make the first clone during its run and the second clone once
    520         // it ends.
    521         runTestOnUiThread(new Runnable() {
    522             @Override
    523             public void run() {
    524                 assertFalse(l1.startIsCalled);
    525                 assertFalse(l1.endIsCalled);
    526 
    527                 s1.start();
    528             }
    529         });
    530 
    531         // Make the first clone, during the animation's run.
    532         assertTrue(s1.isStarted());
    533         final AnimatorSet s2 = s1.clone();
    534         final MyListener l2 = new MyListener();
    535         s2.addListener(l2);
    536 
    537         Thread.sleep(POLL_INTERVAL);
    538         runTestOnUiThread(new Runnable() {
    539             @Override
    540             public void run() {
    541                 s1.end();
    542             }
    543         });
    544 
    545         Thread.sleep(POLL_INTERVAL);
    546         runTestOnUiThread(new Runnable() {
    547             @Override
    548             public void run() {
    549                 assertTrue(l1.startIsCalled);
    550                 assertTrue(l1.endIsCalled);
    551             }
    552         });
    553         Thread.sleep(POLL_INTERVAL);
    554 
    555         // Make the second clone now.
    556         final AnimatorSet s3 = s1.clone();
    557         final MyListener l3 = new MyListener();
    558         s3.addListener(l3);
    559 
    560         runTestOnUiThread(new Runnable() {
    561             @Override
    562             public void run() {
    563                 // Checking the fields before animations start.
    564                 assertFalse(l2.startIsCalled);
    565                 assertFalse(l2.cancelIsCalled);
    566                 assertFalse(l2.endIsCalled);
    567                 assertFalse(l3.startIsCalled);
    568                 assertFalse(l3.cancelIsCalled);
    569                 assertFalse(l3.endIsCalled);
    570 
    571                 s2.start();
    572                 s3.start();
    573             }
    574         });
    575 
    576         Thread.sleep(POLL_INTERVAL);
    577         runTestOnUiThread(new Runnable() {
    578             @Override
    579             public void run() {
    580                 // Make sure the listeners receive the callbacks
    581                 // At this time only onAnimationStart() should be called.
    582                 assertTrue(l2.startIsCalled);
    583                 assertTrue(l3.startIsCalled);
    584                 assertFalse(l2.endIsCalled);
    585                 assertFalse(l3.endIsCalled);
    586                 assertFalse(l2.cancelIsCalled);
    587                 assertFalse(l3.cancelIsCalled);
    588 
    589                 s2.end();
    590                 s3.cancel();
    591             }
    592         });
    593         Thread.sleep(POLL_INTERVAL);
    594         runTestOnUiThread(new Runnable() {
    595             @Override
    596             public void run() {
    597                 // Check that the new listeners for the new animations gets called for the events.
    598                 assertTrue(l2.startIsCalled);
    599                 assertFalse(l2.cancelIsCalled);
    600                 assertTrue(l2.endIsCalled);
    601                 assertTrue(l3.startIsCalled);
    602                 assertTrue(l3.cancelIsCalled);
    603                 assertTrue(l3.endIsCalled);
    604 
    605                 // Check that the listener on the animation that was being clone receive the
    606                 // animation lifecycle events for the clones.
    607                 assertTrue(onlyContains(startedAnimators, s1, s2, s3));
    608                 assertTrue(onlyContains(canceledAnimators, s3));
    609                 assertTrue(onlyContains(endedAnimators, s1, s2, s3));
    610             }
    611         });
    612 
    613     }
    614 
    615     /**
    616      * Check that the animator list contains exactly the given animators and nothing else.
    617      */
    618     private boolean onlyContains(ArrayList<Animator> animators, AnimatorSet... sets) {
    619         if (sets.length != animators.size()) {
    620             return false;
    621         }
    622 
    623         for (int i = 0; i < sets.length; i++) {
    624             AnimatorSet set = sets[i];
    625             if (!animators.contains(set)) {
    626                 return false;
    627             }
    628         }
    629         return true;
    630 
    631     }
    632 
    633     // Create an AnimatorSet with all the animators running sequentially
    634     private AnimatorSet getSequentialSet() {
    635         AnimatorSet set = new AnimatorSet();
    636         set.playSequentially(a1, a2, a3, a4, a5);
    637         return set;
    638     }
    639 
    640     private ArrayList<Animator> getAnimatorList() {
    641         ArrayList<Animator> list = new ArrayList<>();
    642         list.add(a1);
    643         list.add(a2);
    644         list.add(a3);
    645         list.add(a4);
    646         list.add(a5);
    647         return list;
    648     }
    649 
    650 }
    651