139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell/*
239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell * Copyright (C) 2016 The Android Open Source Project
339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell *
439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell * Licensed under the Apache License, Version 2.0 (the "License");
539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell * you may not use this file except in compliance with the License.
639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell * You may obtain a copy of the License at
739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell *
839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell *      http://www.apache.org/licenses/LICENSE-2.0
939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell *
1039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell * Unless required by applicable law or agreed to in writing, software
1139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell * distributed under the License is distributed on an "AS IS" BASIS,
1239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell * See the License for the specific language governing permissions and
1439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell * limitations under the License.
1539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell */
1639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
1739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
1839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powellpackage android.support.v4.app;
1939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
20fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powellimport android.content.Context;
219375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport android.content.Intent;
229375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport android.os.Bundle;
239375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport android.os.Parcelable;
249375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport android.support.annotation.NonNull;
259375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport android.support.annotation.Nullable;
269375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport android.support.test.annotation.UiThreadTest;
2739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powellimport android.support.test.rule.ActivityTestRule;
2839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powellimport android.support.test.runner.AndroidJUnit4;
2939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powellimport android.support.v4.app.test.EmptyFragmentTestActivity;
3096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mountimport android.support.v4.test.R;
3139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powellimport android.test.suitebuilder.annotation.MediumTest;
329375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport android.view.LayoutInflater;
3339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powellimport android.view.View;
3496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mountimport android.view.ViewGroup;
359375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport android.view.Window;
3696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
37fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powellimport android.widget.TextView;
3896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mountimport org.junit.Assert;
3939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powellimport org.junit.Rule;
4039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powellimport org.junit.Test;
4139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powellimport org.junit.runner.RunWith;
4239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
439375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport java.io.FileDescriptor;
449375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport java.io.PrintWriter;
459375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
4696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mountimport static junit.framework.Assert.assertEquals;
4796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mountimport static junit.framework.Assert.assertFalse;
4896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mountimport static junit.framework.Assert.assertNotNull;
4996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mountimport static junit.framework.Assert.assertNotSame;
5096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mountimport static junit.framework.Assert.assertNull;
5196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mountimport static junit.framework.Assert.assertSame;
5296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mountimport static junit.framework.Assert.assertTrue;
539375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powellimport static org.junit.Assert.assertNotEquals;
5439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
5539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell@RunWith(AndroidJUnit4.class)
569375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell@MediumTest
5739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powellpublic class FragmentLifecycleTest {
5839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
5939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    @Rule
6039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    public ActivityTestRule<EmptyFragmentTestActivity> mActivityRule =
6139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell            new ActivityTestRule<EmptyFragmentTestActivity>(EmptyFragmentTestActivity.class);
6239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
6339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    @Test
6439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    public void basicLifecycle() throws Throwable {
6539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
6639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final StrictFragment strictFragment = new StrictFragment();
6739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
6839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Add fragment; StrictFragment will throw if it detects any violation
6939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // in standard lifecycle method ordering or expected preconditions.
7039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().add(strictFragment, "EmptyHeadless").commit();
7139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
7239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
7339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment is not added", strictFragment.isAdded());
7439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment is detached", strictFragment.isDetached());
7539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment is not resumed", strictFragment.isResumed());
7639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
7739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Test removal as well; StrictFragment will throw here too.
7839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().remove(strictFragment).commit();
7939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
8039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
8139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment is added", strictFragment.isAdded());
8239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment is resumed", strictFragment.isResumed());
8339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
8439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // This one is perhaps counterintuitive; "detached" means specifically detached
8539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // but still managed by a FragmentManager. The .remove call above
8639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // should not enter this state.
8739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment is detached", strictFragment.isDetached());
8839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    }
8939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
9039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    @Test
9139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    public void detachment() throws Throwable {
9239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
9339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final StrictFragment f1 = new StrictFragment();
9439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final StrictFragment f2 = new StrictFragment();
9539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
9639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().add(f1, "1").add(f2, "2").commit();
9739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
9839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
9939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1 is not added", f1.isAdded());
10039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 2 is not added", f2.isAdded());
10139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
10239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Test detaching fragments using StrictFragment to throw on errors.
10339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().detach(f1).detach(f2).commit();
10439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
10539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
10639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1 is not detached", f1.isDetached());
10739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 2 is not detached", f2.isDetached());
10839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 1 is added", f1.isAdded());
10939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 2 is added", f2.isAdded());
11039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
11139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Only reattach f1; leave v2 detached.
11239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().attach(f1).commit();
11339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
11439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
11539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1 is not added", f1.isAdded());
11639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 1 is detached", f1.isDetached());
11739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 2 is not detached", f2.isDetached());
11839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
11939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Remove both from the FragmentManager.
12039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().remove(f1).remove(f2).commit();
12139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
12239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
12339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 1 is added", f1.isAdded());
12439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 2 is added", f2.isAdded());
12539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 1 is detached", f1.isDetached());
12639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 2 is detached", f2.isDetached());
12739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    }
12839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
12939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    @Test
13039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    public void basicBackStack() throws Throwable {
13139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
13239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final StrictFragment f1 = new StrictFragment();
13339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final StrictFragment f2 = new StrictFragment();
13439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
13539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Add a fragment normally to set up
13639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().add(f1, "1").commit();
13739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
13839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
13939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1 is not added", f1.isAdded());
14039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
14139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Remove the first one and add a second. We're not using replace() here since
14239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // these fragments are headless and as of this test writing, replace() only works
14339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // for fragments with views and a container view id.
14439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Add it to the back stack so we can pop it afterwards.
14539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().remove(f1).add(f2, "2").addToBackStack("stack1").commit();
14639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
14739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
14839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 1 is added", f1.isAdded());
14939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 2 is not added", f2.isAdded());
15039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
15139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Test popping the stack
15239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.popBackStack();
15339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
15439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
15539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 2 is added", f2.isAdded());
15639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1 is not added", f1.isAdded());
15739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    }
15839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
15939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    @Test
16039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    public void attachBackStack() throws Throwable {
16139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
16239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final StrictFragment f1 = new StrictFragment();
16339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final StrictFragment f2 = new StrictFragment();
16439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
16539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Add a fragment normally to set up
16639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().add(f1, "1").commit();
16739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
16839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
16939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1 is not added", f1.isAdded());
17039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
17139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().detach(f1).add(f2, "2").addToBackStack("stack1").commit();
17239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
17339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
17439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1 is not detached", f1.isDetached());
17539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 2 is detached", f2.isDetached());
17639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 1 is added", f1.isAdded());
17739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 2 is not added", f2.isAdded());
17839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    }
17939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
18039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    @Test
18139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    public void viewLifecycle() throws Throwable {
18239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Test basic lifecycle when the fragment creates a view
18339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
18439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
18539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final StrictViewFragment f1 = new StrictViewFragment();
18639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
18739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().add(android.R.id.content, f1).commit();
18839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
18939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
19039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1 is not added", f1.isAdded());
19139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final View view = f1.getView();
19239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertNotNull("fragment 1 returned null from getView", view);
19339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1's view is not attached to a window", view.isAttachedToWindow());
19439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
19539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().remove(f1).commit();
19639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
19739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
19839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 1 is added", f1.isAdded());
19939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertNull("fragment 1 returned non-null from getView after removal", f1.getView());
20039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 1's previous view is still attached to a window",
20139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell                view.isAttachedToWindow());
20239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    }
20339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
20439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    @Test
20539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    public void viewReplace() throws Throwable {
20639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        // Replace one view with another, then reverse it with the back stack
20739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
20839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
20939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final StrictViewFragment f1 = new StrictViewFragment();
21039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        final StrictViewFragment f2 = new StrictViewFragment();
21139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
21239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().add(android.R.id.content, f1).commit();
21339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
21439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
21539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1 is not added", f1.isAdded());
21639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
21739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        View origView1 = f1.getView();
21839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertNotNull("fragment 1 returned null view", origView1);
21939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1's view not attached", origView1.isAttachedToWindow());
22039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
22139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.beginTransaction().replace(android.R.id.content, f2).addToBackStack("stack1").commit();
22239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
22339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
22439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 1 is added", f1.isAdded());
22539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 2 is added", f2.isAdded());
22639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertNull("fragment 1 returned non-null view", f1.getView());
22739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 1's old view still attached", origView1.isAttachedToWindow());
22839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        View origView2 = f2.getView();
22939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertNotNull("fragment 2 returned null view", origView2);
23039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 2's view not attached", origView2.isAttachedToWindow());
23139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
23239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        fm.popBackStack();
23339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        executePendingTransactions(fm);
23439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
23539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1 is not added", f1.isAdded());
23639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 2 is added", f2.isAdded());
23739a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertNull("fragment 2 returned non-null view", f2.getView());
23839a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertFalse("fragment 2's view still attached", origView2.isAttachedToWindow());
23939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        View newView1 = f1.getView();
24039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertNotSame("fragment 1 had same view from last attachment", origView1, newView1);
24139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        assertTrue("fragment 1's view not attached", newView1.isAttachedToWindow());
24239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    }
24339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell
2449375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell    @Test
2459375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell    @UiThreadTest
2469375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell    public void restoreRetainedInstanceFragments() throws Throwable {
2479375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Create a new FragmentManager in isolation, nest some assorted fragments
2489375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // and then restore them to a second new FragmentManager.
2499375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
2509375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final FragmentController fc1 = FragmentController.createController(
2519375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                new HostCallbacks(mActivityRule.getActivity()));
2529375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
2539375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final FragmentManager fm1 = fc1.getSupportFragmentManager();
2549375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
2559375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.attachHost(null);
2569375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.dispatchCreate();
2579375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
2589375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Configure fragments.
2599375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
2609375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Grandparent fragment will not retain instance
2619375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final StateSaveFragment grandparentFragment = new StateSaveFragment("Grandparent",
2629375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                "UnsavedGrandparent");
2639375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotNull("grandparent fragment saved state not initialized",
2649375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                grandparentFragment.getSavedState());
2659375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotNull("grandparent fragment unsaved state not initialized",
2669375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                grandparentFragment.getUnsavedState());
2679375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fm1.beginTransaction().add(grandparentFragment, "tag:grandparent").commitNow();
2689375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
2699375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Parent fragment will retain instance
2709375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final StateSaveFragment parentFragment = new StateSaveFragment("Parent", "UnsavedParent");
2719375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotNull("parent fragment saved state not initialized",
2729375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                parentFragment.getSavedState());
2739375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotNull("parent fragment unsaved state not initialized",
2749375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                parentFragment.getUnsavedState());
2759375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        parentFragment.setRetainInstance(true);
2769375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        grandparentFragment.getChildFragmentManager().beginTransaction()
2779375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                .add(parentFragment, "tag:parent").commitNow();
2789375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertSame("parent fragment is not a child of grandparent",
2799375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                grandparentFragment, parentFragment.getParentFragment());
2809375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
2819375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Child fragment will not retain instance
2829375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final StateSaveFragment childFragment = new StateSaveFragment("Child", "UnsavedChild");
2839375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotNull("child fragment saved state not initialized",
2849375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                childFragment.getSavedState());
2859375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotNull("child fragment unsaved state not initialized",
2869375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                childFragment.getUnsavedState());
2879375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        parentFragment.getChildFragmentManager().beginTransaction()
2889375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                .add(childFragment, "tag:child").commitNow();
2899375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertSame("child fragment is not a child of grandpanret",
2909375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                parentFragment, childFragment.getParentFragment());
2919375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
2929375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Saved for comparison later
2939375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final FragmentManager parentChildFragmentManager = parentFragment.getChildFragmentManager();
2949375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
2959375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.dispatchActivityCreated();
2969375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.noteStateNotSaved();
2979375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.execPendingActions();
2989375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.doLoaderStart();
2999375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.dispatchStart();
3009375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.reportLoaderStart();
3019375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.dispatchResume();
3029375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.execPendingActions();
3039375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3049375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Bring the state back down to destroyed, simulating an activity restart
3059375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.dispatchPause();
3069375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final Parcelable savedState = fc1.saveAllState();
3079375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final FragmentManagerNonConfig nonconf = fc1.retainNestedNonConfig();
3089375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.dispatchStop();
3099375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.dispatchReallyStop();
3109375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc1.dispatchDestroy();
3119375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3129375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Create the new controller and restore state
3139375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final FragmentController fc2 = FragmentController.createController(
3149375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                new HostCallbacks(mActivityRule.getActivity()));
3159375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3169375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final FragmentManager fm2 = fc2.getSupportFragmentManager();
3179375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3189375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.attachHost(null);
3199375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.restoreAllState(savedState, nonconf);
3209375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.dispatchCreate();
3219375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3229375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Confirm that the restored fragments are available and in the expected states
3239375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final StateSaveFragment restoredGrandparent = (StateSaveFragment) fm2.findFragmentByTag(
3249375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                "tag:grandparent");
3259375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotNull("grandparent fragment not restored", restoredGrandparent);
3269375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3279375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotSame("grandparent fragment instance was saved",
3289375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                grandparentFragment, restoredGrandparent);
3299375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertEquals("grandparent fragment saved state was not equal",
3309375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                grandparentFragment.getSavedState(), restoredGrandparent.getSavedState());
3319375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotEquals("grandparent fragment unsaved state was unexpectedly preserved",
3329375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                grandparentFragment.getUnsavedState(), restoredGrandparent.getUnsavedState());
3339375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3349375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final StateSaveFragment restoredParent = (StateSaveFragment) restoredGrandparent
3359375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                .getChildFragmentManager().findFragmentByTag("tag:parent");
3369375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotNull("parent fragment not restored", restoredParent);
3379375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3389375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertSame("parent fragment instance was not saved", parentFragment, restoredParent);
3399375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertEquals("parent fragment saved state was not equal",
3409375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                parentFragment.getSavedState(), restoredParent.getSavedState());
3419375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertEquals("parent fragment unsaved state was not equal",
3429375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                parentFragment.getUnsavedState(), restoredParent.getUnsavedState());
3439375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotSame("parent fragment has the same child FragmentManager",
3449375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                parentChildFragmentManager, restoredParent.getChildFragmentManager());
3459375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3469375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        final StateSaveFragment restoredChild = (StateSaveFragment) restoredParent
3479375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                .getChildFragmentManager().findFragmentByTag("tag:child");
3489375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotNull("child fragment not restored", restoredChild);
3499375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3509375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotSame("child fragment instance state was saved", childFragment, restoredChild);
3519375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertEquals("child fragment saved state was not equal",
3529375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                childFragment.getSavedState(), restoredChild.getSavedState());
3539375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        assertNotEquals("child fragment saved state was unexpectedly equal",
3549375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                childFragment.getUnsavedState(), restoredChild.getUnsavedState());
3559375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3569375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.dispatchActivityCreated();
3579375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.noteStateNotSaved();
3589375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.execPendingActions();
3599375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.doLoaderStart();
3609375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.dispatchStart();
3619375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.reportLoaderStart();
3629375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.dispatchResume();
3639375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.execPendingActions();
3649375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3659375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Test that the fragments are in the configuration we expect
3669375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
3679375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        // Bring the state back down to destroyed before we finish the test
3689375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.dispatchPause();
3699375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.saveAllState();
3709375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.dispatchStop();
3719375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.dispatchReallyStop();
3729375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        fc2.dispatchDestroy();
373c917e2acb716bd2dea2a31ce712f3ab9d764ee83Adam Powell
374c917e2acb716bd2dea2a31ce712f3ab9d764ee83Adam Powell        assertTrue("grandparent not destroyed", restoredGrandparent.mCalledOnDestroy);
375c917e2acb716bd2dea2a31ce712f3ab9d764ee83Adam Powell        assertTrue("parent not destroyed", restoredParent.mCalledOnDestroy);
376c917e2acb716bd2dea2a31ce712f3ab9d764ee83Adam Powell        assertTrue("child not destroyed", restoredChild.mCalledOnDestroy);
3779375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell    }
3789375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
37996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    @Test
38096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    @UiThreadTest
38196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    public void saveAnimationState() throws Throwable {
38296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        FragmentController fc = startupFragmentController(null);
38396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        FragmentManager fm = fc.getSupportFragmentManager();
38496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
38596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fm.beginTransaction()
38696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                .setCustomAnimations(0, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out)
38796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                .add(android.R.id.content, SimpleFragment.create(R.layout.fragment_a))
38896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                .addToBackStack(null)
38996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                .commit();
39096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fm.executePendingTransactions();
39196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
39296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        assertAnimationsMatch(fm, 0, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out);
39396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
39496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        // Causes save and restore of fragments and back stack
39596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc = restartFragmentController(fc);
39696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fm = fc.getSupportFragmentManager();
39796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
39896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        assertAnimationsMatch(fm, 0, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out);
39996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
40096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fm.beginTransaction()
40196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                .setCustomAnimations(R.anim.fade_in, R.anim.fade_out, 0, 0)
40296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                .replace(android.R.id.content, SimpleFragment.create(R.layout.fragment_b))
40396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                .addToBackStack(null)
40496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                .commit();
40596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fm.executePendingTransactions();
40696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
40796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        assertAnimationsMatch(fm, R.anim.fade_in, R.anim.fade_out, 0, 0);
40896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
40996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        // Causes save and restore of fragments and back stack
41096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc = restartFragmentController(fc);
41196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fm = fc.getSupportFragmentManager();
41296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
41396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        assertAnimationsMatch(fm, R.anim.fade_in, R.anim.fade_out, 0, 0);
41496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
41596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fm.popBackStackImmediate();
41696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
41796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        assertAnimationsMatch(fm, 0, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out);
41896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
41996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        shutdownFragmentController(fc);
42096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    }
42196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
422fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell    /**
423fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell     * This test confirms that as long as a parent fragment has called super.onCreate,
424fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell     * any child fragments added, committed and with transactions executed will be brought
425fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell     * to at least the CREATED state by the time the parent fragment receives onCreateView.
426fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell     * This means the child fragment will have received onAttach/onCreate.
427fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell     */
428fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell    @Test
429fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell    @UiThreadTest
430fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell    public void childFragmentManagerAttach() throws Throwable {
431fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        FragmentController fc = FragmentController.createController(
432fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell                new HostCallbacks(mActivityRule.getActivity()));
433fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        fc.attachHost(null);
434fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        fc.dispatchCreate();
435fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
436fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        FragmentManager fm = fc.getSupportFragmentManager();
437fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
438cef09fee2126f901aa164f6e89c370ab81cff1b3Adam Powell        ChildFragmentManagerFragment fragment = new ChildFragmentManagerFragment();
439fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        fm.beginTransaction()
440cef09fee2126f901aa164f6e89c370ab81cff1b3Adam Powell                .add(android.R.id.content, fragment)
441fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell                .commitNow();
442fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
443fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        fc.dispatchActivityCreated();
444fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
445fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        fc.dispatchStart();
446fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        fc.dispatchResume();
447cef09fee2126f901aa164f6e89c370ab81cff1b3Adam Powell
448cef09fee2126f901aa164f6e89c370ab81cff1b3Adam Powell        // Confirm that the parent fragment received onAttachFragment
449cef09fee2126f901aa164f6e89c370ab81cff1b3Adam Powell        assertTrue("parent fragment did not receive onAttachFragment",
450cef09fee2126f901aa164f6e89c370ab81cff1b3Adam Powell                fragment.mCalledOnAttachFragment);
451cef09fee2126f901aa164f6e89c370ab81cff1b3Adam Powell
452fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        fc.dispatchStop();
453fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        fc.dispatchReallyStop();
454fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        fc.dispatchDestroy();
455fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell    }
456fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
45796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    private void assertAnimationsMatch(FragmentManager fm, int enter, int exit, int popEnter,
45896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount            int popExit) {
45996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        FragmentManagerImpl fmImpl = (FragmentManagerImpl) fm;
46096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        BackStackRecord record = fmImpl.mBackStack.get(fmImpl.mBackStack.size() - 1);
46196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
46296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        Assert.assertEquals(enter, record.mEnterAnim);
46396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        Assert.assertEquals(exit, record.mExitAnim);
46496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        Assert.assertEquals(popEnter, record.mPopEnterAnim);
46596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        Assert.assertEquals(popExit, record.mPopExitAnim);
46696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    }
46796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
46896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    private FragmentController restartFragmentController(FragmentController fc) {
46996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        Parcelable savedState = shutdownFragmentController(fc);
47096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        return startupFragmentController(savedState);
47196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    }
47296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
47396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    private FragmentController startupFragmentController(Parcelable savedState) {
47496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        final FragmentController fc = FragmentController.createController(
47596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                new HostCallbacks(mActivityRule.getActivity()));
47696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.attachHost(null);
47796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.restoreAllState(savedState, (FragmentManagerNonConfig) null);
47896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.dispatchCreate();
47996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.dispatchActivityCreated();
48096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.noteStateNotSaved();
48196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.execPendingActions();
48296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.doLoaderStart();
48396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.dispatchStart();
48496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.reportLoaderStart();
48596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.dispatchResume();
48696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.execPendingActions();
48796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        return fc;
48896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    }
48996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
49096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    private Parcelable shutdownFragmentController(FragmentController fc) {
49196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.dispatchPause();
49296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        final Parcelable savedState = fc.saveAllState();
49396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.dispatchStop();
49496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.dispatchReallyStop();
49596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        fc.dispatchDestroy();
49696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        return savedState;
49796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    }
49896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
49939a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    private void executePendingTransactions(final FragmentManager fm) throws Throwable {
50039a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        mActivityRule.runOnUiThread(new Runnable() {
50139a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell            @Override
50239a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell            public void run() {
50339a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell                fm.executePendingTransactions();
50439a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell            }
50539a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell        });
50639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell    }
5079375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
5089375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell    public static class StateSaveFragment extends StrictFragment {
5099375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        private static final String STATE_KEY = "state";
5109375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
5119375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        private String mSavedState;
5129375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        private String mUnsavedState;
5139375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
5149375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public StateSaveFragment() {
5159375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
5169375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
5179375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public StateSaveFragment(String savedState, String unsavedState) {
5189375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            mSavedState = savedState;
5199375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            mUnsavedState = unsavedState;
5209375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
5219375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
5229375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public String getSavedState() {
5239375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            return mSavedState;
5249375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
5259375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
5269375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public String getUnsavedState() {
5279375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            return mUnsavedState;
5289375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
5299375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
5309375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
5319375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public void onCreate(Bundle savedInstanceState) {
5329375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            super.onCreate(savedInstanceState);
5339375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            if (savedInstanceState != null) {
5349375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                mSavedState = savedInstanceState.getString(STATE_KEY);
5359375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            }
5369375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
5379375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
5389375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
5399375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public void onSaveInstanceState(Bundle outState) {
5409375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            super.onSaveInstanceState(outState);
5419375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            outState.putString(STATE_KEY, mSavedState);
5429375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
5439375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell    }
5449375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
545fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell    public static class ChildFragmentManagerFragment extends StrictFragment {
546fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        private FragmentManager mSavedChildFragmentManager;
547fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
548fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        @Override
549fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        public void onAttach(Context context) {
550fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            super.onAttach(context);
551fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            mSavedChildFragmentManager = getChildFragmentManager();
552fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        }
553fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
554fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        @Nullable
555fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        @Override
556fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
557fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell                @Nullable Bundle savedInstanceState) {
558fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            assertSame("child FragmentManagers not the same instance", mSavedChildFragmentManager,
559fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell                    getChildFragmentManager());
560fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            ChildFragmentManagerChildFragment child = new ChildFragmentManagerChildFragment("foo");
561fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            mSavedChildFragmentManager.beginTransaction()
562fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell                    .add(child, "tag")
563fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell                    .commitNow();
564fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            assertEquals("argument strings don't match", "foo", child.getString());
565fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            return new TextView(container.getContext());
566fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        }
567fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell    }
568fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
569fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell    public static class ChildFragmentManagerChildFragment extends StrictFragment {
570fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        private String mString;
571fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
572fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        public ChildFragmentManagerChildFragment() {
573fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        }
574fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
575fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        public ChildFragmentManagerChildFragment(String arg) {
576fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            final Bundle b = new Bundle();
577fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            b.putString("string", arg);
578fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            setArguments(b);
579fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        }
580fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
581fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        @Override
582fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        public void onAttach(Context context) {
583fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            super.onAttach(context);
584fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            mString = getArguments().getString("string", "NO VALUE");
585fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        }
586fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
587fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        public String getString() {
588fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell            return mString;
589fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell        }
590fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell    }
591fd15fbacc1d0cb92f2edf72137e4940be2547aa4Adam Powell
5929375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell    static class HostCallbacks extends FragmentHostCallback<FragmentActivity> {
5939375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        private final FragmentActivity mActivity;
5949375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
5959375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public HostCallbacks(FragmentActivity activity) {
5969375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            super(activity);
5979375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            mActivity = activity;
5989375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
5999375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6009375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6019375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public void onDump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
6029375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6039375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6049375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6059375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public boolean onShouldSaveFragmentState(Fragment fragment) {
6069375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            return !mActivity.isFinishing();
6079375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6089375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6099375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6109375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public LayoutInflater onGetLayoutInflater() {
6119375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            return mActivity.getLayoutInflater().cloneInContext(mActivity);
6129375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6139375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6149375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6159375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public FragmentActivity onGetHost() {
6169375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            return mActivity;
6179375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6189375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6199375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6209375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public void onSupportInvalidateOptionsMenu() {
6219375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            mActivity.supportInvalidateOptionsMenu();
6229375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6239375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6249375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6259375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public void onStartActivityFromFragment(Fragment fragment, Intent intent, int requestCode) {
6269375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            mActivity.startActivityFromFragment(fragment, intent, requestCode);
6279375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6289375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6299375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6309375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public void onStartActivityFromFragment(
6319375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                Fragment fragment, Intent intent, int requestCode, @Nullable Bundle options) {
6329375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            mActivity.startActivityFromFragment(fragment, intent, requestCode, options);
6339375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6349375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6359375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6369375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public void onRequestPermissionsFromFragment(@NonNull Fragment fragment,
6379375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                @NonNull String[] permissions, int requestCode) {
6389375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            throw new UnsupportedOperationException();
6399375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6409375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6419375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6429375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public boolean onShouldShowRequestPermissionRationale(@NonNull String permission) {
6439375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            return ActivityCompat.shouldShowRequestPermissionRationale(
6449375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell                    mActivity, permission);
6459375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6469375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6479375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6489375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public boolean onHasWindowAnimations() {
6499375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            return mActivity.getWindow() != null;
6509375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6519375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6529375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6539375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public int onGetWindowAnimations() {
6549375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            final Window w = mActivity.getWindow();
6559375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            return (w == null) ? 0 : w.getAttributes().windowAnimations;
6569375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6579375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6589375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6599375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public void onAttachFragment(Fragment fragment) {
6609375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            mActivity.onAttachFragment(fragment);
6619375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6629375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6639375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Nullable
6649375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6659375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public View onFindViewById(int id) {
6669375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            return mActivity.findViewById(id);
6679375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6689375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell
6699375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        @Override
6709375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        public boolean onHasView() {
6719375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            final Window w = mActivity.getWindow();
6729375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell            return (w != null && w.peekDecorView() != null);
6739375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell        }
6749375145b63d854c64aad99e6e50c5b7e5ba32b95Adam Powell    }
67596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
67696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    public static class SimpleFragment extends Fragment {
67796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        private int mLayoutId;
67896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        private static final String LAYOUT_ID = "layoutId";
67996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
68096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        @Override
68196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        public void onCreate(Bundle savedInstanceState) {
68296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount            super.onCreate(savedInstanceState);
68396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount            if (savedInstanceState != null) {
68496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                mLayoutId = savedInstanceState.getInt(LAYOUT_ID, mLayoutId);
68596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount            }
68696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        }
68796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
68896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        @Override
68996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        public void onSaveInstanceState(Bundle outState) {
69096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount            super.onSaveInstanceState(outState);
69196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount            outState.putInt(LAYOUT_ID, mLayoutId);
69296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        }
69396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
69496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        @Override
69596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        public View onCreateView(LayoutInflater inflater, ViewGroup container,
69696cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount                Bundle savedInstanceState) {
69796cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount            return inflater.inflate(mLayoutId, container, false);
69896cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        }
69996cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount
70096cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        public static SimpleFragment create(int layoutId) {
70196cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount            SimpleFragment fragment = new SimpleFragment();
70296cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount            fragment.mLayoutId = layoutId;
70396cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount            return fragment;
70496cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount        }
70596cd95c37930d6d8f79ee8068991f9686c884f7aGeorge Mount    }
70639a21dcc947992baaa700181c08fbe8bb8f077d6Adam Powell}
707