/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view.animation.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

import android.app.Activity;
import android.app.Instrumentation;
import android.content.res.XmlResourceParser;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Xml;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.Transformation;
import android.view.cts.R;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;

import com.android.compatibility.common.util.PollingCheck;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Test {@link Animation}.
 */
@MediumTest
@RunWith(AndroidJUnit4.class)
public class AnimationTest {
    private static final float COMPARISON_DELTA = 0.001f;

    /** It is defined in R.anim.accelerate_alpha */
    private static final int ACCELERATE_ALPHA_DURATION = 1000;

    /** It is defined in R.anim.decelerate_alpha */
    private static final int DECELERATE_ALPHA_DURATION = 2000;

    private static final int CANCELATION_TIMEOUT = 5000;

    private Instrumentation mInstrumentation;
    private Activity mActivity;

    @Rule
    public ActivityTestRule<AnimationTestCtsActivity> mActivityRule =
            new ActivityTestRule<>(AnimationTestCtsActivity.class);

    @Before
    public void setup() {
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        mActivity = mActivityRule.getActivity();
    }

    @Test
    public void testConstructor() {
        XmlResourceParser parser = mActivity.getResources().getAnimation(R.anim.alpha);
        AttributeSet attrs = Xml.asAttributeSet(parser);
        new Animation(mActivity, attrs) {
        };

        new Animation() {
        };
    }

    @Test
    public void testAccessInterpolator() {
        // check default interpolator
        MyAnimation myAnimation = new MyAnimation();
        Interpolator interpolator = myAnimation.getInterpolator();
        assertTrue(interpolator instanceof AccelerateDecelerateInterpolator); // issue 1561186.

        myAnimation.ensureInterpolator();
        assertSame(interpolator, myAnimation.getInterpolator());

        myAnimation.setInterpolator(null);
        assertNull(myAnimation.getInterpolator());
        myAnimation.ensureInterpolator();
        interpolator = myAnimation.getInterpolator();
        assertTrue(interpolator instanceof AccelerateDecelerateInterpolator);

        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.decelerate_alpha);
        interpolator = animation.getInterpolator();
        assertNotNull(interpolator);
        assertTrue(interpolator instanceof DecelerateInterpolator);

