diff --git a/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java b/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java index c66fd1548facb..922bc59d71d19 100644 --- a/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java +++ b/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java @@ -11,6 +11,7 @@ import java.util.ArrayList; public class AnimatorSetActivityTest extends ActivityInstrumentationTestCase2 { + private static final long POLL_INTERVAL = 100; // ms private AnimatorSetActivity mActivity; private ObjectAnimator a1,a2,a3; private ValueAnimator a4,a5; @@ -481,6 +482,154 @@ public class AnimatorSetActivityTest extends ActivityInstrumentationTestCase2 startedAnimators = new ArrayList<>(); + final ArrayList canceledAnimators = new ArrayList<>(); + final ArrayList 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 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();