17dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase/*
27dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * Copyright (C) 2011 The Android Open Source Project
37dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase *
47dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * Licensed under the Apache License, Version 2.0 (the "License");
57dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * you may not use this file except in compliance with the License.
67dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * You may obtain a copy of the License at
77dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase *
87dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase *      http://www.apache.org/licenses/LICENSE-2.0
97dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase *
107dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * Unless required by applicable law or agreed to in writing, software
117dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * distributed under the License is distributed on an "AS IS" BASIS,
127dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * See the License for the specific language governing permissions and
147dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * limitations under the License.
157dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase */
167dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haasepackage android.animation;
177dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
187dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haaseimport android.os.Handler;
197dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haaseimport android.test.ActivityInstrumentationTestCase2;
207dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haaseimport android.test.UiThreadTest;
217dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haaseimport android.test.suitebuilder.annotation.MediumTest;
227dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haaseimport android.test.suitebuilder.annotation.SmallTest;
237dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
24b8f574a165bf6ec5b316734b367ac274ded4809bChet Haaseimport java.util.concurrent.TimeUnit;
25b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
267dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase/**
277dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * Tests for the various lifecycle events of Animators. This abstract class is subclassed by
287dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * concrete implementations that provide the actual Animator objects being tested. All of the
297dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * testing mechanisms are in this class; the subclasses are only responsible for providing
307dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * the mAnimator object.
317dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase *
327dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * This test is more complicated than a typical synchronous test because much of the functionality
337dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * must happen on the UI thread. Some tests do this by using the UiThreadTest annotation to
347dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * automatically run the whole test on that thread. Other tests must run on the UI thread and also
357dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * wait for some later event to occur before ending. These tests use a combination of an
367dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * AbstractFuture mechanism and a delayed action to release that Future later.
377dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase */
387dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haasepublic abstract class EventsTest
397dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
407dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
418b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static final int ANIM_DURATION = 400;
428b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static final int ANIM_DELAY = 100;
438b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static final int ANIM_MID_DURATION = ANIM_DURATION / 2;
448b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static final int ANIM_MID_DELAY = ANIM_DELAY / 2;
458b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static final int FUTURE_RELEASE_DELAY = 50;
467dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
47b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    private boolean mStarted;  // tracks whether we've received the onAnimationStart() callback
488b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected boolean mRunning;  // tracks whether we've started the animator
497dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    private boolean mCanceled; // trackes whether we've canceled the animator
508b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected Animator.AnimatorListener mFutureListener; // mechanism for delaying the end of the test
518b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected FutureWaiter mFuture; // Mechanism for waiting for the UI test to complete
527dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    private Animator.AnimatorListener mListener; // Listener that handles/tests the events
537dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
547dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    protected Animator mAnimator; // The animator used in the tests. Must be set in subclass
557dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                                  // setup() method prior to calling the superclass setup()
567dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
577dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
58b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Cancels the given animator. Used to delay cancellation until some later time (after the
597dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * animator has started playing).
607dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
618b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static class Canceler implements Runnable {
627dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        Animator mAnim;
63b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        FutureWaiter mFuture;
64b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        public Canceler(Animator anim, FutureWaiter future) {
65b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            mAnim = anim;
66b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            mFuture = future;
67b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        }
68b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        @Override
69b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        public void run() {
70b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            try {
71b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mAnim.cancel();
72b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            } catch (junit.framework.AssertionFailedError e) {
73b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mFuture.setException(new RuntimeException(e));
74b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
75b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        }
76b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    };
77b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
78b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
798b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase     * Timeout length, based on when the animation should reasonably be complete.
808b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase     */
818b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected long getTimeout() {
828b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        return ANIM_DURATION + ANIM_DELAY + FUTURE_RELEASE_DELAY;
838b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    }
848b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase
858b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    /**
86b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Ends the given animator. Used to delay ending until some later time (after the
87b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * animator has started playing).
88b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
89b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    static class Ender implements Runnable {
90b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        Animator mAnim;
91b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        FutureWaiter mFuture;
92b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        public Ender(Animator anim, FutureWaiter future) {
937dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            mAnim = anim;
94b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            mFuture = future;
957dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        }
967dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        @Override
977dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        public void run() {
98b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            try {
99b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mAnim.end();
100b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            } catch (junit.framework.AssertionFailedError e) {
101b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mFuture.setException(new RuntimeException(e));
102b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
1037dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        }
1047dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    };
1057dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1067dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
1077dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Releases the given Future object when the listener's end() event is called. Specifically,
1087dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * it releases it after some further delay, to give the test time to do other things right
1097dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * after an animation ends.
1107dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
1118b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static class FutureReleaseListener extends AnimatorListenerAdapter {
1127dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        FutureWaiter mFuture;
1137dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1147dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        public FutureReleaseListener(FutureWaiter future) {
1157dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            mFuture = future;
1167dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        }
117b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
118b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        /**
119b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase         * Variant constructor that auto-releases the FutureWaiter after the specified timeout.
120b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase         * @param future
121b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase         * @param timeout
122b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase         */
123b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        public FutureReleaseListener(FutureWaiter future, long timeout) {
124b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            mFuture = future;
125b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            Handler handler = new Handler();
126b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            handler.postDelayed(new Runnable() {
127b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                @Override
128b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                public void run() {
129b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
130b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
131b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }, timeout);
132b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        }
133b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
1347dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        @Override
1357dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        public void onAnimationEnd(Animator animation) {
1367dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            Handler handler = new Handler();
1377dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            handler.postDelayed(new Runnable() {
1387dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                @Override
1397dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                public void run() {
1407dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.release();
1417dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                }
142b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }, FUTURE_RELEASE_DELAY);
1437dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        }
1447dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    };
1457dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1467dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public EventsTest() {
1477dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        super(BasicAnimatorActivity.class);
1487dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
1497dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1507dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
1517dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Sets up the fields used by each test. Subclasses must override this method to create
1527dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * the protected mAnimator object used in all tests. Overrides must create that animator
1537dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * and then call super.setup(), where further properties are set on that animator.
1547dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * @throws Exception
1557dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
1567dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @Override
1577dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void setUp() throws Exception {
1587dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        super.setUp();
1597dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1607dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        // mListener is the main testing mechanism of this file. The asserts of each test
1617dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        // are embedded in the listener callbacks that it implements.
1627dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mListener = new AnimatorListenerAdapter() {
1637dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
164b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void onAnimationStart(Animator animation) {
165b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                // This should only be called on an animation that has not yet been started
166b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                assertFalse(mStarted);
167b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                assertTrue(mRunning);
168b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mStarted = true;
169b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
170b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
171b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
1727dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void onAnimationCancel(Animator animation) {
1737dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                // This should only be called on an animation that has been started and not
1747dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                // yet canceled or ended
1757dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                assertFalse(mCanceled);
1767dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                assertTrue(mRunning);
177b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                assertTrue(mStarted);
1787dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                mCanceled = true;
1797dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
1807dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1817dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
1827dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void onAnimationEnd(Animator animation) {
1837dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                // This should only be called on an animation that has been started and not
1847dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                // yet ended
1857dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                assertTrue(mRunning);
186b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                assertTrue(mStarted);
1877dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                mRunning = false;
188b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mStarted = false;
1897dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                super.onAnimationEnd(animation);
1907dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
1917dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        };
1927dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1937dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.addListener(mListener);
1947dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.setDuration(ANIM_DURATION);
1957dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1967dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mFuture = new FutureWaiter();
1977dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1987dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mRunning = false;
1997dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mCanceled = false;
200b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mStarted = false;
2017dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
2027dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2037dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
2047dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Verify that calling cancel on an unstarted animator does nothing.
2057dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
2067dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @UiThreadTest
2077dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @SmallTest
2087dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testCancel() throws Exception {
2097dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.cancel();
2107dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
2117dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2127dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
213b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Verify that calling end on an unstarted animator does nothing.
214b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
215b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @UiThreadTest
216b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @SmallTest
217b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testEnd() throws Exception {
218b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.end();
219b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
220b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
221b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
2227dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Verify that calling cancel on a started animator does the right thing.
2237dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
2247dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @UiThreadTest
2257dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @SmallTest
2267dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testStartCancel() throws Exception {
227b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
228b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
229b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
230b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
231b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
232b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
233b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
234b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.cancel();
235b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
236b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
237b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
238b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
239b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
240b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
2418b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
2427dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
2437dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2447dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
245b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Verify that calling end on a started animator does the right thing.
2467dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
2477dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @UiThreadTest
2487dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @SmallTest
249b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testStartEnd() throws Exception {
250b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
251b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
252b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
253b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
254b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
255b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
256b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
257b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
258b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
259b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
260b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
261b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
262b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
263b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
2648b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
265b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
266b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
267b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
268b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testStartCancel, but with a startDelayed animator
269b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
270b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @SmallTest
2717dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testStartDelayedCancel() throws Exception {
272b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
2737dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.setStartDelay(ANIM_DELAY);
274b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
275b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
276b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
277b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
278b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
279b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
280b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.cancel();
281b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
282b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
283b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
284b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
285b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
286b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
2878b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
288b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
289b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
290b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
291b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testStartEnd, but with a startDelayed animator
292b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
293b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @SmallTest
294b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testStartDelayedEnd() throws Exception {
295b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
296b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.setStartDelay(ANIM_DELAY);
297b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
298b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
299b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
300b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
301b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
302b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
303b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
304b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
305b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
306b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
307b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
308b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
309b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
3108b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
3117dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
3127dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
3137dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
3147dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Verify that canceling an animator that is playing does the right thing.
3157dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
3167dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @MediumTest
3177dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testPlayingCancel() throws Exception {
3187dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
3197dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        getActivity().runOnUiThread(new Runnable() {
3207dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
3217dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void run() {
3227dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                try {
3237dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    Handler handler = new Handler();
3247dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.addListener(mFutureListener);
3257dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mRunning = true;
3267dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.start();
327b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
328b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
329b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
330b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
331b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
332b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
3338b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
334b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
335b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
336b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
337b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Verify that ending an animator that is playing does the right thing.
338b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
339b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
340b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testPlayingEnd() throws Exception {
341b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
342b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
343b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
344b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
345b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
346b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    Handler handler = new Handler();
347b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.addListener(mFutureListener);
348b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
349b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
350b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DURATION);
3517dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                } catch (junit.framework.AssertionFailedError e) {
3527dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.setException(new RuntimeException(e));
3537dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                }
3547dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
3557dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        });
3568b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
3577dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
3587dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
3597dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
3607dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Same as testPlayingCancel, but with a startDelayed animator
3617dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
3627dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @MediumTest
3637dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testPlayingDelayedCancel() throws Exception {
3647dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.setStartDelay(ANIM_DELAY);
3657dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
3667dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        getActivity().runOnUiThread(new Runnable() {
3677dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
3687dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void run() {
3697dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                try {
3707dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    Handler handler = new Handler();
3717dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.addListener(mFutureListener);
3727dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mRunning = true;
3737dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.start();
374b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
375b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
376b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
377b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
378b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
379b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
3808b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
381b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
382b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
383b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
384b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testPlayingEnd, but with a startDelayed animator
385b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
386b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
387b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testPlayingDelayedEnd() throws Exception {
388b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.setStartDelay(ANIM_DELAY);
389b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
390b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
391b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
392b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
393b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
394b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    Handler handler = new Handler();
395b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.addListener(mFutureListener);
396b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
397b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
398b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DURATION);
399b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
400b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
401b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
402b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
403b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
4048b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
405b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
406b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
407b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
408b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testPlayingDelayedCancel, but cancel during the startDelay period
409b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
410b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
411b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testPlayingDelayedCancelMidDelay() throws Exception {
412b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.setStartDelay(ANIM_DELAY);
413b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
414b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
415b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
416b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
417b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // Set the listener to automatically timeout after an uncanceled animation
418b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // would have finished. This tests to make sure that we're not calling
419b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // the listeners with cancel/end callbacks since they won't be called
420b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // with the start event.
4218b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase                    mFutureListener = new FutureReleaseListener(mFuture, getTimeout());
422b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    Handler handler = new Handler();
423b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
424b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
425b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DELAY);
4267dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                } catch (junit.framework.AssertionFailedError e) {
4277dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.setException(new RuntimeException(e));
4287dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                }
4297dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
4307dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        });
4318b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout() + 100,  TimeUnit.MILLISECONDS);
432b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
433b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
434b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
435b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testPlayingDelayedEnd, but end during the startDelay period
436b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
437b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
438b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testPlayingDelayedEndMidDelay() throws Exception {
439b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.setStartDelay(ANIM_DELAY);
440b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
441b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
442b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
443b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
444b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // Set the listener to automatically timeout after an uncanceled animation
445b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // would have finished. This tests to make sure that we're not calling
446b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // the listeners with cancel/end callbacks since they won't be called
447b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // with the start event.
4488b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase                    mFutureListener = new FutureReleaseListener(mFuture, getTimeout());
449b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    Handler handler = new Handler();
450b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
451b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
452b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DELAY);
453b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
454b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
455b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
456b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
457b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
4588b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout() + 100,  TimeUnit.MILLISECONDS);
4597dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
4607dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
4617dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
4627dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Verifies that canceling a started animation after it has already been canceled
4637dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * does nothing.
4647dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
4657dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @MediumTest
4667dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testStartDoubleCancel() throws Exception {
4677dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
4687dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        getActivity().runOnUiThread(new Runnable() {
4697dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
4707dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void run() {
4717dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                try {
4727dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mRunning = true;
4737dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.start();
4747dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.cancel();
4757dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.cancel();
4767dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.release();
4777dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                } catch (junit.framework.AssertionFailedError e) {
4787dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.setException(new RuntimeException(e));
4797dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                }
4807dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
4817dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        });
4828b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
483b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
484b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
485b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
486b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Verifies that ending a started animation after it has already been ended
487b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * does nothing.
488b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
489b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
490b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testStartDoubleEnd() throws Exception {
491b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
492b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
493b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
494b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
495b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
496b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
497b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
498b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
499b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
500b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
501b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
502b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
503b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
504b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
505b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
5068b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
5077dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
5087dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
5097dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
5107dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Same as testStartDoubleCancel, but with a startDelayed animator
5117dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
5127dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @MediumTest
5137dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testStartDelayedDoubleCancel() throws Exception {
5147dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.setStartDelay(ANIM_DELAY);
5157dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
5167dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        getActivity().runOnUiThread(new Runnable() {
5177dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
5187dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void run() {
5197dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                try {
5207dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mRunning = true;
5217dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.start();
5227dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.cancel();
5237dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.cancel();
5247dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.release();
5257dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                } catch (junit.framework.AssertionFailedError e) {
5267dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.setException(new RuntimeException(e));
5277dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                }
5287dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
5297dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        });
5308b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
531b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     }
5327dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
533b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
534b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testStartDoubleEnd, but with a startDelayed animator
535b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
536b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
537b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testStartDelayedDoubleEnd() throws Exception {
538b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.setStartDelay(ANIM_DELAY);
539b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
540b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
541b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
542b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
543b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
544b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
545b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
546b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
547b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
548b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
549b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
550b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
551b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
552b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
553b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
5548b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
555b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     }
5567dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
5577dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase}
558