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;
258aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haaseimport java.util.concurrent.TimeoutException;
26b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
277dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase/**
287dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * Tests for the various lifecycle events of Animators. This abstract class is subclassed by
297dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * concrete implementations that provide the actual Animator objects being tested. All of the
307dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * testing mechanisms are in this class; the subclasses are only responsible for providing
317dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * the mAnimator object.
327dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase *
337dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * This test is more complicated than a typical synchronous test because much of the functionality
347dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * must happen on the UI thread. Some tests do this by using the UiThreadTest annotation to
357dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * automatically run the whole test on that thread. Other tests must run on the UI thread and also
367dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * wait for some later event to occur before ending. These tests use a combination of an
377dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase * AbstractFuture mechanism and a delayed action to release that Future later.
387dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase */
397dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haasepublic abstract class EventsTest
407dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
417dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
428b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static final int ANIM_DURATION = 400;
438b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static final int ANIM_DELAY = 100;
448b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static final int ANIM_MID_DURATION = ANIM_DURATION / 2;
458b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static final int ANIM_MID_DELAY = ANIM_DELAY / 2;
468aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    protected static final int ANIM_PAUSE_DURATION = ANIM_DELAY;
478aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    protected static final int ANIM_PAUSE_DELAY = ANIM_DELAY / 2;
488b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static final int FUTURE_RELEASE_DELAY = 50;
498aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    protected static final int ANIM_FULL_DURATION_SLOP = 100;
507dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
51b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    private boolean mStarted;  // tracks whether we've received the onAnimationStart() callback
528b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected boolean mRunning;  // tracks whether we've started the animator
538aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    private boolean mCanceled; // tracks whether we've canceled the animator
548aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    protected Animator.AnimatorListener mFutureListener; // mechanism for delaying end of the test
558b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected FutureWaiter mFuture; // Mechanism for waiting for the UI test to complete
567dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    private Animator.AnimatorListener mListener; // Listener that handles/tests the events
577dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
587dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    protected Animator mAnimator; // The animator used in the tests. Must be set in subclass
597dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                                  // setup() method prior to calling the superclass setup()
607dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
617dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
62b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Cancels the given animator. Used to delay cancellation until some later time (after the
637dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * animator has started playing).
647dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
658b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static class Canceler implements Runnable {
667dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        Animator mAnim;
67b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        FutureWaiter mFuture;
68b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        public Canceler(Animator anim, FutureWaiter future) {
69b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            mAnim = anim;
70b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            mFuture = future;
71b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        }
72b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        @Override
73b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        public void run() {
74b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            try {
75b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mAnim.cancel();
76b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            } catch (junit.framework.AssertionFailedError e) {
77b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mFuture.setException(new RuntimeException(e));
78b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
79b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        }
80b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    };
81b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
82b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
838b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase     * Timeout length, based on when the animation should reasonably be complete.
848b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase     */
858b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected long getTimeout() {
868b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        return ANIM_DURATION + ANIM_DELAY + FUTURE_RELEASE_DELAY;
878b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    }
888b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase
898b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    /**
90b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Ends the given animator. Used to delay ending until some later time (after the
91b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * animator has started playing).
92b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
93b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    static class Ender implements Runnable {
94b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        Animator mAnim;
95b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        FutureWaiter mFuture;
96b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        public Ender(Animator anim, FutureWaiter future) {
977dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            mAnim = anim;
98b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            mFuture = future;
997dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        }
1007dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        @Override
1017dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        public void run() {
102b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            try {
103b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mAnim.end();
104b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            } catch (junit.framework.AssertionFailedError e) {
105b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mFuture.setException(new RuntimeException(e));
106b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
1077dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        }
1087dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    };
1097dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1107dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
1118aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     * Pauses the given animator. Used to delay pausing until some later time (after the
1128aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     * animator has started playing).
1138aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     */
1148aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    static class Pauser implements Runnable {
1158aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        Animator mAnim;
1168aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        FutureWaiter mFuture;
1178aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        public Pauser(Animator anim, FutureWaiter future) {
1188aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            mAnim = anim;
1198aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            mFuture = future;
1208aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        }
1218aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        @Override
1228aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        public void run() {
1238aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            try {
1248aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                mAnim.pause();
1258aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            } catch (junit.framework.AssertionFailedError e) {
1268aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                mFuture.setException(new RuntimeException(e));
1278aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            }
1288aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        }
1298aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    };
1308aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase
1318aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    /**
1328aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     * Resumes the given animator. Used to delay resuming until some later time (after the
1338aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     * animator has paused for some duration).
1348aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     */
1358aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    static class Resumer implements Runnable {
1368aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        Animator mAnim;
1378aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        FutureWaiter mFuture;
1388aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        public Resumer(Animator anim, FutureWaiter future) {
1398aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            mAnim = anim;
1408aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            mFuture = future;
1418aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        }
1428aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        @Override
1438aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        public void run() {
1448aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            try {
1458aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                mAnim.resume();
1468aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            } catch (junit.framework.AssertionFailedError e) {
1478aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                mFuture.setException(new RuntimeException(e));
1488aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            }
1498aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        }
1508aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    };
1518aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase
1528aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    /**
1537dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Releases the given Future object when the listener's end() event is called. Specifically,
1547dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * it releases it after some further delay, to give the test time to do other things right
1557dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * after an animation ends.
1567dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
1578b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase    protected static class FutureReleaseListener extends AnimatorListenerAdapter {
1587dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        FutureWaiter mFuture;
1597dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1607dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        public FutureReleaseListener(FutureWaiter future) {
1617dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            mFuture = future;
1627dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        }
163b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
164b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        /**
165b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase         * Variant constructor that auto-releases the FutureWaiter after the specified timeout.
166b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase         * @param future
167b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase         * @param timeout
168b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase         */
169b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        public FutureReleaseListener(FutureWaiter future, long timeout) {
170b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            mFuture = future;
171b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            Handler handler = new Handler();
172b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            handler.postDelayed(new Runnable() {
173b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                @Override
174b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                public void run() {
175b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
176b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
177b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }, timeout);
178b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        }
179b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
1807dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        @Override
1817dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        public void onAnimationEnd(Animator animation) {
1827dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            Handler handler = new Handler();
1837dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            handler.postDelayed(new Runnable() {
1847dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                @Override
1857dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                public void run() {
1867dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.release();
1877dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                }
188b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }, FUTURE_RELEASE_DELAY);
1897dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        }
1907dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    };
1917dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1927dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public EventsTest() {
1937dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        super(BasicAnimatorActivity.class);
1947dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
1957dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
1967dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
1977dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Sets up the fields used by each test. Subclasses must override this method to create
1987dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * the protected mAnimator object used in all tests. Overrides must create that animator
1997dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * and then call super.setup(), where further properties are set on that animator.
2007dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * @throws Exception
2017dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
2027dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @Override
2037dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void setUp() throws Exception {
2047dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        super.setUp();
2057dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2067dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        // mListener is the main testing mechanism of this file. The asserts of each test
2077dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        // are embedded in the listener callbacks that it implements.
2087dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mListener = new AnimatorListenerAdapter() {
2097dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
210b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void onAnimationStart(Animator animation) {
211b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                // This should only be called on an animation that has not yet been started
212b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                assertFalse(mStarted);
213b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                assertTrue(mRunning);
214b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mStarted = true;
215b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
216b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
217b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
2187dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void onAnimationCancel(Animator animation) {
2197dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                // This should only be called on an animation that has been started and not
2207dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                // yet canceled or ended
2217dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                assertFalse(mCanceled);
22217cf42cb85c22b50ecfa8d21efc992f99d20fc45Chet Haase                assertTrue(mRunning || mStarted);
2237dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                mCanceled = true;
2247dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
2257dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2267dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
2277dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void onAnimationEnd(Animator animation) {
2287dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                // This should only be called on an animation that has been started and not
2297dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                // yet ended
23017cf42cb85c22b50ecfa8d21efc992f99d20fc45Chet Haase                assertTrue(mRunning || mStarted);
2317dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                mRunning = false;
232b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                mStarted = false;
2337dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                super.onAnimationEnd(animation);
2347dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
2357dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        };
2367dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2377dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.addListener(mListener);
2387dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.setDuration(ANIM_DURATION);
2397dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2407dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mFuture = new FutureWaiter();
2417dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2427dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mRunning = false;
2437dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mCanceled = false;
244b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mStarted = false;
2457dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
2467dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2477dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
2487dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Verify that calling cancel on an unstarted animator does nothing.
2497dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
2507dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @UiThreadTest
2517dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @SmallTest
2527dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testCancel() throws Exception {
2537dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.cancel();
2547dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
2557dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2567dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
25717cf42cb85c22b50ecfa8d21efc992f99d20fc45Chet Haase     * Verify that calling end on an unstarted animator starts/ends an animator.
258b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
259b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @UiThreadTest
260b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @SmallTest
261b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testEnd() throws Exception {
26217cf42cb85c22b50ecfa8d21efc992f99d20fc45Chet Haase        mRunning = true; // end() implicitly starts an unstarted animator
263b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.end();
264b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
265b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
266b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
2677dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Verify that calling cancel on a started animator does the right thing.
2687dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
2697dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @UiThreadTest
2707dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @SmallTest
2717dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testStartCancel() throws Exception {
272b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
273b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
274b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
275b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
276b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
277b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
278b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
279b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.cancel();
280b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
281b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
282b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
283b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
284b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
285b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
2868b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
2877dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
2887dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
2897dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
290b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Verify that calling end on a started animator does the right thing.
2917dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
2927dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @UiThreadTest
2937dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @SmallTest
294b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testStartEnd() throws Exception {
295b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
296b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
297b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
298b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
299b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
300b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
301b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
302b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
303b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
304b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
305b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
306b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
307b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
308b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
3098b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
310b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
311b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
312b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
313b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testStartCancel, but with a startDelayed animator
314b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
315b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @SmallTest
3167dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testStartDelayedCancel() throws Exception {
317b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
3187dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.setStartDelay(ANIM_DELAY);
319b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
320b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
321b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
322b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
323b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
324b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
325b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.cancel();
326b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
327b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
328b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
329b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
330b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
331b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
3328b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
333b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
334b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
335b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
336b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testStartEnd, but with a startDelayed animator
337b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
338b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @SmallTest
339b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testStartDelayedEnd() throws Exception {
340b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
341b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.setStartDelay(ANIM_DELAY);
342b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
343b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
344b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
345b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
346b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
347b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
348b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
349b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
350b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
351b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
352b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
353b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
354b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
3558b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
3567dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
3577dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
3587dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
3597dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Verify that canceling an animator that is playing does the right thing.
3607dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
3617dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @MediumTest
3627dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testPlayingCancel() throws Exception {
3637dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
3647dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        getActivity().runOnUiThread(new Runnable() {
3657dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
3667dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void run() {
3677dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                try {
3687dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    Handler handler = new Handler();
3697dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.addListener(mFutureListener);
3707dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mRunning = true;
3717dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.start();
372b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
373b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
374b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
375b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
376b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
377b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
3788b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
379b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
380b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
381b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
382b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Verify that ending an animator that is playing does the right thing.
383b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
384b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
385b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testPlayingEnd() throws Exception {
386b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
387b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
388b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
389b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
390b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
391b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    Handler handler = new Handler();
392b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.addListener(mFutureListener);
393b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
394b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
395b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DURATION);
3967dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                } catch (junit.framework.AssertionFailedError e) {
3977dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.setException(new RuntimeException(e));
3987dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                }
3997dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
4007dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        });
4018b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(), TimeUnit.MILLISECONDS);
4027dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
4037dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
4047dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
4057dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Same as testPlayingCancel, but with a startDelayed animator
4067dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
4077dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @MediumTest
4087dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testPlayingDelayedCancel() throws Exception {
4097dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.setStartDelay(ANIM_DELAY);
4107dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
4117dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        getActivity().runOnUiThread(new Runnable() {
4127dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
4137dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void run() {
4147dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                try {
4157dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    Handler handler = new Handler();
4167dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.addListener(mFutureListener);
4177dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mRunning = true;
4187dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.start();
419b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DURATION);
420b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
421b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
422b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
423b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
424b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
4258b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
426b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
427b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
428b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
429b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testPlayingEnd, but with a startDelayed animator
430b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
431b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
432b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testPlayingDelayedEnd() throws Exception {
433b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.setStartDelay(ANIM_DELAY);
434b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
435b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
436b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
437b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
438b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
439b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    Handler handler = new Handler();
440b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.addListener(mFutureListener);
441b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
442b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
443b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DURATION);
444b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
445b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
446b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
447b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
448b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
4498b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
450b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
451b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
452b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
453b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testPlayingDelayedCancel, but cancel during the startDelay period
454b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
455b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
456b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testPlayingDelayedCancelMidDelay() throws Exception {
457b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.setStartDelay(ANIM_DELAY);
458b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
459b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
460b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
461b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
462b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // Set the listener to automatically timeout after an uncanceled animation
463b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // would have finished. This tests to make sure that we're not calling
464b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // the listeners with cancel/end callbacks since they won't be called
465b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // with the start event.
4668b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase                    mFutureListener = new FutureReleaseListener(mFuture, getTimeout());
467b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    Handler handler = new Handler();
468b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
469b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
470b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Canceler(mAnimator, mFuture), ANIM_MID_DELAY);
4717dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                } catch (junit.framework.AssertionFailedError e) {
4727dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.setException(new RuntimeException(e));
4737dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                }
4747dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
4757dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        });
4768b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout() + 100,  TimeUnit.MILLISECONDS);
477b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
478b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
479b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
480b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testPlayingDelayedEnd, but end during the startDelay period
481b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
482b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
483b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testPlayingDelayedEndMidDelay() throws Exception {
484b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.setStartDelay(ANIM_DELAY);
485b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
486b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
487b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
488b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
489b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // Set the listener to automatically timeout after an uncanceled animation
490b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // would have finished. This tests to make sure that we're not calling
491b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // the listeners with cancel/end callbacks since they won't be called
492b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    // with the start event.
4938b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase                    mFutureListener = new FutureReleaseListener(mFuture, getTimeout());
494b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    Handler handler = new Handler();
495b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
496b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
497b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    handler.postDelayed(new Ender(mAnimator, mFuture), ANIM_MID_DELAY);
498b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
499b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
500b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
501b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
502b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
5038b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout() + 100,  TimeUnit.MILLISECONDS);
5047dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
5057dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
5067dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
5077dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Verifies that canceling a started animation after it has already been canceled
5087dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * does nothing.
5097dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
5107dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @MediumTest
5117dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testStartDoubleCancel() throws Exception {
5127dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
5137dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        getActivity().runOnUiThread(new Runnable() {
5147dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
5157dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void run() {
5167dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                try {
5177dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mRunning = true;
5187dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.start();
5197dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.cancel();
5207dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.cancel();
5217dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.release();
5227dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                } catch (junit.framework.AssertionFailedError e) {
5237dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.setException(new RuntimeException(e));
5247dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                }
5257dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
5267dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        });
5278b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
528b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    }
529b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase
530b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
531b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Verifies that ending a started animation after it has already been ended
532b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * does nothing.
533b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
534b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
535b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testStartDoubleEnd() throws Exception {
536b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
537b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
538b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
539b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
540b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
541b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
542b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
543b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
54417cf42cb85c22b50ecfa8d21efc992f99d20fc45Chet Haase                    mRunning = true; // end() implicitly starts an unstarted animator
545b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
546b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
547b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
548b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
549b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
550b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
551b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
5528b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
5537dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    }
5547dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
5557dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    /**
5567dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     * Same as testStartDoubleCancel, but with a startDelayed animator
5577dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase     */
5587dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    @MediumTest
5597dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase    public void testStartDelayedDoubleCancel() throws Exception {
5607dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mAnimator.setStartDelay(ANIM_DELAY);
5617dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
5627dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        getActivity().runOnUiThread(new Runnable() {
5637dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            @Override
5647dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            public void run() {
5657dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                try {
5667dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mRunning = true;
5677dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.start();
5687dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.cancel();
5697dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mAnimator.cancel();
5707dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.release();
5717dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                } catch (junit.framework.AssertionFailedError e) {
5727dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                    mFuture.setException(new RuntimeException(e));
5737dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase                }
5747dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase            }
5757dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase        });
5768b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
577b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     }
5787dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
579b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    /**
580b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     * Same as testStartDoubleEnd, but with a startDelayed animator
581b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     */
582b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    @MediumTest
583b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase    public void testStartDelayedDoubleEnd() throws Exception {
584b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mAnimator.setStartDelay(ANIM_DELAY);
585b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        mFutureListener = new FutureReleaseListener(mFuture);
586b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        getActivity().runOnUiThread(new Runnable() {
587b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            @Override
588b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            public void run() {
589b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                try {
590b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mRunning = true;
591b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.start();
592b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
59317cf42cb85c22b50ecfa8d21efc992f99d20fc45Chet Haase                    mRunning = true; // end() implicitly starts an unstarted animator
594b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mAnimator.end();
595b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.release();
596b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                } catch (junit.framework.AssertionFailedError e) {
597b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                    mFuture.setException(new RuntimeException(e));
598b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase                }
599b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase            }
600b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase        });
6018b699792b677bd4dd8442b32641ac09d48fdd79cChet Haase        mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
602b8f574a165bf6ec5b316734b367ac274ded4809bChet Haase     }
6037dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase
6048aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    /**
6058aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     * Verify that pausing and resuming an animator ends within
6068aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     * the appropriate timeout duration.
6078aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     */
6088aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    @MediumTest
6098aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    public void testPauseResume() throws Exception {
6108aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
6118aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        getActivity().runOnUiThread(new Runnable() {
6128aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            @Override
6138aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            public void run() {
6148aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                try {
6158aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    Handler handler = new Handler();
6168aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mAnimator.addListener(mFutureListener);
6178aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mRunning = true;
6188aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mAnimator.start();
6198aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
6208aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    handler.postDelayed(new Resumer(mAnimator, mFuture),
6218aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                            ANIM_PAUSE_DELAY + ANIM_PAUSE_DURATION);
6228aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                } catch (junit.framework.AssertionFailedError e) {
6238aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mFuture.setException(new RuntimeException(e));
6248aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                }
6258aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            }
6268aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        });
6278aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        mFuture.get(getTimeout() + ANIM_PAUSE_DURATION, TimeUnit.MILLISECONDS);
6288aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    }
6298aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase
6308aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    /**
6318aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     * Verify that pausing and resuming a startDelayed animator ends within
6328aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     * the appropriate timeout duration.
6338aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     */
6348aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    @MediumTest
6358aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    public void testPauseResumeDelayed() throws Exception {
6368aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        mAnimator.setStartDelay(ANIM_DELAY);
6378aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
6388aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        getActivity().runOnUiThread(new Runnable() {
6398aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            @Override
6408aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            public void run() {
6418aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                try {
6428aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    Handler handler = new Handler();
6438aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mAnimator.addListener(mFutureListener);
6448aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mRunning = true;
6458aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mAnimator.start();
6468aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
6478aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    handler.postDelayed(new Resumer(mAnimator, mFuture),
6488aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                            ANIM_PAUSE_DELAY + ANIM_PAUSE_DURATION);
6498aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                } catch (junit.framework.AssertionFailedError e) {
6508aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mFuture.setException(new RuntimeException(e));
6518aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                }
6528aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            }
6538aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        });
6548aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        mFuture.get(getTimeout() + ANIM_PAUSE_DURATION + ANIM_FULL_DURATION_SLOP,
6558aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                TimeUnit.MILLISECONDS);
6568aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    }
6578aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase
6588aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    /**
6598aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     * Verify that pausing an animator without resuming it causes a timeout.
6608aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     */
6618aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    @MediumTest
6628aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    public void testPauseTimeout() throws Exception {
6638aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
6648aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        getActivity().runOnUiThread(new Runnable() {
6658aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            @Override
6668aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            public void run() {
6678aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                try {
6688aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    Handler handler = new Handler();
6698aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mAnimator.addListener(mFutureListener);
6708aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mRunning = true;
6718aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mAnimator.start();
6728aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
6738aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                } catch (junit.framework.AssertionFailedError e) {
6748aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mFuture.setException(new RuntimeException(e));
6758aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                }
6768aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            }
6778aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        });
6788aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        try {
6798aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            mFuture.get(getTimeout() + ANIM_PAUSE_DURATION + ANIM_FULL_DURATION_SLOP,
6808aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    TimeUnit.MILLISECONDS);
6818aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        } catch (TimeoutException e) {
6828aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            // Expected behavior, swallow the exception
6838aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        }
6848aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    }
6858aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase
6868aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    /**
6878aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     * Verify that pausing a startDelayed animator without resuming it causes a timeout.
6888aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase     */
6898aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    @MediumTest
6908aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    public void testPauseTimeoutDelayed() throws Exception {
6918aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        mAnimator.setStartDelay(ANIM_DELAY);
6928aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        mFutureListener = new FutureReleaseListener(mFuture);
6938aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        getActivity().runOnUiThread(new Runnable() {
6948aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            @Override
6958aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            public void run() {
6968aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                try {
6978aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    Handler handler = new Handler();
6988aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mAnimator.addListener(mFutureListener);
6998aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mRunning = true;
7008aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mAnimator.start();
7018aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
7028aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                } catch (junit.framework.AssertionFailedError e) {
7038aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    mFuture.setException(new RuntimeException(e));
7048aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                }
7058aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            }
7068aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        });
7078aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        try {
7088aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            mFuture.get(getTimeout() + ANIM_PAUSE_DURATION + ANIM_FULL_DURATION_SLOP,
7098aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase                    TimeUnit.MILLISECONDS);
7108aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        } catch (TimeoutException e) {
7118aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase            // Expected behavior, swallow the exception
7128aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase        }
7138aa1ffb0ed292891030992c65df4e5dc8bd37524Chet Haase    }
7147dfacdb1c820f955cb3cd6032ff5fbc2dd7d9df5Chet Haase}
715