| package android.animation; |
| |
| import com.android.frameworks.coretests.R; |
| |
| import android.test.ActivityInstrumentationTestCase2; |
| import android.test.UiThreadTest; |
| import android.test.suitebuilder.annotation.SmallTest; |
| import android.view.View; |
| |
| import java.util.ArrayList; |
| |
| public class AnimatorSetActivityTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> { |
| |
| private static final long POLL_INTERVAL = 100; // ms |
| private AnimatorSetActivity mActivity; |
| private ObjectAnimator a1,a2,a3; |
| private ValueAnimator a4,a5; |
| |
| public AnimatorSetActivityTest() { |
| super(AnimatorSetActivity.class); |
| } |
| |
| static class MyListener implements Animator.AnimatorListener { |
| boolean startIsCalled = false; |
| boolean endIsCalled = false; |
| boolean cancelIsCalled = false; |
| |
| @Override |
| public void onAnimationStart(Animator animation) { |
| startIsCalled = true; |
| } |
| |
| @Override |
| public void onAnimationEnd(Animator animation) { |
| endIsCalled = true; |
| } |
| |
| @Override |
| public void onAnimationCancel(Animator animation) { |
| cancelIsCalled = true; |
| } |
| |
| @Override |
| public void onAnimationRepeat(Animator animation) { |
| |
| } |
| } |
| |
| @Override |
| public void setUp() throws Exception { |
| super.setUp(); |
| mActivity = getActivity(); |
| |
| View square1 = mActivity.findViewById(R.id.square1); |
| View square2 = mActivity.findViewById(R.id.square2); |
| View square3 = mActivity.findViewById(R.id.square3); |
| a1 = ObjectAnimator.ofFloat(square1, View.TRANSLATION_X, 0f, 500f, 0f).setDuration(250); |
| a2 = ObjectAnimator.ofFloat(square2, View.ALPHA, 1f, 0f).setDuration(350); |
| a3 = ObjectAnimator.ofFloat(square3, View.ROTATION, 0, 90).setDuration(450); |
| a4 = ValueAnimator.ofInt(100, 200).setDuration(450); |
| a5 = ValueAnimator.ofFloat(10f, 5f).setDuration(850); |
| } |
| |
| @Override |
| public void tearDown() throws Exception { |
| mActivity = null; |
| a1 = null; |
| a2 = null; |
| a3 = null; |
| a4 = null; |
| a5 = null; |
| super.tearDown(); |
| } |
| |
| @SmallTest |
| public void testGetChildAnimations() { |
| AnimatorSet s1 = new AnimatorSet(); |
| s1.playTogether(a1, a2, a3); |
| ArrayList<Animator> children = s1.getChildAnimations(); |
| assertEquals(3, children.size()); |
| assertTrue(children.contains(a1)); |
| assertTrue(children.contains(a2)); |
| assertTrue(children.contains(a3)); |
| |
| AnimatorSet s2 = new AnimatorSet(); |
| s2.playSequentially(a1, a2, a3); |
| children = s2.getChildAnimations(); |
| assertEquals(3, children.size()); |
| assertTrue(children.contains(a1)); |
| assertTrue(children.contains(a2)); |
| assertTrue(children.contains(a3)); |
| |
| AnimatorSet s3 = new AnimatorSet(); |
| s3.play(a1).before(a2).after(s1).with(s2).after(a3); |
| ArrayList<Animator> s3Children = s3.getChildAnimations(); |
| assertNotNull(s3Children); |
| assertEquals(5, s3Children.size()); |
| assertTrue(s3Children.contains(a1)); |
| assertTrue(s3Children.contains(a2)); |
| assertTrue(s3Children.contains(a3)); |
| assertTrue(s3Children.contains(s1)); |
| assertTrue(s3Children.contains(s2)); |
| |
| AnimatorSet s4 = new AnimatorSet(); |
| s4.playSequentially(s3Children); |
| ArrayList<Animator> s4Children = s4.getChildAnimations(); |
| assertNotNull(s4Children); |
| assertEquals(s3Children.size(), s4Children.size()); |
| for (int i = 0; i < s3Children.size(); i++) { |
| Animator child = s3Children.get(i); |
| assertTrue(s4Children.contains(child)); |
| } |
| } |
| |
| @SmallTest |
| public void testTotalDuration() { |
| ArrayList<Animator> list = getAnimatorList(); |
| |
| // Run animations sequentially and test the total duration against sum of durations. |
| AnimatorSet s1 = new AnimatorSet(); |
| s1.playSequentially(list); |
| long totalDuration = 0; |
| for (int i = 0; i < list.size(); i++) { |
| Animator anim = list.get(i); |
| anim.setStartDelay(0); |
| totalDuration += list.get(i).getDuration(); |
| } |
| assertEquals(totalDuration, s1.getTotalDuration()); |
| |
| // Add delay to set, and test total duration |
| s1.setStartDelay(200); |
| assertEquals(totalDuration + 200, s1.getTotalDuration()); |
| |
| a1.setStartDelay(100); |
| assertEquals(totalDuration + 200 + 100, s1.getTotalDuration()); |
| |
| // Run animations simultaneously, test the total duration against the longest duration |
| AnimatorSet s2 = new AnimatorSet(); |
| s2.playTogether(list); |
| long maxDuration = 0; |
| for (int i = 0; i < list.size(); i++) { |
| long duration = list.get(i).getDuration(); |
| list.get(i).setStartDelay(100); |
| maxDuration = maxDuration > (duration + 100) ? maxDuration : (duration + 100); |
| } |
| assertEquals(maxDuration, s2.getTotalDuration()); |
| |
| // Form a cycle in the AnimatorSet and test the total duration |
| AnimatorSet s3 = new AnimatorSet(); |
| s3.play(a1).before(a2).after(a3); |
| s3.play(a1).after(a2).with(a4); |
| assertEquals(AnimatorSet.DURATION_INFINITE, s3.getTotalDuration()); |
| |
| // Put all the animators in a cycle |
| AnimatorSet s4 = new AnimatorSet(); |
| s4.play(a1).after(a2); |
| s4.play(a2).after(a1); |
| assertEquals(AnimatorSet.DURATION_INFINITE, s4.getTotalDuration()); |
| |
| // No cycle in the set, run a2, a1, a3 in sequence, and a2, a4, a5 together |
| AnimatorSet s5 = new AnimatorSet(); |
| s5.play(a1).after(a2).before(a3); |
| s5.play(a2).with(a4).with(a5); |
| long duration = a1.getDuration() + a1.getStartDelay() + a2.getDuration() + a2 |
| .getStartDelay() + a3.getDuration() + a3.getStartDelay(); |
| long a4Duration = a4.getDuration() + a4.getStartDelay(); |
| long a5Duration = a5.getDuration() + a5.getStartDelay(); |
| duration = Math.max(duration, a4Duration); |
| duration = Math.max(duration, a5Duration); |
| assertEquals(duration, s5.getTotalDuration()); |
| |
| // Change one animator to repeat infinitely and test the total time |
| a3.setRepeatCount(ValueAnimator.INFINITE); |
| assertEquals(AnimatorSet.DURATION_INFINITE, s5.getTotalDuration()); |
| |
| } |
| |
| @SmallTest |
| public void testGetDuration() { |
| AnimatorSet s = new AnimatorSet(); |
| assertTrue(s.getDuration() < 0); |
| s.play(a1).before(a2).before(a3).after(a4).after(a5); |
| assertTrue(s.getDuration() < 0); |
| |
| long duration = 200; |
| s.setDuration(duration); |
| assertEquals(duration, s.getDuration()); |
| |
| } |
| |
| @SmallTest |
| @UiThreadTest |
| public void testSetDuration() { |
| AnimatorSet s = getSequentialSet(); |
| assertTrue(s.getDuration() < 0); |
| |
| long duration = 300; |
| s.setDuration(duration); |
| assertEquals(duration, s.getDuration()); |
| |
| s.start(); |
| assertEquals(duration, s.getDuration()); |
| assertEquals(duration, a1.getDuration()); |
| assertEquals(duration, a2.getDuration()); |
| assertEquals(duration, a3.getDuration()); |
| assertEquals(duration, a4.getDuration()); |
| assertEquals(duration, a5.getDuration()); |
| } |
| |
| @SmallTest |
| public void testAddListener() throws InterruptedException { |
| // Verify that the listener is added to the list of listeners in the AnimatorSet |
| // and that newly added listener gets callback for lifecycle events of the animator |
| final AnimatorSet s = new AnimatorSet(); |
| s.play(a1).before(a2).before(a3).after(a4).after(a5); |
| final MyListener listener = new MyListener(); |
| if (s.getListeners() != null) { |
| assertFalse(s.getListeners().contains(listener)); |
| } |
| s.addListener(listener); |
| assertTrue(s.getListeners().contains(listener)); |
| |
| assertFalse(listener.startIsCalled); |
| assertFalse(listener.endIsCalled); |
| |
| try { |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| s.start(); |
| assertTrue(listener.startIsCalled); |
| assertFalse(listener.endIsCalled); |
| } |
| }); |
| } catch (Throwable throwable) { |
| throwable.printStackTrace(); |
| } |
| |
| Thread.sleep(s.getTotalDuration() + 200); |
| assertTrue(listener.startIsCalled); |
| assertTrue(listener.endIsCalled); |
| } |
| |
| @SmallTest |
| public void testRemoveListener() throws Throwable { |
| final AnimatorSet s = new AnimatorSet(); |
| s.playTogether(a1, a2, a3, a4); |
| MyListener listener = new MyListener(); |
| s.addListener(listener); |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| s.start(); |
| } |
| }); |
| |
| Thread.sleep(s.getTotalDuration() + 100); |
| assertTrue(listener.startIsCalled); |
| assertTrue(listener.endIsCalled); |
| |
| s.removeListener(listener); |
| if (s.getListeners() != null) { |
| assertFalse(s.getListeners().contains(listener)); |
| } |
| listener.startIsCalled = false; |
| listener.endIsCalled = false; |
| |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| s.start(); |
| } |
| }); |
| Thread.sleep(s.getTotalDuration() + 100); |
| assertFalse(listener.startIsCalled); |
| assertFalse(listener.endIsCalled); |
| } |
| |
| @SmallTest |
| public void testEnd() throws Throwable { |
| // End animator set |
| final AnimatorSet s = new AnimatorSet(); |
| s.play(a1).before(a2).after(a3).with(a4); |
| final MyListener listener = new MyListener(); |
| s.addListener(listener); |
| assertFalse(listener.endIsCalled); |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| s.start(); |
| assertTrue(s.isStarted()); |
| assertTrue(listener.startIsCalled); |
| assertFalse(listener.endIsCalled); |
| } |
| }); |
| |
| Thread.sleep(a2.getTotalDuration()); |
| |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| s.end(); |
| assertTrue(listener.startIsCalled); |
| assertTrue(listener.endIsCalled); |
| assertFalse(s.isRunning()); |
| assertFalse(s.isStarted()); |
| |
| assertFalse(a1.isStarted()); |
| assertFalse(a2.isStarted()); |
| assertFalse(a3.isStarted()); |
| assertFalse(a4.isStarted()); |
| } |
| }); |
| |
| } |
| |
| @SmallTest |
| public void testStart() throws Throwable { |
| final AnimatorSet s = new AnimatorSet(); |
| ArrayList<Animator> animators = getAnimatorList(); |
| |
| s.playSequentially(animators); |
| final MyListener l = new MyListener(); |
| s.addListener(l); |
| |
| ArrayList<MyListener> listeners = new ArrayList<>(animators.size()); |
| for (int i = 0; i < animators.size(); i++) { |
| MyListener listener = new MyListener(); |
| listeners.add(listener); |
| animators.get(i).addListener(listener); |
| } |
| |
| // Check the state before calling start() |
| assertFalse(l.startIsCalled); |
| assertFalse(l.endIsCalled); |
| for (int i = 0; i < listeners.size(); i++) { |
| assertFalse(l.startIsCalled); |
| assertFalse(l.endIsCalled); |
| } |
| |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| s.start(); |
| assertTrue(l.startIsCalled); |
| } |
| }); |
| |
| long timeout = s.getTotalDuration() * 2; |
| long wait = 0; |
| |
| while (wait < timeout) { |
| if (l.endIsCalled) { |
| break; |
| } |
| Thread.sleep(200); |
| wait += 200; |
| } |
| |
| // Now the set should finished |
| assertTrue(l.startIsCalled); |
| assertTrue(l.endIsCalled); |
| for (int i = 0; i < listeners.size(); i++) { |
| assertTrue(listeners.get(i).startIsCalled); |
| assertTrue(listeners.get(i).endIsCalled); |
| } |
| } |
| |
| @SmallTest |
| public void testCancel() throws Throwable { |
| // Check whether cancel would trigger onAnimationCanceled and cancel all the unfinished |
| // animations |
| final AnimatorSet s = new AnimatorSet(); |
| final ArrayList<Animator> animators = getAnimatorList(); |
| |
| s.playTogether(animators); |
| final MyListener l = new MyListener(); |
| s.addListener(l); |
| |
| final ArrayList<MyListener> listeners = new ArrayList<>(5); |
| for (int i = 0; i < animators.size(); i++) { |
| MyListener listener = new MyListener(); |
| listeners.add(listener); |
| animators.get(i).addListener(listener); |
| } |
| |
| // Check the state before calling start() |
| assertFalse(l.startIsCalled); |
| assertFalse(l.cancelIsCalled); |
| assertFalse(l.endIsCalled); |
| for (int i = 0; i < listeners.size(); i++) { |
| assertFalse(l.startIsCalled); |
| assertFalse(l.cancelIsCalled); |
| assertFalse(l.endIsCalled); |
| } |
| |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| s.start(); |
| } |
| }); |
| |
| Thread.sleep(a1.getTotalDuration()); |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| assertTrue(s.isStarted()); |
| ArrayList<Integer> runningAnimIds = new ArrayList<Integer>(); |
| for (int i = 0; i < animators.size(); i++) { |
| if (animators.get(i).isStarted()) { |
| runningAnimIds.add(i); |
| } |
| } |
| s.cancel(); |
| assertTrue(l.startIsCalled); |
| assertTrue(l.cancelIsCalled); |
| assertTrue(l.endIsCalled); |
| |
| for (int i = 0; i < listeners.size(); i++) { |
| assertTrue(listeners.get(i).startIsCalled); |
| if (runningAnimIds.contains(i)) { |
| assertTrue(listeners.get(i).cancelIsCalled); |
| } |
| assertTrue(listeners.get(i).endIsCalled); |
| } |
| } |
| }); |
| |
| } |
| |
| @SmallTest |
| public void testIsRunning() throws Throwable { |
| final AnimatorSet s = new AnimatorSet(); |
| final long startDelay = 500; |
| s.play(a1).before(a2).after(a3).with(a4); |
| s.play(a3).after(a5); |
| s.setStartDelay(startDelay); |
| MyListener listener = new MyListener(); |
| s.addListener(listener); |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| s.start(); |
| } |
| }); |
| |
| while (!listener.endIsCalled) { |
| boolean passedStartDelay = a1.isStarted() || a2.isStarted() || a3.isStarted() || |
| a4.isStarted() || a5.isStarted(); |
| assertEquals(passedStartDelay, s.isRunning()); |
| Thread.sleep(50); |
| } |
| assertFalse(s.isRunning()); |
| } |
| |
| @SmallTest |
| public void testPauseAndResume() throws Throwable { |
| final AnimatorSet set = getSequentialSet(); |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| // Calling pause before start should have no effect, per documentation |
| set.pause(); |
| set.start(); |
| assertFalse(set.isPaused()); |
| } |
| }); |
| |
| while (!a2.isStarted()) { |
| Thread.sleep(50); |
| } |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| assertFalse(set.isPaused()); |
| set.pause(); |
| assertTrue(set.isPaused()); |
| set.resume(); |
| assertFalse(set.isPaused()); |
| } |
| }); |
| } |
| |
| @SmallTest |
| public void testClone() throws Throwable { |
| // Set up an AnimatorSet and two clones, add one listener to each. When the clones animate, |
| // listeners of both the clone and the animator being cloned should receive animation |
| // lifecycle events. |
| final AnimatorSet s1 = getSequentialSet(); |
| |
| // Record animators that called their listeners for the corresponding event. |
| final ArrayList<Animator> startedAnimators = new ArrayList<>(); |
| final ArrayList<Animator> canceledAnimators = new ArrayList<>(); |
| final ArrayList<Animator> endedAnimators = new ArrayList<>(); |
| |
| final MyListener l1 = new MyListener() { |
| @Override |
| public void onAnimationStart(Animator anim) { |
| super.onAnimationStart(anim); |
| startedAnimators.add(anim); |
| } |
| |
| @Override |
| public void onAnimationCancel(Animator anim) { |
| super.onAnimationCancel(anim); |
| canceledAnimators.add(anim); |
| } |
| |
| @Override |
| public void onAnimationEnd(Animator anim) { |
| super.onAnimationEnd(anim); |
| endedAnimators.add(anim); |
| } |
| |
| }; |
| s1.addListener(l1); |
| |
| // Start the animation, and make the first clone during its run and the second clone once |
| // it ends. |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| assertFalse(l1.startIsCalled); |
| assertFalse(l1.endIsCalled); |
| |
| s1.start(); |
| } |
| }); |
| |
| // Make the first clone, during the animation's run. |
| assertTrue(s1.isStarted()); |
| final AnimatorSet s2 = s1.clone(); |
| final MyListener l2 = new MyListener(); |
| s2.addListener(l2); |
| |
| Thread.sleep(POLL_INTERVAL); |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| s1.end(); |
| } |
| }); |
| |
| Thread.sleep(POLL_INTERVAL); |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| assertTrue(l1.startIsCalled); |
| assertTrue(l1.endIsCalled); |
| } |
| }); |
| Thread.sleep(POLL_INTERVAL); |
| |
| // Make the second clone now. |
| final AnimatorSet s3 = s1.clone(); |
| final MyListener l3 = new MyListener(); |
| s3.addListener(l3); |
| |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| // Checking the fields before animations start. |
| assertFalse(l2.startIsCalled); |
| assertFalse(l2.cancelIsCalled); |
| assertFalse(l2.endIsCalled); |
| assertFalse(l3.startIsCalled); |
| assertFalse(l3.cancelIsCalled); |
| assertFalse(l3.endIsCalled); |
| |
| s2.start(); |
| s3.start(); |
| } |
| }); |
| |
| Thread.sleep(POLL_INTERVAL); |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| // Make sure the listeners receive the callbacks |
| // At this time only onAnimationStart() should be called. |
| assertTrue(l2.startIsCalled); |
| assertTrue(l3.startIsCalled); |
| assertFalse(l2.endIsCalled); |
| assertFalse(l3.endIsCalled); |
| assertFalse(l2.cancelIsCalled); |
| assertFalse(l3.cancelIsCalled); |
| |
| s2.end(); |
| s3.cancel(); |
| } |
| }); |
| Thread.sleep(POLL_INTERVAL); |
| runTestOnUiThread(new Runnable() { |
| @Override |
| public void run() { |
| // Check that the new listeners for the new animations gets called for the events. |
| assertTrue(l2.startIsCalled); |
| assertFalse(l2.cancelIsCalled); |
| assertTrue(l2.endIsCalled); |
| assertTrue(l3.startIsCalled); |
| assertTrue(l3.cancelIsCalled); |
| assertTrue(l3.endIsCalled); |
| |
| // Check that the listener on the animation that was being clone receive the |
| // animation lifecycle events for the clones. |
| assertTrue(onlyContains(startedAnimators, s1, s2, s3)); |
| assertTrue(onlyContains(canceledAnimators, s3)); |
| assertTrue(onlyContains(endedAnimators, s1, s2, s3)); |
| } |
| }); |
| |
| } |
| |
| /** |
| * Check that the animator list contains exactly the given animators and nothing else. |
| */ |
| private boolean onlyContains(ArrayList<Animator> animators, AnimatorSet... sets) { |
| if (sets.length != animators.size()) { |
| return false; |
| } |
| |
| for (int i = 0; i < sets.length; i++) { |
| AnimatorSet set = sets[i]; |
| if (!animators.contains(set)) { |
| return false; |
| } |
| } |
| return true; |
| |
| } |
| |
| // Create an AnimatorSet with all the animators running sequentially |
| private AnimatorSet getSequentialSet() { |
| AnimatorSet set = new AnimatorSet(); |
| set.playSequentially(a1, a2, a3, a4, a5); |
| return set; |
| } |
| |
| private ArrayList<Animator> getAnimatorList() { |
| ArrayList<Animator> list = new ArrayList<>(); |
| list.add(a1); |
| list.add(a2); |
| list.add(a3); |
| list.add(a4); |
| list.add(a5); |
| return list; |
| } |
| |
| } |