1a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount/*
2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 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 */
16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.fragment.app.test;
17a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
18eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mountimport static org.junit.Assert.assertFalse;
19eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount
20a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.app.Activity;
212913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powellimport android.content.Context;
22a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnickimport android.content.Intent;
23a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.os.Build.VERSION;
24a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.os.Build.VERSION_CODES;
25a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.os.Bundle;
26a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.transition.Transition;
27a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.transition.Transition.TransitionListener;
28a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.transition.TransitionInflater;
29a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.view.LayoutInflater;
30a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.view.View;
31a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountimport android.view.ViewGroup;
32a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
33320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.annotation.Nullable;
34320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.fragment.app.Fragment;
35320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.fragment.app.FragmentActivity;
36320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikasimport androidx.fragment.test.R;
37320113721c2e14bbc2403809046fa2959a665c11Aurimas Liutikas
38a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mountimport java.util.concurrent.CountDownLatch;
39a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mountimport java.util.concurrent.TimeUnit;
40a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount
41a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount/**
422913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell * A simple activity used for Fragment Transitions and lifecycle event ordering
43a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount */
44a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mountpublic class FragmentTestActivity extends FragmentActivity {
45eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    public final CountDownLatch onDestroyLatch = new CountDownLatch(1);
46eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount
47a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    @Override
48a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    public void onCreate(Bundle icicle) {
49a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        super.onCreate(icicle);
50a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        setContentView(R.layout.activity_content);
51eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        Intent intent = getIntent();
52eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        if (intent != null && intent.getBooleanExtra("finishEarly", false)) {
53eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount            finish();
54eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount            getSupportFragmentManager().beginTransaction()
55eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount                    .add(new AssertNotDestroyed(), "not destroyed")
56eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount                    .commit();
57eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        }
58eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    }
59eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount
60eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    @Override
61eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    protected void onDestroy() {
62eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        super.onDestroy();
63eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        onDestroyLatch.countDown();
64a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    }
65a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
66a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    public static class TestFragment extends Fragment {
67a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int ENTER = 0;
68a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int RETURN = 1;
69a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int EXIT = 2;
70a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int REENTER = 3;
71a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int SHARED_ELEMENT_ENTER = 4;
72a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static final int SHARED_ELEMENT_RETURN = 5;
73a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private static final int TRANSITION_COUNT = 6;
74a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
75a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private static final String LAYOUT_ID = "layoutId";
76a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private static final String TRANSITION_KEY = "transition_";
77a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private int mLayoutId = R.layout.fragment_start;
78a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private final int[] mTransitionIds = new int[] {
79a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
80a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
81a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
82a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.fade,
83a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.change_bounds,
84a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                R.transition.change_bounds,
85a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        };
86a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        private final Object[] mListeners = new Object[TRANSITION_COUNT];
87a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
88a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public TestFragment() {
89a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
90a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                for (int i = 0; i < TRANSITION_COUNT; i++) {
91a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                    mListeners[i] = new TransitionCalledListener();
92a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                }
93a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
94a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
95a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
96a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public static TestFragment create(int layoutId) {
97a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            TestFragment testFragment = new TestFragment();
98a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            testFragment.mLayoutId = layoutId;
99a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            return testFragment;
100a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
101a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
102a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void clearTransitions() {
103a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            for (int i = 0; i < TRANSITION_COUNT; i++) {
104a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                mTransitionIds[i] = 0;
105a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
106a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
107a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
108a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void clearNotifications() {
109a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            for (int i = 0; i < TRANSITION_COUNT; i++) {
110a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                ((TransitionCalledListener)mListeners[i]).startLatch = new CountDownLatch(1);
111a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                ((TransitionCalledListener)mListeners[i]).endLatch = new CountDownLatch(1);
112a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
113a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
114a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
115a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
116a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void onCreate(Bundle savedInstanceState) {
117a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            super.onCreate(savedInstanceState);
118a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            if (savedInstanceState != null) {
119a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                mLayoutId = savedInstanceState.getInt(LAYOUT_ID, mLayoutId);
120a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                for (int i = 0; i < TRANSITION_COUNT; i++) {
121a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                    String key = TRANSITION_KEY + i;
122a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                    mTransitionIds[i] = savedInstanceState.getInt(key, mTransitionIds[i]);
123a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                }
124a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
125a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
126a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
127a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
128a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void onSaveInstanceState(Bundle outState) {
129a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            super.onSaveInstanceState(outState);
130a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            outState.putInt(LAYOUT_ID, mLayoutId);
131a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            for (int i = 0; i < TRANSITION_COUNT; i++) {
132a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                String key = TRANSITION_KEY + i;
133a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                outState.putInt(key, mTransitionIds[i]);
134a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
135a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
136a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
137a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
138a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public View onCreateView(LayoutInflater inflater, ViewGroup container,
139a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                Bundle savedInstanceState) {
140a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            return inflater.inflate(mLayoutId, container, false);
141a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
142a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
143a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @SuppressWarnings("deprecation")
144a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        @Override
145a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public void onAttach(Activity activity) {
146a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            super.onAttach(activity);
147a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            if (VERSION.SDK_INT > VERSION_CODES.KITKAT) {
148a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setEnterTransition(loadTransition(ENTER));
149a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setReenterTransition(loadTransition(REENTER));
150a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setExitTransition(loadTransition(EXIT));
151a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setReturnTransition(loadTransition(RETURN));
152a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setSharedElementEnterTransition(loadTransition(SHARED_ELEMENT_ENTER));
153a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                setSharedElementReturnTransition(loadTransition(SHARED_ELEMENT_RETURN));
154a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
155a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
156a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
157a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public boolean wasStartCalled(int transitionKey) {
158a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return ((TransitionCalledListener)mListeners[transitionKey]).startLatch.getCount() == 0;
159a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
160a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
161a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        public boolean wasEndCalled(int transitionKey) {
162a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return ((TransitionCalledListener)mListeners[transitionKey]).endLatch.getCount() == 0;
163a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        }
164a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount
165a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        public boolean waitForStart(int transitionKey)
166a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                throws InterruptedException {
167a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            TransitionCalledListener l = ((TransitionCalledListener)mListeners[transitionKey]);
168a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return l.startLatch.await(500,TimeUnit.MILLISECONDS);
169a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        }
170a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount
171a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount        public boolean waitForEnd(int transitionKey)
172a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                throws InterruptedException {
173a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            TransitionCalledListener l = ((TransitionCalledListener)mListeners[transitionKey]);
174a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            return l.endLatch.await(500,TimeUnit.MILLISECONDS);
175a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
176a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
177a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private Transition loadTransition(int key) {
178a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            final int id = mTransitionIds[key];
179a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            if (id == 0) {
180a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount                return null;
181a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
182a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            Transition transition = TransitionInflater.from(getActivity()).inflateTransition(id);
183a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            transition.addListener(((TransitionCalledListener)mListeners[key]));
184a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            return transition;
185a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
186a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
187a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        private class TransitionCalledListener implements TransitionListener {
188a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            public CountDownLatch startLatch = new CountDownLatch(1);
189a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount            public CountDownLatch endLatch = new CountDownLatch(1);
190a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
191a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public TransitionCalledListener() {
192a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
193a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
194a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
195a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionStart(Transition transition) {
196a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                startLatch.countDown();
197a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
198a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
199a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
200a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionEnd(Transition transition) {
201a0926f64b419cfd95b7d092f7bd6bee818ccc7e1George Mount                endLatch.countDown();
202a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
203a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
204a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
205a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionCancel(Transition transition) {
206a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
207a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
208a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
209a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionPause(Transition transition) {
210a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
211a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
212a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            @Override
213a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            public void onTransitionResume(Transition transition) {
214a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount            }
215a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount        }
216a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount    }
217a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount
2182913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    public static class ParentFragment extends Fragment {
219c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        static final String CHILD_FRAGMENT_TAG = "childFragment";
2202913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public boolean wasAttachedInTime;
221c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
222c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        private boolean mRetainChild;
223a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick
2242913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        @Override
2252913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public void onCreate(Bundle savedInstanceState) {
2262913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell            super.onCreate(savedInstanceState);
227c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
228c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            ChildFragment f = getChildFragment();
229c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            if (f == null) {
230c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                f = new ChildFragment();
231c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                if (mRetainChild) {
232c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                    f.setRetainInstance(true);
233c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                }
234c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                getChildFragmentManager().beginTransaction().add(f, CHILD_FRAGMENT_TAG).commitNow();
235c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            }
236c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            wasAttachedInTime = f.attached;
237c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
238c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
239c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public ChildFragment getChildFragment() {
240c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            return (ChildFragment) getChildFragmentManager().findFragmentByTag(CHILD_FRAGMENT_TAG);
241c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
242c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
243c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public void setRetainChildInstance(boolean retainChild) {
244c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            mRetainChild = retainChild;
2452913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        }
2462913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    }
2472913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell
2482913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    public static class ChildFragment extends Fragment {
249c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        private OnAttachListener mOnAttachListener;
250c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
2512913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public boolean attached;
252a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public boolean onActivityResultCalled;
253a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public int onActivityResultRequestCode;
254a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public int onActivityResultResultCode;
255a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick
2562913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        @Override
2572913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        public void onAttach(Context activity) {
2582913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell            super.onAttach(activity);
2592913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell            attached = true;
260c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            if (mOnAttachListener != null) {
261c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell                mOnAttachListener.onAttach(activity, this);
262c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            }
263c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
264c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
265c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public void setOnAttachListener(OnAttachListener listener) {
266c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            mOnAttachListener = listener;
267c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        }
268c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell
269c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell        public interface OnAttachListener {
270c077b4cd990a9f220a27ad5eca04828e17136064Adam Powell            void onAttach(Context activity, ChildFragment fragment);
2712913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell        }
272a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick
273a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        @Override
274a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        public void onActivityResult(int requestCode, int resultCode, Intent data) {
275a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick            onActivityResultCalled = true;
276a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick            onActivityResultRequestCode = requestCode;
277a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick            onActivityResultResultCode = resultCode;
278a76a4339be2f27431a167381187c3f0b0d08f1b7Daniel Resnick        }
2792913b112d6089ea3e7ebe4a807394dd99f3ebc0fAdam Powell    }
280eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount
281eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    public static class AssertNotDestroyed extends Fragment {
282eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        @Override
283eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
284eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount            super.onActivityCreated(savedInstanceState);
285eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount            if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) {
286eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount                assertFalse(getActivity().isDestroyed());
287eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount            }
288eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount        }
289eb87508275fbb5d9bbce0d363a0de2f913b116dfGeorge Mount    }
290a1f95ec10cc7e88dcc1c57c92ac5d0c37c2d9553George Mount}
291