/*
 * Copyright (C) 2015 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.transition.cts;

import static com.android.compatibility.common.util.CtsMockitoUtils.within;

import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.animation.Animator;
import android.graphics.Rect;
import android.os.SystemClock;
import android.transition.ArcMotion;
import android.transition.AutoTransition;
import android.transition.ChangeBounds;
import android.transition.CircularPropagation;
import android.transition.PathMotion;
import android.transition.Scene;
import android.transition.Transition;
import android.transition.Transition.EpicenterCallback;
import android.transition.Transition.TransitionListener;
import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
import android.transition.TransitionPropagation;
import android.transition.TransitionValues;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;

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

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

@MediumTest
@RunWith(AndroidJUnit4.class)
public class TransitionTest extends BaseTransitionTest {
    @Test
    public void testAddListener() throws Throwable {
        startTransition(R.layout.scene1);
        waitForStart();

        final Transition.TransitionListener listener2 = mock(Transition.TransitionListener.class);

        mActivityRule.runOnUiThread(() -> {
            AutoTransition autoTransition = new AutoTransition();
            autoTransition.setDuration(100);
            autoTransition.addListener(listener2);
            Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity);
            TransitionManager.go(scene, autoTransition);
        });

        waitForStart(listener2);

        verify(mListener, times(1)).onTransitionPause(any());
        verify(mListener, times(1)).onTransitionResume(any());
        verify(mListener, never()).onTransitionCancel(any());
        verify(mListener, never()).onTransitionEnd(any());
        verify(mListener, times(1)).onTransitionStart(any());

        verify(listener2, never()).onTransitionPause(any());
        verify(listener2, never()).onTransitionResume(any());
        verify(listener2, never()).onTransitionCancel(any());
        verify(listener2, never()).onTransitionEnd(any());
        verify(listener2, times(1)).onTransitionStart(any());
        endTransition();
    }

    @Test
    public void testRemoveListener() throws Throwable {
        startTransition(R.layout.scene1);
        waitForStart();

        mActivityRule.runOnUiThread(() -> mTransition.removeListener(mListener));

        SystemClock.sleep(250);
        verify(mListener, never()).onTransitionEnd(any());
    }

    @Test
    public void testAddTargetId() throws Throwable {
        enterScene(R.layout.scene4);
        assertNotNull(mTransition.getTargetIds());
        assertTrue(mTransition.getTargetIds().isEmpty());
        mTransition.addTarget(R.id.holder);
        mTransition.addTarget(R.id.hello);
        assertEquals(2, mTransition.getTargetIds().size());
        startTransition(R.layout.scene1);
        assertEquals(1, mTargets.size());
        assertEquals(R.id.hello, mTargets.get(0).getId());
        endTransition();
    }

    @Test
    public void testRemoveTargetId() throws Throwable {
        enterScene(R.layout.scene4);
        mTransition.addTarget(R.id.holder);
        mTransition.addTarget(R.id.hello);
        mTransition.addTarget(R.id.redSquare);
        assertEquals(3, mTransition.getTargetIds().size());
        mTransition.removeTarget(0); // nothing should happen
        mTransition.removeTarget(R.id.redSquare);
        assertEquals(2, mTransition.getTargetIds().size());

        startTransition(R.layout.scene1);
        assertEquals(1, mTargets.size());
        assertEquals(R.id.hello, mTargets.get(0).getId());
        endTransition();
    }

    @Test
    public void testAddTargetClass() throws Throwable {
        enterScene(R.layout.scene4);
        assertNull(mTransition.getTargetTypes());
        mTransition.addTarget(RelativeLayout.class);
        mTransition.addTarget(TextView.class);
        assertEquals(2, mTransition.getTargetTypes().size());
        startTransition(R.layout.scene1);
        assertEquals(1, mTargets.size());
        assertTrue(mTargets.get(0) instanceof TextView);
        endTransition();
    }

    @Test
    public void testRemoveTargetClass() throws Throwable {
        enterScene(R.layout.scene4);
        mTransition.addTarget(TextView.class);
        mTransition.addTarget(View.class);
        mTransition.addTarget(RelativeLayout.class);
        assertEquals(3, mTransition.getTargetTypes().size());
        mTransition.removeTarget(ImageView.class); // should do nothing
        mTransition.removeTarget(View.class);
        assertEquals(2, mTransition.getTargetTypes().size());
        startTransition(R.layout.scene1);
        assertEquals(1, mTargets.size());
        assertTrue(mTargets.get(0) instanceof TextView);
        endTransition();
    }

    @Test
    public void testAddTargetView() throws Throwable {
        enterScene(R.layout.scene1);

        final View[] target = new View[1];
        mActivityRule.runOnUiThread(() -> target[0] = mActivity.findViewById(R.id.hello));
        mTransition.addTarget(target[0]);
        assertEquals(1, mTransition.getTargets().size());
        mActivityRule.runOnUiThread(() -> {
            TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
            target[0].setVisibility(View.GONE);
        });
        waitForStart();
        assertEquals(1, mTargets.size());
        assertEquals(target[0], mTargets.get(0));
        endTransition();
    }

    @Test
    public void testRemoveTargetView() throws Throwable {
        enterScene(R.layout.scene1);

        final View[] target = new View[3];
        mActivityRule.runOnUiThread(() -> {
            target[0] = mActivity.findViewById(R.id.hello);
            target[1] = mActivity.findViewById(R.id.greenSquare);
            target[2] = mActivity.findViewById(R.id.redSquare);
        });

        mTransition.addTarget(target[0]);
        mTransition.addTarget(target[1]);
        assertEquals(2, mTransition.getTargets().size());
        mTransition.removeTarget(target[2]); // should do nothing
        mTransition.removeTarget(target[1]);
        assertEquals(1, mTransition.getTargets().size());
        mActivityRule.runOnUiThread(() -> {
            TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
            target[0].setVisibility(View.GONE);
        });
        waitForStart();
        assertEquals(1, mTargets.size());
        assertEquals(target[0], mTargets.get(0));
        endTransition();
    }

    @Test
    public void testAddTargetName() throws Throwable {
        enterScene(R.layout.scene4);
        assertNull(mTransition.getTargetNames());
        mTransition.addTarget("red");
        mTransition.addTarget("holder");
        assertEquals(2, mTransition.getTargetNames().size());
        assertEquals(0, mTargets.size());
        startTransition(R.layout.scene2);
        assertEquals(1, mTargets.size());
        assertEquals(R.id.redSquare, mTargets.get(0).getId());
        endTransition();
    }

    @Test
    public void testRemoveTargetName() throws Throwable {
        enterScene(R.layout.scene4);
        mTransition.addTarget("holder");
        mTransition.addTarget("red");
        mTransition.addTarget("green");
        assertEquals(3, mTransition.getTargetNames().size());
        mTransition.removeTarget("purple"); // should do nothing
        // try to force a different String instance
        String greenName = new StringBuilder("gre").append("en").toString();
        mTransition.removeTarget(greenName);
        assertEquals(2, mTransition.getTargetNames().size());
        startTransition(R.layout.scene1);
        assertEquals(1, mTargets.size());
        assertEquals(R.id.redSquare, mTargets.get(0).getId());
        endTransition();
    }

    @Test
    public void testIsTransitionRequired() throws Throwable {
        enterScene(R.layout.scene1);
        mTransition = new NotRequiredTransition();
        assertFalse(mTransition.isTransitionRequired(null, null));
        resetListener();
        mActivityRule.runOnUiThread(() -> {
            TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
            mActivity.findViewById(R.id.hello).setVisibility(View.GONE);
        });
        waitForStart();
        assertEquals(0, mTargets.size());
        endTransition();
    }

    @Test
    public void testCanRemoveViews() throws Throwable {
        enterScene(R.layout.scene1);
        assertFalse(mTransition.canRemoveViews());
        mTransition.addListener(new TransitionListener() {
            @Override
            public void onTransitionStart(Transition transition) {
                assertTrue(transition.canRemoveViews());
            }

            @Override
            public void onTransitionEnd(Transition transition) {
            }

            @Override
            public void onTransitionCancel(Transition transition) {
            }

            @Override
            public void onTransitionPause(Transition transition) {
            }

            @Override
            public void onTransitionResume(Transition transition) {
            }
        });
        startTransition(R.layout.scene2);
    }

    @Test
    public void testExcludeChildrenView() throws Throwable {
        View layout1 = loadLayout(R.layout.scene1);
        Scene scene1 = loadScene(layout1);
        enterScene(scene1);
        View holder1 = layout1.findViewById(R.id.holder);
        mTransition.excludeChildren(holder1, true);
        View layout2 = loadLayout(R.layout.scene2);
        Scene scene2 = loadScene(layout2);
        View holder2 = layout2.findViewById(R.id.holder);
        mTransition.excludeChildren(holder2, true);
        startTransition(scene2);
        // Should already be ended, since no children are transitioning
        verify(mListener, times(1)).onTransitionEnd(any());

        mTransition.excludeChildren(holder1, false); // remove it
        mTransition.excludeChildren(holder2, false); // remove it
        resetListener();
        startTransition(scene1);
        verify(mListener, never()).onTransitionEnd(any()); // it is running as expected
        endTransition();
    }

    @Test
    public void testExcludeChildrenId() throws Throwable {
        enterScene(R.layout.scene1);
        mTransition.excludeChildren(R.id.holder, true);
        startTransition(R.layout.scene2);
        // Should already be ended, since no children are transitioning
        verify(mListener, times(1)).onTransitionEnd(any());

        resetListener();
        mTransition.excludeChildren(R.id.holder, false); // remove it
        startTransition(R.layout.scene1);
        verify(mListener, never()).onTransitionEnd(any()); // it is running as expected
        endTransition();
    }

    @Test
    public void testExcludeChildrenClass() throws Throwable {
        enterScene(R.layout.scene1);
        mTransition.excludeChildren(RelativeLayout.class, true);
        startTransition(R.layout.scene2);
        // Should already be ended, since no children are transitioning
        verify(mListener, times(1)).onTransitionEnd(any());

        resetListener();
        mTransition.excludeChildren(RelativeLayout.class, false); // remove it
        startTransition(R.layout.scene1);
        verify(mListener, never()).onTransitionEnd(any()); // it is running as expected
        endTransition();
    }

    @Test
    public void testExcludeTargetView() throws Throwable {
        View layout1 = loadLayout(R.layout.scene1);
        Scene scene1 = loadScene(layout1);
        enterScene(R.layout.scene1);
        View redSquare1 = layout1.findViewById(R.id.redSquare);
        mTransition.excludeTarget(redSquare1, true);
        startTransition(R.layout.scene7);
        waitForEnd(600);

        mTransition.excludeTarget(redSquare1, false); // remove it
        resetListener();
        startTransition(scene1);
        verify(mListener, never()).onTransitionEnd(any()); // it is running as expected
        endTransition();
    }

    @Test
    public void testExcludeTargetId() throws Throwable {
        enterScene(R.layout.scene1);
        mTransition.excludeTarget(R.id.redSquare, true);
        startTransition(R.layout.scene7);
        // Should already be ended, since no children are transitioning
        verify(mListener, times(1)).onTransitionEnd(any());

        resetListener();
        mTransition.excludeTarget(R.id.redSquare, false); // remove it
        startTransition(R.layout.scene1);
        verify(mListener, never()).onTransitionEnd(any()); // it is running as expected
        endTransition();
    }

    @Test
    public void testExcludeTargetClass() throws Throwable {
        enterScene(R.layout.scene1);
        mTransition.excludeTarget(TextView.class, true);
        startTransition(R.layout.scene3);
        // Should already be ended, since no children are transitioning
        verify(mListener, times(1)).onTransitionEnd(any());

        resetListener();
        mTransition.excludeTarget(TextView.class, false); // remove it
        startTransition(R.layout.scene1);
        verify(mListener, never()).onTransitionEnd(any()); // it is running as expected
        endTransition();
    }

    @Test
    public void testExcludeTargetName() throws Throwable {
        enterScene(R.layout.scene1);
        mTransition.excludeTarget("hello", true);
        startTransition(R.layout.scene3);
        // Should already be ended, since no children are transitioning
        verify(mListener, times(1)).onTransitionEnd(any());

        resetListener();
        mTransition.excludeTarget("hello", false); // remove it
        startTransition(R.layout.scene1);
        verify(mListener, never()).onTransitionEnd(any()); // it is running as expected
        endTransition();
    }

    @Test
    public void testDuration() throws Throwable {
        assertEquals(-1, mTransition.getDuration());
        enterScene(R.layout.scene1);
        mTransition.setDuration(500);
        assertEquals(500, mTransition.getDuration());
        DurationListener durationListener = new DurationListener();
        mTransition.addListener(durationListener);
        startTransition(R.layout.scene3);
        waitForEnd(800);
        assertThat(durationListener.getDuration(),
                allOf(greaterThanOrEqualTo(500L), lessThan(900L)));
    }

    @Test
    public void testEpicenter() throws Throwable {
        assertNull(mTransition.getEpicenter());
        EpicenterCallback callback = new EpicenterCallback() {
            @Override
            public Rect onGetEpicenter(Transition transition) {
                return new Rect(0, 0, 1, 1);
            }
        };
        mTransition.setEpicenterCallback(callback);
        assertSame(callback, mTransition.getEpicenterCallback());
        assertEquals(new Rect(0, 0, 1, 1), mTransition.getEpicenter());
    }

    @Test
    public void testInterpolator() throws Throwable {
        enterScene(R.layout.scene1);
        View redSquare = mActivity.findViewById(R.id.redSquare);
        CaptureAnimatorTransition transition = new CaptureAnimatorTransition();
        assertNull(transition.getInterpolator());
        AccelerateInterpolator interpolator = new AccelerateInterpolator();
        transition.setInterpolator(interpolator);
        assertSame(interpolator, transition.getInterpolator());
        mTransition = transition;
        resetListener();
        startTransition(R.layout.scene4);
        assertFalse(transition.animators.isEmpty());
        Animator animator = transition.animators.get(redSquare);
        Animator.AnimatorListener listener = transition.listeners.get(redSquare);
        verify(listener, within(100)).onAnimationStart(any(), eq(false));
        assertSame(interpolator, animator.getInterpolator());
        endTransition();
    }

    @Test
    public void testName() throws Throwable {
        assertEquals("android.transition.cts.BaseTransitionTest$TestTransition",
                mTransition.getName());
    }

    @Test
    public void testPathMotion() throws Throwable {
        PathMotion pathMotion = new ArcMotion();
        mTransition.setPathMotion(pathMotion);
        assertEquals(pathMotion, mTransition.getPathMotion());
    }

    @Test
    public void testPropagation() throws Throwable {
        enterScene(R.layout.scene1);
        CaptureAnimatorTransition transition = new CaptureAnimatorTransition();
        mTransition = transition;
        TransitionPropagation yPropagation = new TransitionPropagation() {
            private static final String TOP = "top value";
            private final String[] PROPERTIES = {TOP};

            @Override
            public long getStartDelay(ViewGroup viewGroup, Transition transition,
                    TransitionValues startValues, TransitionValues endValues) {
                int startTop = startValues == null ? 0 : (Integer) startValues.values.get(TOP);
                int endTop = endValues == null ? 0 : (Integer) endValues.values.get(TOP);
                return (startTop == 0) ? endTop : startTop;
            }

            @Override
            public void captureValues(TransitionValues transitionValues) {
                if (transitionValues.view != null) {
                    transitionValues.values.put(TOP, transitionValues.view.getTop());
                }
            }

            @Override
            public String[] getPropagationProperties() {
                return PROPERTIES;
            }
        };
        mTransition.setPropagation(yPropagation);
        resetListener();

        View redSquare = mActivity.findViewById(R.id.redSquare);
        View greenSquare = mActivity.findViewById(R.id.greenSquare);
        int diffTop = greenSquare.getTop() - redSquare.getTop();
        startTransition(R.layout.scene4);
        Animator redSquareAnimator = transition.animators.get(redSquare);
        Animator greenSquareAnimator = transition.animators.get(greenSquare);
        Animator.AnimatorListener listener = transition.listeners.get(redSquare);
        verify(listener, within(100)).onAnimationStart(any(), eq(false));
        assertEquals(0, redSquareAnimator.getStartDelay());
        assertEquals(diffTop, greenSquareAnimator.getStartDelay());
        endTransition();
    }

    @Test
    public void testSetPropagation() throws Throwable {
        Transition transition = new ChangeBounds();
        assertNull(transition.getPropagation());
        TransitionPropagation propagation = new CircularPropagation();
        transition.setPropagation(propagation);
        assertSame(propagation, transition.getPropagation());
    }

    @Test
    public void testStartDelay() throws Throwable {
        CaptureAnimatorTransition transition = new CaptureAnimatorTransition();
        mTransition = transition;
        resetListener();
        enterScene(R.layout.scene1);
        View redSquare = mActivity.findViewById(R.id.redSquare);

        assertEquals(-1, mTransition.getStartDelay());
        mTransition.setStartDelay(200);
        assertEquals(200, mTransition.getStartDelay());

        startTransition(R.layout.scene4);

        Animator animator = transition.animators.get(redSquare);
        assertFalse(animator.isRunning());
        Animator.AnimatorListener listener = transition.listeners.get(redSquare);
        verify(listener, within(250)).onAnimationStart(any(), eq(false));
        endTransition();
    }

    @Test
    public void testTransitionValues() throws Throwable {
        enterScene(R.layout.scene1);
        CheckTransitionValuesTransition transition = new CheckTransitionValuesTransition();
        mTransition = transition;
        mTransition.setDuration(10);
        resetListener();
        startTransition(R.layout.scene2);
        assertTrue(transition.onDisappearCalled.await(500, TimeUnit.MILLISECONDS));
        assertTrue(transition.onAppearCalled.await(500, TimeUnit.MILLISECONDS));
        // The transition has all the asserts in it, so we can just end it now.
        endTransition();
    }

    @Test
    public void testMatchOrder() throws Throwable {
        mTransition = new ChangeBounds();
        resetListener();
        enterScene(R.layout.scene1);
        startTransition(R.layout.scene8);

        // scene 8 swaps the ids, but not the names. No transition should happen.
        waitForEnd(1000);

        // now change the match order to prefer the id
        mTransition.setMatchOrder(new int[] {Transition.MATCH_ID, Transition.MATCH_NAME});

        resetListener();
        startTransition(R.layout.scene1);
        verify(mListener, never()).onTransitionEnd(any()); // it is running as expected
        waitForEnd(1000);
    }

    @Test
    public void testGetTransitionProperties() throws Throwable {
        enterScene(R.layout.scene1);
        // Make the transition make changes to properties in getTransitionProperties.
        TransitionPropertiesTransition transition = new TransitionPropertiesTransition(false);
        mTransition = transition;
        resetListener();
        startTransition(R.layout.scene2);
        assertTrue(transition.latch.await(500, TimeUnit.MILLISECONDS));
        endTransition();

        // Now make the transition only make changes to unimportant properties.
        transition = new TransitionPropertiesTransition(true);
        mTransition = transition;
        resetListener();
        startTransition(R.layout.scene1);
        verify(mListener, within(500)).onTransitionEnd(any());
        // createAnimator shouldn't have been called.
        assertEquals(1, transition.latch.getCount());

        assertNotNull(transition.getTransitionProperties());
        assertEquals(1, transition.getTransitionProperties().length);
    }

    @Test
    public void testGoWithNullParameter() throws Throwable {
        final View layout1 = loadLayout(R.layout.scene1);
        final Scene scene1 = loadScene(layout1);

        final View layout3 = loadLayout(R.layout.scene3);
        final Scene scene3 = loadScene(layout3);

        enterScene(scene1);

        mActivityRule.runOnUiThread(() -> {
            // scene1
            assertSame(layout1, mActivity.findViewById(R.id.holder));
            assertNotNull(mActivity.findViewById(R.id.hello));

            TransitionManager.go(scene3, null);
            // now at scene3
            assertSame(layout3, mActivity.findViewById(R.id.holder));
            assertNull(mActivity.findViewById(R.id.hello));

            TransitionManager.go(scene1, null);

            // now at scene1
            assertSame(layout1, mActivity.findViewById(R.id.holder));
            assertNotNull(mActivity.findViewById(R.id.hello));
        });
    }

    private class NotRequiredTransition extends TestTransition {
        @Override
        public boolean isTransitionRequired(TransitionValues startValues,
                TransitionValues newValues) {
            return false;
        }
    }

    private class CaptureAnimatorTransition extends TestTransition {
        public HashMap<View, Animator> animators = new HashMap<>();
        public HashMap<View, Animator.AnimatorListener> listeners = new HashMap<>();

        @Override
        public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
                TransitionValues endValues) {
            return setupAnimator(super.onAppear(sceneRoot, view, startValues, endValues),
                    endValues.view);
        }

        @Override
        public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
                TransitionValues endValues) {
            return setupAnimator(super.onDisappear(sceneRoot, view, startValues, endValues),
                    startValues.view);
        }

        private Animator setupAnimator(Animator animator, View view) {
            animators.put(view, animator);
            Animator.AnimatorListener listener = mock(Animator.AnimatorListener.class);
            animator.addListener(listener);
            listeners.put(view, listener);
            return animator;
        }
    }

    private class CheckTransitionValuesTransition extends TestTransition {
        public CountDownLatch onAppearCalled = new CountDownLatch(1);
        public CountDownLatch onDisappearCalled = new CountDownLatch(1);
        @Override
        public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
                TransitionValues endValues) {
            onAppearCalled.countDown();
            assertNull(getTransitionValues(endValues.view, true));
            assertEquals(endValues, getTransitionValues(endValues.view, false));
            return super.onAppear(sceneRoot, view, startValues, endValues);
        }

        @Override
        public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
                TransitionValues endValues) {
            onDisappearCalled.countDown();
            assertNull(getTransitionValues(startValues.view, false));
            assertEquals(startValues, getTransitionValues(startValues.view, true));
            return super.onDisappear(sceneRoot, view, startValues, endValues);
        }
    }

    private static class TransitionPropertiesTransition extends Transition {
        private static final String SIDE_PROP = "prop1";
        private static final String IMPORTANT_PROP = "prop2";
        private static final String[] PROPERTIES = {
                IMPORTANT_PROP
        };

        private boolean mOnlyUnimportant;
        public CountDownLatch latch = new CountDownLatch(1);

        public TransitionPropertiesTransition(boolean onlyUnimportant) {
            mOnlyUnimportant = onlyUnimportant;
        }

        @Override
        public String[] getTransitionProperties() {
            return PROPERTIES;
        }

        @Override
        public void captureStartValues(TransitionValues transitionValues) {
            transitionValues.values.put(SIDE_PROP, 1);
            transitionValues.values.put(IMPORTANT_PROP, 1);
        }

        @Override
        public void captureEndValues(TransitionValues transitionValues) {
            transitionValues.values.put(SIDE_PROP, 2);
            int val = mOnlyUnimportant ? 1 : 2;
            transitionValues.values.put(IMPORTANT_PROP, val);
        }

        @Override
        public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
                TransitionValues endValues) {
            if (startValues != null && endValues != null) {
                latch.countDown();
            }

            return null;
        }
    }

    private static class DurationListener extends TransitionListenerAdapter {

        private long mUptimeMillisStart = -1;
        private long mDuration = -1;

        @Override
        public void onTransitionStart(Transition transition) {
            mUptimeMillisStart = SystemClock.uptimeMillis();
        }

        @Override
        public void onTransitionEnd(Transition transition) {
            mDuration = SystemClock.uptimeMillis() - mUptimeMillisStart;
        }

        public long getDuration() {
            if (mDuration < 0) {
                fail("Requested duration measurement of an incomplete transition.");
            }
            return mDuration;
        }
    }
}