        animation = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
        interpolator = animation.getInterpolator();
        assertNotNull(interpolator);
        assertTrue(interpolator instanceof AccelerateInterpolator);
    }

    @Test
    public void testDefaultFill() {
        Animation animation = new Animation() {
        };
        assertTrue(animation.getFillBefore());
        assertFalse(animation.getFillAfter());
    }

    @Test
    public void testAccessFill() throws Throwable {
        View animWindow = mActivity.findViewById(R.id.anim_window);
        // XML file of R.anim.accelerate_alpha
        // <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        //     android:interpolator="@android:anim/accelerate_interpolator"
        //     android:fromAlpha="0.1"
        //     android:toAlpha="0.9"
        //     android:duration="1000" />
        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
        assertFalse(animation.isFillEnabled());
        assertTrue(animation.getFillBefore());
        assertFalse(animation.getFillAfter());

        AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow,
                animation);

        // fillBefore and fillAfter are ignored when fillEnabled is false
        Transformation transformation = new Transformation();
        // check alpha before start
        animation.getTransformation(animation.getStartTime() - 1, transformation);
        float alpha = transformation.getAlpha();
        assertEquals(0.1f, alpha, COMPARISON_DELTA);  // issue 1698355

        transformation = new Transformation();
        // check alpha after the end
        animation.getTransformation(animation.getStartTime() + animation.getDuration() + 1,
                transformation);
        alpha = transformation.getAlpha();
        assertEquals(0.9f, alpha, COMPARISON_DELTA);  // issue 1698355

        animation.setFillEnabled(true);
        animation.setFillBefore(false);
        assertTrue(animation.isFillEnabled());
        assertFalse(animation.getFillBefore());
        assertFalse(animation.getFillAfter());
        AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow,
                animation);

        transformation = new Transformation();
        animation.getTransformation(animation.getStartTime() - 1, transformation);
        alpha = transformation.getAlpha();
        assertEquals(1.0f, alpha, COMPARISON_DELTA);

        transformation = new Transformation();
        animation.getTransformation(animation.getStartTime() + animation.getDuration() + 1,
                transformation);
        alpha = transformation.getAlpha();
        assertEquals(1.0f, alpha, COMPARISON_DELTA);

        animation.setFillBefore(true);
        animation.setFillAfter(true);
        assertTrue(animation.isFillEnabled());
        assertTrue(animation.getFillBefore());
        assertTrue(animation.getFillAfter());
        AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow,
                animation);

        transformation = new Transformation();
        animation.getTransformation(animation.getStartTime() - 1, transformation);
        alpha = transformation.getAlpha();
        assertEquals(0.1f, alpha, COMPARISON_DELTA);

        transformation = new Transformation();
        animation.getTransformation(animation.getStartTime() + animation.getDuration() + 1,
                transformation);
        alpha = transformation.getAlpha();
        assertEquals(0.9f, alpha, COMPARISON_DELTA);
    }

    @Test
    public void testComputeDurationHint() {
        // start offset is 0, duration is 2000, repeat count is 0.
        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.decelerate_alpha);
        assertEquals(2000, animation.computeDurationHint());

        // start offset is 0, duration is 2000, repeat count is 2.
        animation.setRepeatCount(2);
        assertEquals(6000, animation.computeDurationHint());

        // start offset is 800, duration is 2000, repeat count is 2.
        animation.setStartOffset(800);
        assertEquals(8400, animation.computeDurationHint());
    }

    @Test
    public void testRepeatAnimation() throws Throwable {
        // check default repeatMode
        Animation animation = new Animation() {
        };
        assertEquals(Animation.RESTART, animation.getRepeatMode());

        final View animWindow = mActivity.findViewById(R.id.anim_window);

        // XML file of R.anim.decelerate_alpha
        // <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        //      android:interpolator="@android:anim/decelerate_interpolator"
        //      android:fromAlpha="0.0"
        //      android:toAlpha="1.0"
        //      android:duration="2000" />
        final Animation anim = AnimationUtils.loadAnimation(mActivity, R.anim.decelerate_alpha);
        assertEquals(Animation.RESTART, animation.getRepeatMode());
        long duration = anim.getDuration();
        assertEquals(DECELERATE_ALPHA_DURATION, duration);
        // repeat count is 0, repeat mode does not make sense.
        AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, anim);

        // test repeat mode REVERSE
        anim.setRepeatCount(1);
        anim.setRepeatMode(Animation.REVERSE);
        // we have to PollingCheck the animation status on test thread,
        // it cannot be done on UI thread, so we invoke runOnUiThread method here.
        mActivityRule.runOnUiThread(() -> animWindow.startAnimation(anim));

        // check whether animation has started
        PollingCheck.waitFor(anim::hasStarted);

        Transformation transformation = new Transformation();
        long startTime = anim.getStartTime();
        anim.getTransformation(startTime, transformation);
        float alpha1 = transformation.getAlpha();
        assertEquals(0.0f, alpha1, COMPARISON_DELTA);

        anim.getTransformation(startTime + 1000, transformation);
        float alpha2 = transformation.getAlpha();

        anim.getTransformation(startTime + 2000, transformation);
        float alpha3 = transformation.getAlpha();
        assertEquals(1.0f, alpha3, COMPARISON_DELTA);

        // wait for animation has ended.
        // timeout is larger than duration, in case the system is sluggish
        PollingCheck.waitFor(duration * 2 + 1000, anim::hasEnded);

        // get start time of reversing.
        startTime = anim.getStartTime();
        anim.getTransformation(startTime + 3000, transformation);
        float alpha4 = transformation.getAlpha();

        anim.getTransformation(startTime + 4000, transformation);
        float alpha5 = transformation.getAlpha();
        assertEquals(0.0f, alpha5, COMPARISON_DELTA);

        // check decelerating delta alpha when reverse. alpha should change form 0.0f to 1.0f
        // and then from 1.0f to 0.0f
        float delta1 = alpha2 - alpha1;
        float delta2 = alpha3 - alpha2;
        // the animation plays backward
        float delta3 = alpha3 - alpha4;
        float delta4 = alpha4 - alpha5;
        assertTrue(delta1 > delta2);
        assertTrue(delta3 > delta4);

        // test repeat mode RESTART
        anim.setRepeatMode(Animation.RESTART);
        // we have to PollingCheck the animation status on test thread,
        // it cannot be done on UI thread, so we invoke runOnUiThread method here.
        mActivityRule.runOnUiThread(() -> animWindow.startAnimation(anim));

        // check whether animation has started
        PollingCheck.waitFor(anim::hasStarted);

        transformation = new Transformation();
        startTime = anim.getStartTime();
        anim.getTransformation(startTime, transformation);
        alpha1 = transformation.getAlpha();
        assertEquals(0.0f, alpha1, COMPARISON_DELTA);

        anim.getTransformation(startTime + 1000, transformation);
        alpha2 = transformation.getAlpha();

        anim.getTransformation(startTime + 2000, transformation);
        alpha3 = transformation.getAlpha();
        assertEquals(1.0f, alpha3, COMPARISON_DELTA);

        // wait for animation has ended.
        // timeout is larger than duration, in case the system is sluggish
        PollingCheck.waitFor(duration * 2 + 1000, anim::hasEnded);

        // get start time of restarting.
        startTime = anim.getStartTime();
        anim.getTransformation(startTime + 3000, transformation);
        alpha4 = transformation.getAlpha();

        anim.getTransformation(startTime + 4000, transformation);
        alpha5 = transformation.getAlpha();
        assertEquals(1.0f, alpha5, COMPARISON_DELTA);

        // check decelerating delta alpha when restart. alpha should change form 0.0f to 1.0f
        // and then from 0.0f to 1.0f again
        delta1 = alpha2 - 0.0f;
        delta2 = alpha3 - alpha2;
        // the animation restarts from the beginning
        delta3 = alpha4 - 0.0f;
        delta4 = alpha5 - alpha4;
        assertTrue(delta1 > delta2);
        assertTrue(delta3 > delta4);
    }

    @Test
    public void testAccessStartOffset() throws Throwable {
        final long startOffset = 800;
        // check default startOffset
        Animation animation = new Animation() {
        };
        assertEquals(0, animation.getStartOffset());

        View animWindow = mActivity.findViewById(R.id.anim_window);
        // XML file of R.anim.accelerate_alpha
        // <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        //      android:interpolator="@android:anim/accelerate_interpolator"
        //      android:fromAlpha="0.1"
        //      android:toAlpha="0.9"
        //      android:duration="1000" />
        animation = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
        animation.setStartOffset(startOffset);
        assertEquals(startOffset, animation.getStartOffset());

        AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow,
                animation, ACCELERATE_ALPHA_DURATION + startOffset);

        Transformation transformation = new Transformation();
        long startTime = animation.getStartTime();
        animation.getTransformation(startTime, transformation);
        float alpha1 = transformation.getAlpha();
        assertEquals(0.1f, alpha1, COMPARISON_DELTA);

        animation.getTransformation(startTime + 400, transformation);
        float alpha2 = transformation.getAlpha();
        // alpha is 0.1f during start offset
        assertEquals(0.1f, alpha2, COMPARISON_DELTA);

        animation.getTransformation(startTime + startOffset, transformation);
        float alpha3 = transformation.getAlpha();
        // alpha is 0.1f during start offset
        assertEquals(0.1f, alpha3, COMPARISON_DELTA);

        animation.getTransformation(startTime + startOffset + 1, transformation);
        float alpha4 = transformation.getAlpha();
        // alpha is lager than 0.1f after start offset
        assertTrue(alpha4 > 0.1f);
    }

    @Test
    public void testRunAccelerateAlpha() throws Throwable {
        // check default startTime
        Animation animation = new Animation() {
        };
        assertEquals(Animation.START_ON_FIRST_FRAME, animation.getStartTime());

        long currentTime = AnimationUtils.currentAnimationTimeMillis();
        animation.setStartTime(currentTime);
        assertEquals(currentTime, animation.getStartTime());

        View animWindow = mActivity.findViewById(R.id.anim_window);

        // XML file of R.anim.accelerate_alpha
        // <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        //      android:interpolator="@android:anim/accelerate_interpolator"
        //      android:fromAlpha="0.1"
        //      android:toAlpha="0.9"
        //      android:duration="1000" />
        Animation anim = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
        assertEquals(Animation.START_ON_FIRST_FRAME, anim.getStartTime());
        assertFalse(anim.hasStarted());
        AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, anim);
    }

    @Test
    public void testGetTransformation() throws Throwable {
        final View animWindow = mActivity.findViewById(R.id.anim_window);

        // XML file of R.anim.accelerate_alpha
        // <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        //      android:interpolator="@android:anim/accelerate_interpolator"
        //      android:fromAlpha="0.1"
        //      android:toAlpha="0.9"
        //      android:duration="1000" />
        final Animation anim = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
        assertFalse(anim.hasStarted());

        // we have to PollingCheck the animation status on test thread,
        // it cannot be done on UI thread, so we invoke runOnUiThread method here.
        mActivityRule.runOnUiThread(() -> animWindow.startAnimation(anim));

        // check whether animation has started
        PollingCheck.waitFor(anim::hasStarted);

        // check transformation objects that is provided by the
        // caller and will be filled in by the animation.
        Transformation transformation = new Transformation();
        long startTime = anim.getStartTime();
        assertTrue(anim.getTransformation(startTime, transformation));
        float alpha1 = transformation.getAlpha();
        assertEquals(0.1f, alpha1, COMPARISON_DELTA);

        assertTrue(anim.getTransformation(startTime + 250, transformation));
        float alpha2 = transformation.getAlpha();

        assertTrue(anim.getTransformation(startTime + 500, transformation));
        float alpha3 = transformation.getAlpha();

        assertTrue(anim.getTransformation(startTime + 750, transformation));
        float alpha4 = transformation.getAlpha();

        // wait for animation has ended.
        // timeout is larger than duration, in case the system is sluggish
        PollingCheck.waitFor(2000, anim::hasEnded);

        assertFalse(anim.getTransformation(startTime + 1000, transformation));
        float alpha5 = transformation.getAlpha();
        assertEquals(0.9f, alpha5, COMPARISON_DELTA);

        // check decelerating delta alpha
        float delta1 = alpha2 - alpha1;
        float delta2 = alpha3 - alpha2;
        float delta3 = alpha4 - alpha3;
        float delta4 = alpha5 - alpha4;
        assertTrue(delta1 < delta2);
        assertTrue(delta2 < delta3);
        assertTrue(delta3 < delta4);
    }

    @Test
    public void testAccessZAdjustment() {
        // check default zAdjustment
        Animation animation = new Animation() {
        };
        assertEquals(Animation.ZORDER_NORMAL, animation.getZAdjustment());

        animation = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
        assertEquals(Animation.ZORDER_NORMAL, animation.getZAdjustment());

        animation.setZAdjustment(Animation.ZORDER_TOP);
        assertEquals(Animation.ZORDER_TOP, animation.getZAdjustment());

        animation.setZAdjustment(Animation.ZORDER_BOTTOM);
        assertEquals(Animation.ZORDER_BOTTOM, animation.getZAdjustment());
    }

    @Test
    public void testInitialize() {
        Animation animation = new Animation() {
        };

        assertFalse(animation.isInitialized());
        animation.initialize(320, 480, 320, 480);
        assertTrue(animation.isInitialized());
    }

    @Test
    public void testResolveSize() {
        MyAnimation myAnimation = new MyAnimation();

        assertEquals(1.0f, myAnimation.resolveSize(Animation.ABSOLUTE, 1.0f, 0, 0),
                COMPARISON_DELTA);
        assertEquals(2.0f, myAnimation.resolveSize(Animation.ABSOLUTE, 2.0f, 0, 0),
                COMPARISON_DELTA);

        assertEquals(6.0f, myAnimation.resolveSize(Animation.RELATIVE_TO_SELF, 3.0f, 2, 0),
                COMPARISON_DELTA);
        assertEquals(9.0f, myAnimation.resolveSize(Animation.RELATIVE_TO_SELF, 3.0f, 3, 0),
                COMPARISON_DELTA);

        assertEquals(18.0f, myAnimation.resolveSize(Animation.RELATIVE_TO_PARENT, 3.0f, 0, 6),
                COMPARISON_DELTA);
        assertEquals(12.0f, myAnimation.resolveSize(Animation.RELATIVE_TO_PARENT, 3.0f, 0, 4),
                COMPARISON_DELTA);

        int unknownType = 7;
        assertEquals(8.0f, myAnimation.resolveSize(unknownType, 8.0f, 3, 4), COMPARISON_DELTA);
        assertEquals(10.0f, myAnimation.resolveSize(unknownType, 10.0f, 3, 4), COMPARISON_DELTA);
    }

    @Test
    public void testRestrictDuration() {
        Animation animation = new Animation() {
        };

        animation.setStartOffset(1000);
        animation.restrictDuration(500);
        assertEquals(500, animation.getStartOffset());
        assertEquals(0, animation.getDuration());
        assertEquals(0, animation.getRepeatCount());

        animation.setStartOffset(1000);
        animation.setDuration(1000);
        animation.restrictDuration(1500);
        assertEquals(500, animation.getDuration());

        animation.setStartOffset(1000);
        animation.setDuration(1000);
        animation.setRepeatCount(3);
        animation.restrictDuration(4500);
        assertEquals(1, animation.getRepeatCount());
    }

    @Test
    public void testScaleCurrentDuration() {
        Animation animation = new Animation() {
        };

        animation.setDuration(10);
        animation.scaleCurrentDuration(0);
        assertEquals(0, animation.getDuration());

        animation.setDuration(10);
        animation.scaleCurrentDuration(2);
        assertEquals(20, animation.getDuration());

        animation.setDuration(10);
        animation.scaleCurrentDuration(-1);
        assertEquals(-10, animation.getDuration());
    }

    @LargeTest
    @Test
    public void testSetAnimationListener() throws Throwable {
        final View animWindow = mActivity.findViewById(R.id.anim_window);

        // XML file of R.anim.accelerate_alpha
        // <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        //      android:interpolator="@android:anim/accelerate_interpolator"
        //      android:fromAlpha="0.1"
        //      android:toAlpha="0.9"
        //      android:duration="1000" />
        final Animation anim = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
        final AnimationListener listener = mock(AnimationListener.class);
        anim.setAnimationListener(listener);
        verifyZeroInteractions(listener);

        AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, anim);
        verify(listener, times(1)).onAnimationStart(anim);
        verify(listener, times(1)).onAnimationEnd(anim);
        verify(listener, never()).onAnimationRepeat(anim);

        reset(listener);
        anim.setRepeatCount(2);
        anim.setRepeatMode(Animation.REVERSE);

        AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, anim,
                3000);
        verify(listener, times(1)).onAnimationStart(anim);
        verify(listener, times(2)).onAnimationRepeat(anim);
        verify(listener, times(1)).onAnimationEnd(anim);

        reset(listener);
        // onAnimationEnd will not be invoked and animation should not end
        anim.setRepeatCount(Animation.INFINITE);

        mActivityRule.runOnUiThread(() -> animWindow.startAnimation(anim));
        // Verify that our animation doesn't call listener's onAnimationEnd even after a long
        // period of time. We just sleep and then verify what's happened with the listener.
        SystemClock.sleep(4 * ACCELERATE_ALPHA_DURATION);

        verify(listener, times(1)).onAnimationStart(anim);
        verify(listener, atLeastOnce()).onAnimationRepeat(anim);
        verify(listener, never()).onAnimationEnd(anim);
    }

    @Test
    public void testStart() {
        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
        animation.setStartTime(0);

        animation.start();
        assertEquals(Animation.START_ON_FIRST_FRAME, animation.getStartTime());
    }

    @Test
    public void testStartNow() {
        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.accelerate_alpha);
        animation.setStartTime(0);

        long currentTime = AnimationUtils.currentAnimationTimeMillis();
        animation.startNow();
        assertEquals(currentTime, animation.getStartTime(), 100);
    }

    @Test
    public void testWillChangeBounds() {
        Animation animation = new Animation() {
        };

        assertTrue(animation.willChangeBounds());
    }

    @Test
    public void testWillChangeTransformationMatrix() {
        Animation animation = new Animation() {
        };

        assertTrue(animation.willChangeTransformationMatrix());
    }

    @Test
    public void testClone() throws CloneNotSupportedException {
        MyAnimation myAnimation = new MyAnimation();
        myAnimation.setDuration(3000);
        myAnimation.setFillAfter(true);
        myAnimation.setFillBefore(false);
        myAnimation.setFillEnabled(true);
        myAnimation.setStartTime(1000);
        myAnimation.setRepeatCount(10);
        myAnimation.setRepeatMode(Animation.REVERSE);

        Animation cloneAnimation = myAnimation.clone();
        assertNotSame(myAnimation, cloneAnimation);
        assertEquals(myAnimation.getDuration(), cloneAnimation.getDuration());
        assertEquals(myAnimation.getFillAfter(), cloneAnimation.getFillAfter());
        assertEquals(myAnimation.getFillBefore(), cloneAnimation.getFillBefore());
        assertEquals(myAnimation.isFillEnabled(), cloneAnimation.isFillEnabled());
        assertEquals(myAnimation.getStartOffset(), cloneAnimation.getStartOffset());
        assertEquals(myAnimation.getRepeatCount(), cloneAnimation.getRepeatCount());
        assertEquals(myAnimation.getRepeatMode(), cloneAnimation.getRepeatMode());
    }

    @Test
    public void testCancelImmediately() throws Throwable {
        MyAnimation anim = new MyAnimation();
        final CountDownLatch latch1 = new CountDownLatch(1);
        runCanceledAnimation(anim, latch1, false, false);
        assertTrue(latch1.await(CANCELATION_TIMEOUT, TimeUnit.MILLISECONDS));
        assertFalse(anim.isStillAnimating());
    }

    @Test
    public void testRepeatingCancelImmediately() throws Throwable {
        MyAnimation anim = new MyAnimation();
        final CountDownLatch latch2 = new CountDownLatch(1);
        runCanceledAnimation(anim, latch2, true, false);
        assertTrue(latch2.await(CANCELATION_TIMEOUT, TimeUnit.MILLISECONDS));
        assertFalse(anim.isStillAnimating());
    }

    @Test
    public void testCancelDelayed() throws Throwable {
        MyAnimation anim = new MyAnimation();
        final CountDownLatch latch3 = new CountDownLatch(1);
        runCanceledAnimation(anim, latch3, false, true);
        assertTrue(latch3.await(CANCELATION_TIMEOUT, TimeUnit.MILLISECONDS));
        assertFalse(anim.isStillAnimating());
    }

    @Test
    public void testRepeatingCancelDelayed() throws Throwable {
        MyAnimation anim = new MyAnimation();
        final CountDownLatch latch4 = new CountDownLatch(1);
        runCanceledAnimation(anim, latch4, true, true);
        assertTrue(latch4.await(CANCELATION_TIMEOUT, TimeUnit.MILLISECONDS));
        assertFalse(anim.isStillAnimating());
    }

    private void runCanceledAnimation(final MyAnimation anim, final CountDownLatch latch,
            final boolean repeating, final boolean delayed) throws Throwable {
        // The idea behind this test is that canceling an Animation should result in
        // it ending, which means not having its getTransformation() method called
        // anymore. The trick is that cancel() will still allow one more frame to run,
        // so we have to insert some delay between when we cancel and when we can check
        // whether it is still animating.
        final View view = mActivity.findViewById(R.id.anim_window);
        mActivityRule.runOnUiThread(() -> {
            anim.setDuration(delayed ? 150 : 100);
            if (repeating) {
                anim.setRepeatCount(Animation.INFINITE);
            }
            view.startAnimation(anim);
            if (!delayed) {
                anim.cancel();
            } else {
                view.postDelayed(anim::cancel, 50);
            }
            view.postDelayed(() -> {
                anim.setStillAnimating(false);
                view.postDelayed(latch::countDown, 50);
            }, delayed ? 100 : 50);
        });
    }

    private class MyAnimation extends Animation {
        boolean mStillAnimating = false;

        @Override
        protected void ensureInterpolator() {
            super.ensureInterpolator();
        }

        @Override
        protected float resolveSize(int type, float value, int size, int parentSize) {
            return super.resolveSize(type, value, size, parentSize);
        }

        @Override
        protected Animation clone() throws CloneNotSupportedException {
            return super.clone();
        }

        public void setStillAnimating(boolean value) {
            mStillAnimating = value;
        }

        public boolean isStillAnimating() {
            return mStillAnimating;
        }

        @Override
        public boolean getTransformation(long currentTime, Transformation outTransformation) {
            mStillAnimating = true;
            return super.getTransformation(currentTime, outTransformation);
        }
    }
}
