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

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.assertTrue;
import static org.junit.Assert.fail;

import android.app.Fragment;
import android.app.FragmentController;
import android.app.FragmentManager;
import android.app.FragmentManagerNonConfig;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

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

@MediumTest
@RunWith(AndroidJUnit4.class)
public class PostponedTransitionTest {
    @Rule
    public ActivityTestRule<FragmentTestActivity> mActivityRule =
            new ActivityTestRule<FragmentTestActivity>(FragmentTestActivity.class);

    private PostponedFragment1 mBeginningFragment;

    @Before
    public void setupContainer() throws Throwable {
        FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        mBeginningFragment = new PostponedFragment1();
        fm.beginTransaction()
                .add(R.id.fragmentContainer, mBeginningFragment)
                .commit();
        FragmentTestUtil.waitForExecution(mActivityRule);

        mBeginningFragment.startPostponedEnterTransition();
        mBeginningFragment.waitForTransition();
        clearTargets(mBeginningFragment);
    }

    // Ensure that replacing with a fragment that has a postponed transition
    // will properly postpone it, both adding and popping.
    @Test
    public void replaceTransition() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        final View startBlue = mActivityRule.getActivity().findViewById(R.id.blueSquare);

        final PostponedFragment2 fragment = new PostponedFragment2();
        fm.beginTransaction()
                .addSharedElement(startBlue, "blueSquare")
                .replace(R.id.fragmentContainer, fragment)
                .addToBackStack(null)
                .commit();

        FragmentTestUtil.waitForExecution(mActivityRule);

        // should be postponed now
        assertPostponedTransition(mBeginningFragment, fragment, null);

        // start the postponed transition
        fragment.startPostponedEnterTransition();

        // make sure it ran
        assertForwardTransition(mBeginningFragment, fragment);

        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        // should be postponed going back, too
        assertPostponedTransition(fragment, mBeginningFragment, null);

        // start the postponed transition
        mBeginningFragment.startPostponedEnterTransition();

