1990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount/*
2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project
3990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount *
4990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Licensed under the Apache License, Version 2.0 (the "License");
5990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * you may not use this file except in compliance with the License.
6990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * You may obtain a copy of the License at
7990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount *
8990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount *      http://www.apache.org/licenses/LICENSE-2.0
9990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount *
10990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Unless required by applicable law or agreed to in writing, software
11990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * distributed under the License is distributed on an "AS IS" BASIS,
12990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * See the License for the specific language governing permissions and
14990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * limitations under the License.
15990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */
16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.fragment.app;
17990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
18990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static org.junit.Assert.assertEquals;
19990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static org.junit.Assert.assertFalse;
20990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static org.junit.Assert.assertNotNull;
21990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static org.junit.Assert.assertNull;
22990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport static org.junit.Assert.assertTrue;
23990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
24990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.app.Instrumentation;
25e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport android.os.Bundle;
26990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.os.Parcelable;
27990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.support.test.InstrumentationRegistry;
28990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.support.test.filters.MediumTest;
29990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.support.test.rule.ActivityTestRule;
30990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.support.test.runner.AndroidJUnit4;
31990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.util.Pair;
32e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport android.view.LayoutInflater;
33990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.View;
34e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport android.view.ViewGroup;
35990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.animation.Animation;
36e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport android.view.animation.AnimationUtils;
37990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport android.view.animation.TranslateAnimation;
38990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
39320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.annotation.AnimRes;
40320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.core.view.ViewCompat;
41320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.fragment.app.test.FragmentTestActivity;
42320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.fragment.test.R;
43320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikas
44990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport org.junit.Before;
45990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport org.junit.Rule;
46990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport org.junit.Test;
47990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountimport org.junit.runner.RunWith;
48990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
49e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport java.util.concurrent.CountDownLatch;
50e62545fdf58881a2d0426285648f71ce9323ca15George Mountimport java.util.concurrent.TimeUnit;
51e62545fdf58881a2d0426285648f71ce9323ca15George Mount
52990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount@MediumTest
53990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount@RunWith(AndroidJUnit4.class)
54990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mountpublic class FragmentAnimationTest {
55990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // These are pretend resource IDs for animators. We don't need real ones since we
56990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // load them by overriding onCreateAnimator
57990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @AnimRes
58990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    private static final int ENTER = 1;
59990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @AnimRes
60990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    private static final int EXIT = 2;
61990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @AnimRes
62990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    private static final int POP_ENTER = 3;
63990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @AnimRes
64990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    private static final int POP_EXIT = 4;
65990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
66990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Rule
67990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public ActivityTestRule<FragmentTestActivity> mActivityRule =
68990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            new ActivityTestRule<FragmentTestActivity>(FragmentTestActivity.class);
69990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
70990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    private Instrumentation mInstrumentation;
71990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
72990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Before
73990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void setupContainer() {
74990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        mInstrumentation = InstrumentationRegistry.getInstrumentation();
75990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
76990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
77990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
78990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Ensure that adding and popping a Fragment uses the enter and popExit animators
79990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
80990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void addAnimators() throws Throwable {
81990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
82990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
83990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        // One fragment with a view
84990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment = new AnimatorFragment();
85990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
86990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
87990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .add(R.id.fragmentContainer, fragment)
88990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
89990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
90990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
91990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
92990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEnterPopExit(fragment);
93990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
94990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
95990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Ensure that removing and popping a Fragment uses the exit and popEnter animators
96990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
97990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void removeAnimators() throws Throwable {
98990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
99990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
100990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        // One fragment with a view
101990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment = new AnimatorFragment();
102990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit();
103990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
104990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
105990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
106990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
107990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .remove(fragment)
108990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
109990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
110990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
111990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
112990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertExitPopEnter(fragment);
113990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
114990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
115990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Ensure that showing and popping a Fragment uses the enter and popExit animators
116990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
117990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void showAnimators() throws Throwable {
118990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
119990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
120990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        // One fragment with a view
121990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment = new AnimatorFragment();
122990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction().add(R.id.fragmentContainer, fragment).hide(fragment).commit();
123990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
124990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
125990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
126990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
127990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .show(fragment)
128990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
129990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
130990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
131990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
132990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEnterPopExit(fragment);
133990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
134990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
135990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Ensure that hiding and popping a Fragment uses the exit and popEnter animators
136990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
137990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void hideAnimators() throws Throwable {
138990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
139990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
140990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        // One fragment with a view
141990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment = new AnimatorFragment();
142990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit();
143990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
144990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
145990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
146990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
147990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .hide(fragment)
148990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
149990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
150990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
151990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
152990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertExitPopEnter(fragment);
153990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
154990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
155990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Ensure that attaching and popping a Fragment uses the enter and popExit animators
156990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
157990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void attachAnimators() throws Throwable {
158990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
159990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
160990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        // One fragment with a view
161990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment = new AnimatorFragment();
162990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction().add(R.id.fragmentContainer, fragment).detach(fragment).commit();
163990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
164990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
165990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
166990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
167990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .attach(fragment)
168990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
169990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
170990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
171990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
172990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEnterPopExit(fragment);
173990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
174990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
175990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Ensure that detaching and popping a Fragment uses the exit and popEnter animators
176990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
177990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void detachAnimators() throws Throwable {
178990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
179990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
180990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        // One fragment with a view
181990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment = new AnimatorFragment();
182990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit();
183990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
184990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
185990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
186990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
187990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .detach(fragment)
188990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
189990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
190990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
191990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
192990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertExitPopEnter(fragment);
193990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
194990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
195990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Replace should exit the existing fragments and enter the added fragment, then
196990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // popping should popExit the removed fragment and popEnter the added fragments
197990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
198990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void replaceAnimators() throws Throwable {
199990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
200990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
201990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        // One fragment with a view
202990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment1 = new AnimatorFragment();
203990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment2 = new AnimatorFragment();
204990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
205990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .add(R.id.fragmentContainer, fragment1, "1")
206990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .add(R.id.fragmentContainer, fragment2, "2")
207990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
208990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
209990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
210990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment3 = new AnimatorFragment();
211990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
212990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
213990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .replace(R.id.fragmentContainer, fragment3)
214990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
215990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
216990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
217990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
218990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(fragment1, 1, false, EXIT);
219990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(fragment2, 1, false, EXIT);
220990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(fragment3, 1, true, ENTER);
221990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
222990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.popBackStack();
223990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
224990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
225990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(fragment3, 2, false, POP_EXIT);
226990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment replacement1 = (AnimatorFragment) fm.findFragmentByTag("1");
227990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment replacement2 = (AnimatorFragment) fm.findFragmentByTag("1");
228990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        int expectedAnimations = replacement1 == fragment1 ? 2 : 1;
229990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(replacement1, expectedAnimations, true, POP_ENTER);
230990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(replacement2, expectedAnimations, true, POP_ENTER);
231990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
232990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
233990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Ensure that adding and popping a Fragment uses the enter and popExit animators,
234990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // but the animators are delayed when an entering Fragment is postponed.
235990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
236990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void postponedAddAnimators() throws Throwable {
237990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
238990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
239990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment = new AnimatorFragment();
240990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fragment.postponeEnterTransition();
241990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
242990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
243990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .add(R.id.fragmentContainer, fragment)
244990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
245fda5be2466024a656152015c45a7681361d399bbGeorge Mount                .setReorderingAllowed(true)
246990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
247990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
248990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
249990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertPostponed(fragment, 0);
250990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fragment.startPostponedEnterTransition();
251990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
252990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
253990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEnterPopExit(fragment);
254990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
255990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
256990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Ensure that removing and popping a Fragment uses the exit and popEnter animators,
257990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // but the animators are delayed when an entering Fragment is postponed.
258990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
259990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void postponedRemoveAnimators() throws Throwable {
260990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
261990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
262990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment = new AnimatorFragment();
263990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction().add(R.id.fragmentContainer, fragment, "1").commit();
264990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
265990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
266990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
267990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
268990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .remove(fragment)
269990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
270fda5be2466024a656152015c45a7681361d399bbGeorge Mount                .setReorderingAllowed(true)
271990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
272990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
273990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
274990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertExitPostponedPopEnter(fragment);
275990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
276990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
277990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Ensure that adding and popping a Fragment is postponed in both directions
278990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // when the fragments have been marked for postponing.
279990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
280990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void postponedAddRemove() throws Throwable {
281990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
282990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
283990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment1 = new AnimatorFragment();
284990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
285990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .add(R.id.fragmentContainer, fragment1)
286990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
287fda5be2466024a656152015c45a7681361d399bbGeorge Mount                .setReorderingAllowed(true)
288990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
289990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
290990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
291990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment2 = new AnimatorFragment();
292990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fragment2.postponeEnterTransition();
293990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
294990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
295990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
296990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .replace(R.id.fragmentContainer, fragment2)
297990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
298fda5be2466024a656152015c45a7681361d399bbGeorge Mount                .setReorderingAllowed(true)
299990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
300990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
301990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
302990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
303990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertPostponed(fragment2, 0);
304990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertNotNull(fragment1.getView());
305990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEquals(View.VISIBLE, fragment1.getView().getVisibility());
30615e593ea3575512d7072240d1db9d74fad8749a3George Mount        assertEquals(1f, fragment1.getView().getAlpha(), 0f);
3074285a0db794444695fd0752e7bbc2ad95082043cGeorge Mount        assertTrue(ViewCompat.isAttachedToWindow(fragment1.getView()));
308990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
309990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fragment2.startPostponedEnterTransition();
310990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
311990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
312990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertExitPostponedPopEnter(fragment1);
313990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
314990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
315990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Popping a postponed transaction should result in no animators
316990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
317990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void popPostponed() throws Throwable {
318990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
319990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
320990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment1 = new AnimatorFragment();
321990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
322990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .add(R.id.fragmentContainer, fragment1)
323fda5be2466024a656152015c45a7681361d399bbGeorge Mount                .setReorderingAllowed(true)
324990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
325990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
326990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEquals(0, fragment1.numAnimators);
327990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
328990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final AnimatorFragment fragment2 = new AnimatorFragment();
329990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fragment2.postponeEnterTransition();
330990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
331990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.beginTransaction()
332990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(ENTER, EXIT, POP_ENTER, POP_EXIT)
333990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .replace(R.id.fragmentContainer, fragment2)
334990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
335fda5be2466024a656152015c45a7681361d399bbGeorge Mount                .setReorderingAllowed(true)
336990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
337990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
338990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
339990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
340990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertPostponed(fragment2, 0);
341990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
342990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        // Now pop the postponed transaction
343990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.popBackStackImmediate(mActivityRule);
344990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
345990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertNotNull(fragment1.getView());
346990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEquals(View.VISIBLE, fragment1.getView().getVisibility());
34715e593ea3575512d7072240d1db9d74fad8749a3George Mount        assertEquals(1f, fragment1.getView().getAlpha(), 0f);
3484285a0db794444695fd0752e7bbc2ad95082043cGeorge Mount        assertTrue(ViewCompat.isAttachedToWindow(fragment1.getView()));
349990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertTrue(fragment1.isAdded());
350990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
351990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertNull(fragment2.getView());
352990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFalse(fragment2.isAdded());
353990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
354990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEquals(0, fragment1.numAnimators);
355990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEquals(0, fragment2.numAnimators);
356990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertNull(fragment1.animation);
357990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertNull(fragment2.animation);
358990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
359990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
360990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // Make sure that if the state was saved while a Fragment was animating that its
361990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    // state is proper after restoring.
362990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    @Test
363990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public void saveWhileAnimatingAway() throws Throwable {
364990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentController fc1 = FragmentTestUtil.createController(mActivityRule);
3659268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount        FragmentTestUtil.resume(mActivityRule, fc1, null);
366990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
367990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm1 = fc1.getSupportFragmentManager();
368990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
369990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        StrictViewFragment fragment1 = new StrictViewFragment();
370990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fragment1.setLayoutId(R.layout.scene1);
371990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm1.beginTransaction()
372990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .add(R.id.fragmentContainer, fragment1, "1")
373990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
374990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
375990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
376990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        StrictViewFragment fragment2 = new StrictViewFragment();
377990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
378990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm1.beginTransaction()
379990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .setCustomAnimations(0, 0, 0, R.anim.long_fade_out)
380990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .replace(R.id.fragmentContainer, fragment2, "2")
381990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .addToBackStack(null)
382990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                .commit();
383990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        mInstrumentation.runOnMainSync(new Runnable() {
384990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            @Override
385990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            public void run() {
386990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                fm1.executePendingTransactions();
387990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            }
388990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        });
389990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
390990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
391990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm1.popBackStack();
392990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
393990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        mInstrumentation.runOnMainSync(new Runnable() {
394990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            @Override
395990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            public void run() {
396990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                fm1.executePendingTransactions();
397990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            }
398990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        });
399990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
400990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        // Now fragment2 should be animating away
401990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFalse(fragment2.isAdded());
402990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEquals(fragment2, fm1.findFragmentByTag("2")); // still exists because it is animating
403990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
404990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        Pair<Parcelable, FragmentManagerNonConfig> state =
4059268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount                FragmentTestUtil.destroy(mActivityRule, fc1);
406990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
407990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentController fc2 = FragmentTestUtil.createController(mActivityRule);
4089268ce1264c6c2919b3feb1e26eef13ded3c9ab4George Mount        FragmentTestUtil.resume(mActivityRule, fc2, state);
409990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
410990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm2 = fc2.getSupportFragmentManager();
411990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        Fragment fragment2restored = fm2.findFragmentByTag("2");
412990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertNull(fragment2restored);
413990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
414990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        Fragment fragment1restored = fm2.findFragmentByTag("1");
415990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertNotNull(fragment1restored);
416990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertNotNull(fragment1restored.getView());
417990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
418990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
419a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount    // When an animation is running on a Fragment's View, the view shouldn't be
420a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount    // prevented from being removed. There's no way to directly test this, so we have to
421a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount    // test to see if the animation is still running.
422a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount    @Test
423a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount    public void clearAnimations() throws Throwable {
424a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
425a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount
426a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        final StrictViewFragment fragment1 = new StrictViewFragment();
427a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        fm.beginTransaction()
428a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount                .add(R.id.fragmentContainer, fragment1)
429fda5be2466024a656152015c45a7681361d399bbGeorge Mount                .setReorderingAllowed(true)
430a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount                .commit();
431a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        FragmentTestUtil.waitForExecution(mActivityRule);
432a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount
433a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        final View fragmentView = fragment1.getView();
434a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount
435a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        final TranslateAnimation xAnimation = new TranslateAnimation(0, 1000, 0, 0);
436a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        mActivityRule.runOnUiThread(new Runnable() {
437a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount            @Override
438a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount            public void run() {
439a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount                fragmentView.startAnimation(xAnimation);
440a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount            }
441a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        });
442a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount
443a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        FragmentTestUtil.waitForExecution(mActivityRule);
444a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        FragmentTestUtil.popBackStackImmediate(mActivityRule);
445a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        mActivityRule.runOnUiThread(new Runnable() {
446a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount            @Override
447a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount            public void run() {
448a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount                assertNull(fragmentView.getAnimation());
449a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount            }
450a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount        });
451a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount    }
452a6a88fd0bbc5e342b4a71c143c907a61c5666bb4George Mount
453e62545fdf58881a2d0426285648f71ce9323ca15George Mount    // When a view is animated out, is parent should be null after the animation completes
454e62545fdf58881a2d0426285648f71ce9323ca15George Mount    @Test
455e62545fdf58881a2d0426285648f71ce9323ca15George Mount    public void parentNullAfterAnimation() throws Throwable {
456e62545fdf58881a2d0426285648f71ce9323ca15George Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
457e62545fdf58881a2d0426285648f71ce9323ca15George Mount
458e62545fdf58881a2d0426285648f71ce9323ca15George Mount        final EndAnimationListenerFragment fragment1 = new EndAnimationListenerFragment();
459e62545fdf58881a2d0426285648f71ce9323ca15George Mount        fm.beginTransaction()
460e62545fdf58881a2d0426285648f71ce9323ca15George Mount                .add(R.id.fragmentContainer, fragment1)
461e62545fdf58881a2d0426285648f71ce9323ca15George Mount                .commit();
462e62545fdf58881a2d0426285648f71ce9323ca15George Mount        FragmentTestUtil.waitForExecution(mActivityRule);
463e62545fdf58881a2d0426285648f71ce9323ca15George Mount
464e62545fdf58881a2d0426285648f71ce9323ca15George Mount        final EndAnimationListenerFragment fragment2 = new EndAnimationListenerFragment();
465e62545fdf58881a2d0426285648f71ce9323ca15George Mount
466e62545fdf58881a2d0426285648f71ce9323ca15George Mount        fm.beginTransaction()
467e62545fdf58881a2d0426285648f71ce9323ca15George Mount                .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out,
468e62545fdf58881a2d0426285648f71ce9323ca15George Mount                        android.R.anim.fade_in, android.R.anim.fade_out)
469e62545fdf58881a2d0426285648f71ce9323ca15George Mount                .replace(R.id.fragmentContainer, fragment2)
470e62545fdf58881a2d0426285648f71ce9323ca15George Mount                .addToBackStack(null)
471e62545fdf58881a2d0426285648f71ce9323ca15George Mount                .commit();
472e62545fdf58881a2d0426285648f71ce9323ca15George Mount
473e62545fdf58881a2d0426285648f71ce9323ca15George Mount        FragmentTestUtil.waitForExecution(mActivityRule);
474e62545fdf58881a2d0426285648f71ce9323ca15George Mount
475e62545fdf58881a2d0426285648f71ce9323ca15George Mount        assertTrue(fragment1.exitLatch.await(1, TimeUnit.SECONDS));
476e62545fdf58881a2d0426285648f71ce9323ca15George Mount        assertTrue(fragment2.enterLatch.await(1, TimeUnit.SECONDS));
477e62545fdf58881a2d0426285648f71ce9323ca15George Mount
478e62545fdf58881a2d0426285648f71ce9323ca15George Mount        mActivityRule.runOnUiThread(new Runnable() {
479e62545fdf58881a2d0426285648f71ce9323ca15George Mount            @Override
480e62545fdf58881a2d0426285648f71ce9323ca15George Mount            public void run() {
481e62545fdf58881a2d0426285648f71ce9323ca15George Mount                assertNotNull(fragment1.view);
482e62545fdf58881a2d0426285648f71ce9323ca15George Mount                assertNotNull(fragment2.view);
483e62545fdf58881a2d0426285648f71ce9323ca15George Mount                assertNull(fragment1.view.getParent());
484e62545fdf58881a2d0426285648f71ce9323ca15George Mount            }
485e62545fdf58881a2d0426285648f71ce9323ca15George Mount        });
486e62545fdf58881a2d0426285648f71ce9323ca15George Mount
487e62545fdf58881a2d0426285648f71ce9323ca15George Mount        // Now pop the transaction
488e62545fdf58881a2d0426285648f71ce9323ca15George Mount        FragmentTestUtil.popBackStackImmediate(mActivityRule);
489e62545fdf58881a2d0426285648f71ce9323ca15George Mount
490e62545fdf58881a2d0426285648f71ce9323ca15George Mount        assertTrue(fragment2.exitLatch.await(1, TimeUnit.SECONDS));
491e62545fdf58881a2d0426285648f71ce9323ca15George Mount        assertTrue(fragment1.enterLatch.await(1, TimeUnit.SECONDS));
492e62545fdf58881a2d0426285648f71ce9323ca15George Mount
493e62545fdf58881a2d0426285648f71ce9323ca15George Mount        mActivityRule.runOnUiThread(new Runnable() {
494e62545fdf58881a2d0426285648f71ce9323ca15George Mount            @Override
495e62545fdf58881a2d0426285648f71ce9323ca15George Mount            public void run() {
496e62545fdf58881a2d0426285648f71ce9323ca15George Mount                assertNull(fragment2.view.getParent());
497e62545fdf58881a2d0426285648f71ce9323ca15George Mount            }
498e62545fdf58881a2d0426285648f71ce9323ca15George Mount        });
499e62545fdf58881a2d0426285648f71ce9323ca15George Mount    }
500e62545fdf58881a2d0426285648f71ce9323ca15George Mount
501990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    private void assertEnterPopExit(AnimatorFragment fragment) throws Throwable {
502990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(fragment, 1, true, ENTER);
503990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
504990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
505990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.popBackStack();
506990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
507990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
508990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(fragment, 2, false, POP_EXIT);
509990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
510990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
511990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    private void assertExitPopEnter(AnimatorFragment fragment) throws Throwable {
512990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(fragment, 1, false, EXIT);
513990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
514990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
515990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fm.popBackStack();
516990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
517990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
518990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        AnimatorFragment replacement = (AnimatorFragment) fm.findFragmentByTag("1");
519990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
520990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        boolean isSameFragment = replacement == fragment;
521990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        int expectedAnimators = isSameFragment ? 2 : 1;
522990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(replacement, expectedAnimators, true, POP_ENTER);
523990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
524990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
525990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    private void assertExitPostponedPopEnter(AnimatorFragment fragment) throws Throwable {
526990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(fragment, 1, false, EXIT);
527990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
528990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fragment.postponeEnterTransition();
529990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.popBackStackImmediate(mActivityRule);
530990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
531990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertPostponed(fragment, 1);
532990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
533990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        fragment.startPostponedEnterTransition();
534990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        FragmentTestUtil.waitForExecution(mActivityRule);
535990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertFragmentAnimation(fragment, 2, true, POP_ENTER);
536990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
537990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
538990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    private void assertFragmentAnimation(AnimatorFragment fragment, int numAnimators,
539990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            boolean isEnter, int animatorResourceId) throws InterruptedException {
540990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEquals(numAnimators, fragment.numAnimators);
541990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEquals(isEnter, fragment.enter);
542990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEquals(animatorResourceId, fragment.resourceId);
543990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertNotNull(fragment.animation);
5444285a0db794444695fd0752e7bbc2ad95082043cGeorge Mount        assertTrue(FragmentTestUtil.waitForAnimationEnd(1000, fragment.animation));
545990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertTrue(fragment.animation.hasStarted());
546990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
547990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
548990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    private void assertPostponed(AnimatorFragment fragment, int expectedAnimators)
549990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            throws InterruptedException {
550990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertTrue(fragment.mOnCreateViewCalled);
55115e593ea3575512d7072240d1db9d74fad8749a3George Mount        assertEquals(View.VISIBLE, fragment.getView().getVisibility());
55215e593ea3575512d7072240d1db9d74fad8749a3George Mount        assertEquals(0f, fragment.getView().getAlpha(), 0f);
553990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        assertEquals(expectedAnimators, fragment.numAnimators);
554990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
555990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
556990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    public static class AnimatorFragment extends StrictViewFragment {
557990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        public int numAnimators;
558990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        public Animation animation;
559990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        public boolean enter;
560990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        public int resourceId;
561990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount
562990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        @Override
563990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
564990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            if (nextAnim == 0) {
565990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount                return null;
566990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            }
567990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            this.numAnimators++;
568990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            this.animation = new TranslateAnimation(-10, 0, 0, 0);
569990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            this.animation.setDuration(1);
570990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            this.resourceId = nextAnim;
571990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            this.enter = enter;
572990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount            return this.animation;
573990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount        }
574990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount    }
575e62545fdf58881a2d0426285648f71ce9323ca15George Mount
576e62545fdf58881a2d0426285648f71ce9323ca15George Mount    public static class EndAnimationListenerFragment extends StrictViewFragment {
577e62545fdf58881a2d0426285648f71ce9323ca15George Mount        public View view;
578e62545fdf58881a2d0426285648f71ce9323ca15George Mount        public final CountDownLatch enterLatch = new CountDownLatch(1);
579e62545fdf58881a2d0426285648f71ce9323ca15George Mount        public final CountDownLatch exitLatch = new CountDownLatch(1);
580e62545fdf58881a2d0426285648f71ce9323ca15George Mount
581e62545fdf58881a2d0426285648f71ce9323ca15George Mount        @Override
582e62545fdf58881a2d0426285648f71ce9323ca15George Mount        public View onCreateView(LayoutInflater inflater, ViewGroup container,
583e62545fdf58881a2d0426285648f71ce9323ca15George Mount                Bundle savedInstanceState) {
584e62545fdf58881a2d0426285648f71ce9323ca15George Mount            if (view != null) {
585e62545fdf58881a2d0426285648f71ce9323ca15George Mount                return view;
586e62545fdf58881a2d0426285648f71ce9323ca15George Mount            }
587e62545fdf58881a2d0426285648f71ce9323ca15George Mount            view = super.onCreateView(inflater, container, savedInstanceState);
588e62545fdf58881a2d0426285648f71ce9323ca15George Mount            return view;
589e62545fdf58881a2d0426285648f71ce9323ca15George Mount        }
590e62545fdf58881a2d0426285648f71ce9323ca15George Mount
591e62545fdf58881a2d0426285648f71ce9323ca15George Mount        @Override
592e62545fdf58881a2d0426285648f71ce9323ca15George Mount        public Animation onCreateAnimation(int transit, final boolean enter, int nextAnim) {
593e62545fdf58881a2d0426285648f71ce9323ca15George Mount            if (nextAnim == 0) {
594e62545fdf58881a2d0426285648f71ce9323ca15George Mount                return null;
595e62545fdf58881a2d0426285648f71ce9323ca15George Mount            }
596e62545fdf58881a2d0426285648f71ce9323ca15George Mount            Animation anim = AnimationUtils.loadAnimation(getActivity(), nextAnim);
597e62545fdf58881a2d0426285648f71ce9323ca15George Mount            if (anim != null) {
598e62545fdf58881a2d0426285648f71ce9323ca15George Mount                anim.setAnimationListener(new Animation.AnimationListener() {
599e62545fdf58881a2d0426285648f71ce9323ca15George Mount                    @Override
600e62545fdf58881a2d0426285648f71ce9323ca15George Mount                    public void onAnimationStart(Animation animation) {
601e62545fdf58881a2d0426285648f71ce9323ca15George Mount                    }
602e62545fdf58881a2d0426285648f71ce9323ca15George Mount
603e62545fdf58881a2d0426285648f71ce9323ca15George Mount                    @Override
604e62545fdf58881a2d0426285648f71ce9323ca15George Mount                    public void onAnimationEnd(Animation animation) {
605e62545fdf58881a2d0426285648f71ce9323ca15George Mount                        if (enter) {
606e62545fdf58881a2d0426285648f71ce9323ca15George Mount                            enterLatch.countDown();
607e62545fdf58881a2d0426285648f71ce9323ca15George Mount                        } else {
608e62545fdf58881a2d0426285648f71ce9323ca15George Mount                            exitLatch.countDown();
609e62545fdf58881a2d0426285648f71ce9323ca15George Mount                        }
610e62545fdf58881a2d0426285648f71ce9323ca15George Mount                    }
611e62545fdf58881a2d0426285648f71ce9323ca15George Mount
612e62545fdf58881a2d0426285648f71ce9323ca15George Mount                    @Override
613e62545fdf58881a2d0426285648f71ce9323ca15George Mount                    public void onAnimationRepeat(Animation animation) {
614e62545fdf58881a2d0426285648f71ce9323ca15George Mount
615e62545fdf58881a2d0426285648f71ce9323ca15George Mount                    }
616e62545fdf58881a2d0426285648f71ce9323ca15George Mount                });
617e62545fdf58881a2d0426285648f71ce9323ca15George Mount            }
618e62545fdf58881a2d0426285648f71ce9323ca15George Mount            return anim;
619e62545fdf58881a2d0426285648f71ce9323ca15George Mount        }
620e62545fdf58881a2d0426285648f71ce9323ca15George Mount    }
621990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount}
622