1a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount/*
2a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * Copyright (C) 2015 The Android Open Source Project
3a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount *
4a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * Licensed under the Apache License, Version 2.0 (the "License");
5a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * you may not use this file except in compliance with the License.
6a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * You may obtain a copy of the License at
7a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount *
8a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount *      http://www.apache.org/licenses/LICENSE-2.0
9a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount *
10a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * Unless required by applicable law or agreed to in writing, software
11a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * distributed under the License is distributed on an "AS IS" BASIS,
12a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * See the License for the specific language governing permissions and
14a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount * limitations under the License.
15a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount */
16a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountpackage android.support.v4.app.test;
17a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
18a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.app.Activity;
192913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powellimport android.content.Context;
20a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnickimport android.content.Intent;
21a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.os.Build.VERSION;
22a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.os.Build.VERSION_CODES;
23a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.os.Bundle;
24a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.support.v4.app.Fragment;
25a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.support.v4.app.FragmentActivity;
26a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.support.v4.test.R;
27a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.transition.Transition;
28a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.transition.Transition.TransitionListener;
29a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.transition.TransitionInflater;
30a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.view.LayoutInflater;
31a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.view.View;
32a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.view.ViewGroup;
33a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
34a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mountimport java.util.concurrent.CountDownLatch;
35a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mountimport java.util.concurrent.TimeUnit;
36a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount
37a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount/**
382913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell * A simple activity used for Fragment Transitions and lifecycle event ordering
39a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount */
40a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountpublic class FragmentTestActivity extends FragmentActivity {
41a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    @Override
42a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    public void onCreate(Bundle icicle) {
43a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        super.onCreate(icicle);
44a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        setContentView(R.layout.activity_content);
45a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    }
46a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
47a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    public static class TestFragment extends Fragment {
48a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int ENTER = 0;
49a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int RETURN = 1;
50a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int EXIT = 2;
51a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int REENTER = 3;
52a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int SHARED_ELEMENT_ENTER = 4;
53a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int SHARED_ELEMENT_RETURN = 5;
54a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private static final int TRANSITION_COUNT = 6;
55a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
56a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private static final String LAYOUT_ID = "layoutId";
57a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private static final String TRANSITION_KEY = "transition_";
58a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private int mLayoutId = R.layout.fragment_start;
59a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private final int[] mTransitionIds = new int[] {
60a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
61a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
62a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
63a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
64a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.change_bounds,
65a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.change_bounds,
66a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        };
67a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        private final Object[] mListeners = new Object[TRANSITION_COUNT];
68a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
69a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public TestFragment() {
70a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
71a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                for (int i = 0; i < TRANSITION_COUNT; i++) {
72a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                    mListeners[i] = new TransitionCalledListener();
73a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                }
74a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
75a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
76a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
77a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static TestFragment create(int layoutId) {
78a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            TestFragment testFragment = new TestFragment();
79a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            testFragment.mLayoutId = layoutId;
80a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            return testFragment;
81a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
82a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
83a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void clearTransitions() {
84a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            for (int i = 0; i < TRANSITION_COUNT; i++) {
85a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                mTransitionIds[i] = 0;
86a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
87a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
88a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
89a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void clearNotifications() {
90a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            for (int i = 0; i < TRANSITION_COUNT; i++) {
91a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                ((TransitionCalledListener)mListeners[i]).startLatch = new CountDownLatch(1);
92a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                ((TransitionCalledListener)mListeners[i]).endLatch = new CountDownLatch(1);
93a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
94a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
95a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
96a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
97a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void onCreate(Bundle savedInstanceState) {
98a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            super.onCreate(savedInstanceState);
99a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            if (savedInstanceState != null) {
100a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                mLayoutId = savedInstanceState.getInt(LAYOUT_ID, mLayoutId);
101a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                for (int i = 0; i < TRANSITION_COUNT; i++) {
102a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                    String key = TRANSITION_KEY + i;
103a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                    mTransitionIds[i] = savedInstanceState.getInt(key, mTransitionIds[i]);
104a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                }
105a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
106a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
107a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
108a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
109a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void onSaveInstanceState(Bundle outState) {
110a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            super.onSaveInstanceState(outState);
111a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            outState.putInt(LAYOUT_ID, mLayoutId);
112a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            for (int i = 0; i < TRANSITION_COUNT; i++) {
113a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                String key = TRANSITION_KEY + i;
114a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                outState.putInt(key, mTransitionIds[i]);
115a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
116a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
117a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
118a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
119a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public View onCreateView(LayoutInflater inflater, ViewGroup container,
120a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                Bundle savedInstanceState) {
121a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            return inflater.inflate(mLayoutId, container, false);
122a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
123a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
124a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @SuppressWarnings("deprecation")
125a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
126a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void onAttach(Activity activity) {
127a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            super.onAttach(activity);
128a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            if (VERSION.SDK_INT > VERSION_CODES.KITKAT) {
129a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setEnterTransition(loadTransition(ENTER));
130a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setReenterTransition(loadTransition(REENTER));
131a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setExitTransition(loadTransition(EXIT));
132a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setReturnTransition(loadTransition(RETURN));
133a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setSharedElementEnterTransition(loadTransition(SHARED_ELEMENT_ENTER));
134a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setSharedElementReturnTransition(loadTransition(SHARED_ELEMENT_RETURN));
135a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
136a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
137a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
138a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public boolean wasStartCalled(int transitionKey) {
139a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return ((TransitionCalledListener)mListeners[transitionKey]).startLatch.getCount() == 0;
140a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
141a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
142a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public boolean wasEndCalled(int transitionKey) {
143a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return ((TransitionCalledListener)mListeners[transitionKey]).endLatch.getCount() == 0;
144a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        }
145a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount
146a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        public boolean waitForStart(int transitionKey)
147a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                throws InterruptedException {
148a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            TransitionCalledListener l = ((TransitionCalledListener)mListeners[transitionKey]);
149a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return l.startLatch.await(500,TimeUnit.MILLISECONDS);
150a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        }
151a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount
152a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        public boolean waitForEnd(int transitionKey)
153a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                throws InterruptedException {
154a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            TransitionCalledListener l = ((TransitionCalledListener)mListeners[transitionKey]);
155a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return l.endLatch.await(500,TimeUnit.MILLISECONDS);
156a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
157a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
158a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private Transition loadTransition(int key) {
159a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            final int id = mTransitionIds[key];
160a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            if (id == 0) {
161a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                return null;
162a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
163a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            Transition transition = TransitionInflater.from(getActivity()).inflateTransition(id);
164a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            transition.addListener(((TransitionCalledListener)mListeners[key]));
165a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            return transition;
166a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
167a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
168a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private class TransitionCalledListener implements TransitionListener {
169a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            public CountDownLatch startLatch = new CountDownLatch(1);
170a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            public CountDownLatch endLatch = new CountDownLatch(1);
171a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
172a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public TransitionCalledListener() {
173a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
174a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
175a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
176a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionStart(Transition transition) {
177a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                startLatch.countDown();
178a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
179a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
180a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
181a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionEnd(Transition transition) {
182a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                endLatch.countDown();
183a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
184a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
185a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
186a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionCancel(Transition transition) {
187a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
188a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
189a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
190a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionPause(Transition transition) {
191a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
192a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
193a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
194a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionResume(Transition transition) {
195a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
196a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
197a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    }
198a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
1992913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    public static class ParentFragment extends Fragment {
200c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        static final String CHILD_FRAGMENT_TAG = "childFragment";
2012913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public boolean wasAttachedInTime;
202c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
203c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        private boolean mRetainChild;
204a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick
2052913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        @Override
2062913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public void onCreate(Bundle savedInstanceState) {
2072913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell            super.onCreate(savedInstanceState);
208c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
209c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            ChildFragment f = getChildFragment();
210c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            if (f == null) {
211c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                f = new ChildFragment();
212c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                if (mRetainChild) {
213c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                    f.setRetainInstance(true);
214c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                }
215c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                getChildFragmentManager().beginTransaction().add(f, CHILD_FRAGMENT_TAG).commitNow();
216c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            }
217c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            wasAttachedInTime = f.attached;
218c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
219c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
220c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public ChildFragment getChildFragment() {
221c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            return (ChildFragment) getChildFragmentManager().findFragmentByTag(CHILD_FRAGMENT_TAG);
222c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
223c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
224c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public void setRetainChildInstance(boolean retainChild) {
225c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            mRetainChild = retainChild;
2262913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        }
2272913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    }
2282913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell
2292913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    public static class ChildFragment extends Fragment {
230c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        private OnAttachListener mOnAttachListener;
231c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
2322913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public boolean attached;
233a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public boolean onActivityResultCalled;
234a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public int onActivityResultRequestCode;
235a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public int onActivityResultResultCode;
236a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick
2372913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        @Override
2382913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public void onAttach(Context activity) {
2392913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell            super.onAttach(activity);
2402913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell            attached = true;
241c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            if (mOnAttachListener != null) {
242c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                mOnAttachListener.onAttach(activity, this);
243c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            }
244c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
245c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
246c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public void setOnAttachListener(OnAttachListener listener) {
247c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            mOnAttachListener = listener;
248c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
249c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
250c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public interface OnAttachListener {
251c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            void onAttach(Context activity, ChildFragment fragment);
2522913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        }
253a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick
254a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        @Override
255a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public void onActivityResult(int requestCode, int resultCode, Intent data) {
256a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick            onActivityResultCalled = true;
257a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick            onActivityResultRequestCode = requestCode;
258a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick            onActivityResultResultCode = resultCode;
259a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        }
2602913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    }
261a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount}
262