        // make sure it ran
        assertBackTransition(fragment, mBeginningFragment);
    }

    // Ensure that replacing a fragment doesn't cause problems with the back stack nesting level
    @Test
    public void backStackNestingLevel() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        View startBlue = mActivityRule.getActivity().findViewById(R.id.blueSquare);

        final TransitionFragment fragment1 = new TransitionFragment2();
        fm.beginTransaction()
                .addSharedElement(startBlue, "blueSquare")
                .replace(R.id.fragmentContainer, fragment1)
                .addToBackStack(null)
                .setReorderingAllowed(true)
                .commit();

        // make sure transition ran
        assertForwardTransition(mBeginningFragment, fragment1);

        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        // should be postponed going back
        assertPostponedTransition(fragment1, mBeginningFragment, null);

        // start the postponed transition
        mBeginningFragment.startPostponedEnterTransition();

        // make sure it ran
        assertBackTransition(fragment1, mBeginningFragment);

        startBlue = mActivityRule.getActivity().findViewById(R.id.blueSquare);

        final TransitionFragment fragment2 = new TransitionFragment2();
        fm.beginTransaction()
                .addSharedElement(startBlue, "blueSquare")
                .replace(R.id.fragmentContainer, fragment2)
                .addToBackStack(null)
                .setReorderingAllowed(true)
                .commit();

        // make sure transition ran
        assertForwardTransition(mBeginningFragment, fragment2);

        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        // should be postponed going back
        assertPostponedTransition(fragment2, mBeginningFragment, null);

        // start the postponed transition
        mBeginningFragment.startPostponedEnterTransition();

        // make sure it ran
        assertBackTransition(fragment2, mBeginningFragment);
    }

    // Ensure that postponed transition is forced after another has been committed.
    // This tests when the transactions are executed together
    @Test
    public void forcedTransition1() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        final View startBlue = mActivityRule.getActivity().findViewById(R.id.blueSquare);

        final PostponedFragment2 fragment2 = new PostponedFragment2();
        final PostponedFragment1 fragment3 = new PostponedFragment1();

        final int commit[] = new int[1];
        // Need to run this on the UI thread so that the transaction doesn't start
        // between the two
        mActivityRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                commit[0] = fm.beginTransaction()
                        .addSharedElement(startBlue, "blueSquare")
                        .replace(R.id.fragmentContainer, fragment2)
                        .addToBackStack(null)
                        .commit();

                fm.beginTransaction()
                        .addSharedElement(startBlue, "blueSquare")
                        .replace(R.id.fragmentContainer, fragment3)
                        .addToBackStack(null)
                        .commit();
            }
        });
        FragmentTestUtil.waitForExecution(mActivityRule);

        // transition to fragment2 should be started
        assertForwardTransition(mBeginningFragment, fragment2);

        // fragment3 should be postponed, but fragment2 should be executed with no transition.
        assertPostponedTransition(fragment2, fragment3, mBeginningFragment);

        // start the postponed transition
        fragment3.startPostponedEnterTransition();

        // make sure it ran
        assertForwardTransition(fragment2, fragment3);

        FragmentTestUtil.popBackStackImmediate(mActivityRule, commit[0],
                FragmentManager.POP_BACK_STACK_INCLUSIVE);

        assertBackTransition(fragment3, fragment2);

        assertPostponedTransition(fragment2, mBeginningFragment, fragment3);

        // start the postponed transition
        mBeginningFragment.startPostponedEnterTransition();

        // make sure it ran
        assertBackTransition(fragment2, mBeginningFragment);
    }

    // Ensure that postponed transition is forced after another has been committed.
    // This tests when the transactions are processed separately.
    @Test
    public void forcedTransition2() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        final View startBlue = mActivityRule.getActivity().findViewById(R.id.blueSquare);

        final PostponedFragment2 fragment2 = new PostponedFragment2();

        fm.beginTransaction()
                .addSharedElement(startBlue, "blueSquare")
                .replace(R.id.fragmentContainer, fragment2)
                .addToBackStack(null)
                .commit();

        FragmentTestUtil.waitForExecution(mActivityRule);

        assertPostponedTransition(mBeginningFragment, fragment2, null);

        final PostponedFragment1 fragment3 = new PostponedFragment1();
        fm.beginTransaction()
                .addSharedElement(startBlue, "blueSquare")
                .replace(R.id.fragmentContainer, fragment3)
                .addToBackStack(null)
                .commit();

        // This should cancel the mBeginningFragment -> fragment2 transition
        // and start fragment2 -> fragment3 transition postponed
        FragmentTestUtil.waitForExecution(mActivityRule);

        // fragment3 should be postponed, but fragment2 should be executed with no transition.
        assertPostponedTransition(fragment2, fragment3, mBeginningFragment);

        // start the postponed transition
        fragment3.startPostponedEnterTransition();

        // make sure it ran
        assertForwardTransition(fragment2, fragment3);

        // Pop back to fragment2, but it should be postponed
        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        assertPostponedTransition(fragment3, fragment2, null);

        // Pop to mBeginningFragment -- should cancel the fragment2 transition and
        // start the mBeginningFragment transaction postponed

        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        assertPostponedTransition(fragment2, mBeginningFragment, fragment3);

        // start the postponed transition
        mBeginningFragment.startPostponedEnterTransition();

        // make sure it ran
        assertBackTransition(fragment2, mBeginningFragment);
    }

    // Do a bunch of things to one fragment in a transaction and see if it can screw things up.
    @Test
    public void crazyTransition() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        final View startBlue = mActivityRule.getActivity().findViewById(R.id.blueSquare);

        final PostponedFragment2 fragment2 = new PostponedFragment2();

        fm.beginTransaction()
                .addSharedElement(startBlue, "blueSquare")
                .hide(mBeginningFragment)
                .replace(R.id.fragmentContainer, fragment2)
                .hide(fragment2)
                .detach(fragment2)
                .attach(fragment2)
                .show(fragment2)
                .addToBackStack(null)
                .commit();

        FragmentTestUtil.waitForExecution(mActivityRule);

        assertPostponedTransition(mBeginningFragment, fragment2, null);

        // start the postponed transition
        fragment2.startPostponedEnterTransition();

        // make sure it ran
        assertForwardTransition(mBeginningFragment, fragment2);

        // Pop back to fragment2, but it should be postponed
        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        assertPostponedTransition(fragment2, mBeginningFragment, null);

        // start the postponed transition
        mBeginningFragment.startPostponedEnterTransition();

        // make sure it ran
        assertBackTransition(fragment2, mBeginningFragment);
    }

    // Execute transactions on different containers and ensure that they don't conflict
    @Test
    public void differentContainers() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        fm.beginTransaction().remove(mBeginningFragment).commit();
        FragmentTestUtil.waitForExecution(mActivityRule);
        FragmentTestUtil.setContentView(mActivityRule, R.layout.double_container);

        TransitionFragment fragment1 = new PostponedFragment1();
        TransitionFragment fragment2 = new PostponedFragment1();

        fm.beginTransaction()
                .add(R.id.fragmentContainer1, fragment1)
                .add(R.id.fragmentContainer2, fragment2)
                .commit();
        FragmentTestUtil.waitForExecution(mActivityRule);
        fragment1.startPostponedEnterTransition();
        fragment2.startPostponedEnterTransition();
        fragment1.waitForTransition();
        fragment2.waitForTransition();
        clearTargets(fragment1);
        clearTargets(fragment2);

        final View startBlue1 = fragment1.getView().findViewById(R.id.blueSquare);
        final View startBlue2 = fragment2.getView().findViewById(R.id.blueSquare);

        final TransitionFragment fragment3 = new PostponedFragment2();

        fm.beginTransaction()
                .addSharedElement(startBlue1, "blueSquare")
                .replace(R.id.fragmentContainer1, fragment3)
                .addToBackStack(null)
                .commit();

        FragmentTestUtil.waitForExecution(mActivityRule);

        assertPostponedTransition(fragment1, fragment3, null);

        final TransitionFragment fragment4 = new PostponedFragment2();

        fm.beginTransaction()
                .addSharedElement(startBlue2, "blueSquare")
                .replace(R.id.fragmentContainer2, fragment4)
                .addToBackStack(null)
                .commit();

        FragmentTestUtil.waitForExecution(mActivityRule);

        assertPostponedTransition(fragment1, fragment3, null);
        assertPostponedTransition(fragment2, fragment4, null);

        // start the postponed transition
        fragment3.startPostponedEnterTransition();

        // make sure only one ran
        assertForwardTransition(fragment1, fragment3);
        assertPostponedTransition(fragment2, fragment4, null);

        // start the postponed transition
        fragment4.startPostponedEnterTransition();

        // make sure it ran
        assertForwardTransition(fragment2, fragment4);

        // Pop back to fragment2 -- should be postponed
        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        assertPostponedTransition(fragment4, fragment2, null);

        // Pop back to fragment1 -- also should be postponed
        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        assertPostponedTransition(fragment4, fragment2, null);
        assertPostponedTransition(fragment3, fragment1, null);

        // start the postponed transition
        fragment2.startPostponedEnterTransition();

        // make sure it ran
        assertBackTransition(fragment4, fragment2);

        // but not the postponed one
        assertPostponedTransition(fragment3, fragment1, null);

        // start the postponed transition
        fragment1.startPostponedEnterTransition();

        // make sure it ran
        assertBackTransition(fragment3, fragment1);
    }

    // Execute transactions on different containers and ensure that they don't conflict.
    // The postponement can be started out-of-order
    @Test
    public void outOfOrderContainers() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        fm.beginTransaction().remove(mBeginningFragment).commit();
        FragmentTestUtil.waitForExecution(mActivityRule);
        FragmentTestUtil.setContentView(mActivityRule, R.layout.double_container);

        TransitionFragment fragment1 = new PostponedFragment1();
        TransitionFragment fragment2 = new PostponedFragment1();

        fm.beginTransaction()
                .add(R.id.fragmentContainer1, fragment1)
                .add(R.id.fragmentContainer2, fragment2)
                .commit();
        FragmentTestUtil.waitForExecution(mActivityRule);
        fragment1.startPostponedEnterTransition();
        fragment2.startPostponedEnterTransition();
        fragment1.waitForTransition();
        fragment2.waitForTransition();
        clearTargets(fragment1);
        clearTargets(fragment2);

        final View startBlue1 = fragment1.getView().findViewById(R.id.blueSquare);
        final View startBlue2 = fragment2.getView().findViewById(R.id.blueSquare);

        final TransitionFragment fragment3 = new PostponedFragment2();

        fm.beginTransaction()
                .addSharedElement(startBlue1, "blueSquare")
                .replace(R.id.fragmentContainer1, fragment3)
                .addToBackStack(null)
                .commit();

        FragmentTestUtil.waitForExecution(mActivityRule);

        assertPostponedTransition(fragment1, fragment3, null);

        final TransitionFragment fragment4 = new PostponedFragment2();

        fm.beginTransaction()
                .addSharedElement(startBlue2, "blueSquare")
                .replace(R.id.fragmentContainer2, fragment4)
                .addToBackStack(null)
                .commit();

        FragmentTestUtil.waitForExecution(mActivityRule);

        assertPostponedTransition(fragment1, fragment3, null);
        assertPostponedTransition(fragment2, fragment4, null);

        // start the postponed transition
        fragment4.startPostponedEnterTransition();

        // make sure only one ran
        assertForwardTransition(fragment2, fragment4);
        assertPostponedTransition(fragment1, fragment3, null);

        // start the postponed transition
        fragment3.startPostponedEnterTransition();

        // make sure it ran
        assertForwardTransition(fragment1, fragment3);

        // Pop back to fragment2 -- should be postponed
        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        assertPostponedTransition(fragment4, fragment2, null);

        // Pop back to fragment1 -- also should be postponed
        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        assertPostponedTransition(fragment4, fragment2, null);
        assertPostponedTransition(fragment3, fragment1, null);

        // start the postponed transition
        fragment1.startPostponedEnterTransition();

        // make sure it ran
        assertBackTransition(fragment3, fragment1);

        // but not the postponed one
        assertPostponedTransition(fragment4, fragment2, null);

        // start the postponed transition
        fragment2.startPostponedEnterTransition();

        // make sure it ran
        assertBackTransition(fragment4, fragment2);
    }

    // Make sure that commitNow for a transaction on a different fragment container doesn't
    // affect the postponed transaction
    @Test
    public void commitNowNoEffect() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        fm.beginTransaction().remove(mBeginningFragment).commit();
        FragmentTestUtil.waitForExecution(mActivityRule);
        FragmentTestUtil.setContentView(mActivityRule, R.layout.double_container);

        final TransitionFragment fragment1 = new PostponedFragment1();
        final TransitionFragment fragment2 = new PostponedFragment1();

        fm.beginTransaction()
                .add(R.id.fragmentContainer1, fragment1)
                .add(R.id.fragmentContainer2, fragment2)
                .commit();
        FragmentTestUtil.waitForExecution(mActivityRule);
        fragment1.startPostponedEnterTransition();
        fragment2.startPostponedEnterTransition();
        fragment1.waitForTransition();
        fragment2.waitForTransition();
        clearTargets(fragment1);
        clearTargets(fragment2);

        final View startBlue1 = fragment1.getView().findViewById(R.id.blueSquare);
        final View startBlue2 = fragment2.getView().findViewById(R.id.blueSquare);

        final TransitionFragment fragment3 = new PostponedFragment2();
        final StrictFragment strictFragment1 = new StrictFragment();

        fm.beginTransaction()
                .addSharedElement(startBlue1, "blueSquare")
                .replace(R.id.fragmentContainer1, fragment3)
                .add(strictFragment1, "1")
                .addToBackStack(null)
                .commit();

        FragmentTestUtil.waitForExecution(mActivityRule);

        assertPostponedTransition(fragment1, fragment3, null);

        final TransitionFragment fragment4 = new PostponedFragment2();
        final StrictFragment strictFragment2 = new StrictFragment();

        mActivityRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                fm.beginTransaction()
                        .addSharedElement(startBlue2, "blueSquare")
                        .replace(R.id.fragmentContainer2, fragment4)
                        .remove(strictFragment1)
                        .add(strictFragment2, "2")
                        .commitNow();
            }
        });

        FragmentTestUtil.waitForExecution(mActivityRule);

        assertPostponedTransition(fragment1, fragment3, null);
        assertPostponedTransition(fragment2, fragment4, null);

        // start the postponed transition
        fragment4.startPostponedEnterTransition();

        // make sure only one ran
        assertForwardTransition(fragment2, fragment4);
        assertPostponedTransition(fragment1, fragment3, null);

        // start the postponed transition
        fragment3.startPostponedEnterTransition();

        // make sure it ran
        assertForwardTransition(fragment1, fragment3);
    }

    // Make sure that commitNow for a transaction affecting a postponed fragment in the same
    // container forces the postponed transition to start.
    @Test
    public void commitNowStartsPostponed() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        final View startBlue1 = mBeginningFragment.getView().findViewById(R.id.blueSquare);

        final TransitionFragment fragment2 = new PostponedFragment2();
        final TransitionFragment fragment1 = new PostponedFragment1();

        fm.beginTransaction()
                .addSharedElement(startBlue1, "blueSquare")
                .replace(R.id.fragmentContainer, fragment2)
                .addToBackStack(null)
                .commit();
        FragmentTestUtil.waitForExecution(mActivityRule);

        final View startBlue2 = fragment2.getView().findViewById(R.id.blueSquare);

        mActivityRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                fm.beginTransaction()
                        .addSharedElement(startBlue2, "blueSquare")
                        .replace(R.id.fragmentContainer, fragment1)
                        .commitNow();
            }
        });

        assertPostponedTransition(fragment2, fragment1, mBeginningFragment);

        // start the postponed transition
        fragment1.startPostponedEnterTransition();

        assertForwardTransition(fragment2, fragment1);
    }

    // Make sure that when a transaction that removes a view is postponed that
    // another transaction doesn't accidentally remove the view early.
    @Test
    public void noAccidentalRemoval() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        fm.beginTransaction().remove(mBeginningFragment).commit();
        FragmentTestUtil.waitForExecution(mActivityRule);
        FragmentTestUtil.setContentView(mActivityRule, R.layout.double_container);

        TransitionFragment fragment1 = new PostponedFragment1();

        fm.beginTransaction()
                .add(R.id.fragmentContainer1, fragment1)
                .commit();
        FragmentTestUtil.waitForExecution(mActivityRule);
        fragment1.startPostponedEnterTransition();
        fragment1.waitForTransition();
        clearTargets(fragment1);

        TransitionFragment fragment2 = new PostponedFragment2();
        // Create a postponed transaction that removes a view
        fm.beginTransaction()
                .replace(R.id.fragmentContainer1, fragment2)
                .commit();
        FragmentTestUtil.waitForExecution(mActivityRule);
        assertPostponedTransition(fragment1, fragment2, null);

        TransitionFragment fragment3 = new PostponedFragment1();
        // Create a transaction that doesn't interfere with the previously postponed one
        fm.beginTransaction()
                .replace(R.id.fragmentContainer2, fragment3)
                .commit();
        FragmentTestUtil.waitForExecution(mActivityRule);

        assertPostponedTransition(fragment1, fragment2, null);

        fragment3.startPostponedEnterTransition();
        fragment3.waitForTransition();
        clearTargets(fragment3);

        assertPostponedTransition(fragment1, fragment2, null);
    }

    // Ensure that a postponed transaction that is popped runs immediately and that
    // the transaction results in the original state with no transition.
    @Test
    public void popPostponedTransaction() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        final View startBlue = mBeginningFragment.getView().findViewById(R.id.blueSquare);

        final TransitionFragment fragment = new PostponedFragment2();

        fm.beginTransaction()
                .addSharedElement(startBlue, "blueSquare")
                .replace(R.id.fragmentContainer, fragment)
                .addToBackStack(null)
                .commit();
        FragmentTestUtil.waitForExecution(mActivityRule);

        assertPostponedTransition(mBeginningFragment, fragment, null);

        FragmentTestUtil.popBackStackImmediate(mActivityRule);

        fragment.waitForNoTransition();
        mBeginningFragment.waitForNoTransition();

        assureNoTransition(fragment);
        assureNoTransition(mBeginningFragment);

        assertFalse(fragment.isAdded());
        assertNull(fragment.getView());
        assertNotNull(mBeginningFragment.getView());
        assertTrue(FragmentTestUtil.isVisible(mBeginningFragment));
        assertTrue(mBeginningFragment.getView().isAttachedToWindow());
    }

    // Make sure that when saving the state during a postponed transaction that it saves
    // the state as if it wasn't postponed.
    @Test
    public void saveWhilePostponed() throws Throwable {
        final FragmentController fc1 = FragmentTestUtil.createController(mActivityRule);
        FragmentTestUtil.resume(mActivityRule, fc1, null);

        final FragmentManager fm1 = fc1.getFragmentManager();

        PostponedFragment1 fragment1 = new PostponedFragment1();
        fm1.beginTransaction()
                .add(R.id.fragmentContainer, fragment1, "1")
                .addToBackStack(null)
                .commit();
        FragmentTestUtil.waitForExecution(mActivityRule);

        Pair<Parcelable, FragmentManagerNonConfig> state =
                FragmentTestUtil.destroy(mActivityRule, fc1);

        final FragmentController fc2 = FragmentTestUtil.createController(mActivityRule);
        FragmentTestUtil.resume(mActivityRule, fc2, state);

        final FragmentManager fm2 = fc2.getFragmentManager();
        Fragment fragment2 = fm2.findFragmentByTag("1");
        assertNotNull(fragment2);
        assertNotNull(fragment2.getView());
        assertEquals(View.VISIBLE, fragment2.getView().getVisibility());
        assertTrue(fragment2.isResumed());
        assertTrue(fragment2.isAdded());
        assertTrue(fragment2.getView().isAttachedToWindow());

        mActivityRule.runOnUiThread(() -> {
            assertTrue(fm2.popBackStackImmediate());
        });

        assertFalse(fragment2.isResumed());
        assertFalse(fragment2.isAdded());
        assertNull(fragment2.getView());
    }

    // Ensure that the postponed fragment transactions don't allow reentrancy in fragment manager
    @Test
    public void postponeDoesNotAllowReentrancy() throws Throwable {
        final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
        final View startBlue = mActivityRule.getActivity().findViewById(R.id.blueSquare);

        final CommitNowFragment fragment = new CommitNowFragment();
        fm.beginTransaction()
                .addSharedElement(startBlue, "blueSquare")
                .replace(R.id.fragmentContainer, fragment)
                .addToBackStack(null)
                .commit();

        FragmentTestUtil.waitForExecution(mActivityRule);

        // should be postponed now
        assertPostponedTransition(mBeginningFragment, fragment, null);

        mActivityRule.runOnUiThread(() -> {
            // start the postponed transition
            fragment.startPostponedEnterTransition();

            try {
                // This should trigger an IllegalStateException
                fm.executePendingTransactions();
                fail("commitNow() while executing a transaction should cause an "
                        + "IllegalStateException");
            } catch (IllegalStateException e) {
                // expected
            }
        });
    }

    private void assertPostponedTransition(TransitionFragment fromFragment,
            TransitionFragment toFragment, TransitionFragment removedFragment)
            throws InterruptedException {
        if (removedFragment != null) {
            assertNull(removedFragment.getView());
            assureNoTransition(removedFragment);
        }

        toFragment.waitForNoTransition();
        assertNotNull(fromFragment.getView());
        assertNotNull(toFragment.getView());
        assertTrue(fromFragment.getView().isAttachedToWindow());
        assertTrue(toFragment.getView().isAttachedToWindow());
        assertEquals(View.VISIBLE, fromFragment.getView().getVisibility());
        assertTrue(FragmentTestUtil.isVisible(fromFragment));
        assertEquals(View.VISIBLE, toFragment.getView().getVisibility());
        assertFalse(FragmentTestUtil.isVisible(toFragment));
        assureNoTransition(fromFragment);
        assureNoTransition(toFragment);
        assertTrue(fromFragment.isResumed());
        assertFalse(toFragment.isResumed());
    }

    private void clearTargets(TransitionFragment fragment) {
        fragment.enterTransition.targets.clear();
        fragment.reenterTransition.targets.clear();
        fragment.exitTransition.targets.clear();
        fragment.returnTransition.targets.clear();
        fragment.sharedElementEnter.targets.clear();
        fragment.sharedElementReturn.targets.clear();
    }

    private void assureNoTransition(TransitionFragment fragment) {
        assertEquals(0, fragment.enterTransition.targets.size());
        assertEquals(0, fragment.reenterTransition.targets.size());
        assertEquals(0, fragment.enterTransition.targets.size());
        assertEquals(0, fragment.returnTransition.targets.size());
        assertEquals(0, fragment.sharedElementEnter.targets.size());
        assertEquals(0, fragment.sharedElementReturn.targets.size());
    }

    private void assertForwardTransition(TransitionFragment start, TransitionFragment end)
            throws InterruptedException {
        start.waitForTransition();
        end.waitForTransition();
        assertEquals(0, start.enterTransition.targets.size());
        assertEquals(1, end.enterTransition.targets.size());

        assertEquals(0, start.reenterTransition.targets.size());
        assertEquals(0, end.reenterTransition.targets.size());

        assertEquals(0, start.returnTransition.targets.size());
        assertEquals(0, end.returnTransition.targets.size());

        assertEquals(1, start.exitTransition.targets.size());
        assertEquals(0, end.exitTransition.targets.size());

        assertEquals(0, start.sharedElementEnter.targets.size());
        assertEquals(2, end.sharedElementEnter.targets.size());

        assertEquals(0, start.sharedElementReturn.targets.size());
        assertEquals(0, end.sharedElementReturn.targets.size());

        final View blue = end.getView().findViewById(R.id.blueSquare);
        assertTrue(end.sharedElementEnter.targets.contains(blue));
        assertEquals("blueSquare", end.sharedElementEnter.targets.get(0).getTransitionName());
        assertEquals("blueSquare", end.sharedElementEnter.targets.get(1).getTransitionName());

        assertNoTargets(start);
        assertNoTargets(end);

        clearTargets(start);
        clearTargets(end);
    }

    private void assertBackTransition(TransitionFragment start, TransitionFragment end)
            throws InterruptedException {
        start.waitForTransition();
        end.waitForTransition();
        assertEquals(1, end.reenterTransition.targets.size());
        assertEquals(0, start.reenterTransition.targets.size());

        assertEquals(0, end.returnTransition.targets.size());
        assertEquals(1, start.returnTransition.targets.size());

        assertEquals(0, start.enterTransition.targets.size());
        assertEquals(0, end.enterTransition.targets.size());

        assertEquals(0, start.exitTransition.targets.size());
        assertEquals(0, end.exitTransition.targets.size());

        assertEquals(0, start.sharedElementEnter.targets.size());
        assertEquals(0, end.sharedElementEnter.targets.size());

        assertEquals(2, start.sharedElementReturn.targets.size());
        assertEquals(0, end.sharedElementReturn.targets.size());

        final View blue = end.getView().findViewById(R.id.blueSquare);
        assertTrue(start.sharedElementReturn.targets.contains(blue));
        assertEquals("blueSquare", start.sharedElementReturn.targets.get(0).getTransitionName());
        assertEquals("blueSquare", start.sharedElementReturn.targets.get(1).getTransitionName());

        assertNoTargets(end);
        assertNoTargets(start);

        clearTargets(start);
        clearTargets(end);
    }

    private static void assertNoTargets(TransitionFragment fragment) {
        assertTrue(fragment.enterTransition.getTargets().isEmpty());
        assertTrue(fragment.reenterTransition.getTargets().isEmpty());
        assertTrue(fragment.exitTransition.getTargets().isEmpty());
        assertTrue(fragment.returnTransition.getTargets().isEmpty());
        assertTrue(fragment.sharedElementEnter.getTargets().isEmpty());
        assertTrue(fragment.sharedElementReturn.getTargets().isEmpty());
    }

    public static class PostponedFragment1 extends TransitionFragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            postponeEnterTransition();
            return inflater.inflate(R.layout.scene1, container, false);
        }
    }

    public static class PostponedFragment2 extends TransitionFragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            postponeEnterTransition();
            return inflater.inflate(R.layout.scene2, container, false);
        }
    }

    public static class CommitNowFragment extends PostponedFragment1 {
        @Override
        public void onResume() {
            super.onResume();
            // This should throw because this happens during the execution
            getFragmentManager().beginTransaction()
                    .add(R.id.fragmentContainer, new PostponedFragment1())
                    .commitNow();
        }
    }

    public static class TransitionFragment2 extends TransitionFragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            super.onCreateView(inflater, container, savedInstanceState);
            return inflater.inflate(R.layout.scene2, container, false);
        }
    }
}
