Fragment.java revision d3892caf95ce77c5e3c33a1f51d5ccbd7f313ccd
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import android.animation.Animator;
20import android.annotation.CallSuper;
21import android.annotation.NonNull;
22import android.annotation.Nullable;
23import android.annotation.StringRes;
24import android.content.ComponentCallbacks2;
25import android.content.Context;
26import android.content.Intent;
27import android.content.IntentSender;
28import android.content.res.Configuration;
29import android.content.res.Resources;
30import android.content.res.TypedArray;
31import android.os.Build;
32import android.os.Build.VERSION_CODES;
33import android.os.Bundle;
34import android.os.Looper;
35import android.os.Parcel;
36import android.os.Parcelable;
37import android.os.UserHandle;
38import android.transition.Transition;
39import android.transition.TransitionInflater;
40import android.transition.TransitionSet;
41import android.util.AndroidRuntimeException;
42import android.util.ArrayMap;
43import android.util.AttributeSet;
44import android.util.DebugUtils;
45import android.util.Log;
46import android.util.SparseArray;
47import android.util.SuperNotCalledException;
48import android.view.ContextMenu;
49import android.view.ContextMenu.ContextMenuInfo;
50import android.view.LayoutInflater;
51import android.view.Menu;
52import android.view.MenuInflater;
53import android.view.MenuItem;
54import android.view.View;
55import android.view.View.OnCreateContextMenuListener;
56import android.view.ViewGroup;
57import android.widget.AdapterView;
58
59import java.io.FileDescriptor;
60import java.io.PrintWriter;
61import java.lang.reflect.InvocationTargetException;
62
63final class FragmentState implements Parcelable {
64    final String mClassName;
65    final int mIndex;
66    final boolean mFromLayout;
67    final int mFragmentId;
68    final int mContainerId;
69    final String mTag;
70    final boolean mRetainInstance;
71    final boolean mDetached;
72    final Bundle mArguments;
73    final boolean mHidden;
74
75    Bundle mSavedFragmentState;
76
77    Fragment mInstance;
78
79    public FragmentState(Fragment frag) {
80        mClassName = frag.getClass().getName();
81        mIndex = frag.mIndex;
82        mFromLayout = frag.mFromLayout;
83        mFragmentId = frag.mFragmentId;
84        mContainerId = frag.mContainerId;
85        mTag = frag.mTag;
86        mRetainInstance = frag.mRetainInstance;
87        mDetached = frag.mDetached;
88        mArguments = frag.mArguments;
89        mHidden = frag.mHidden;
90    }
91
92    public FragmentState(Parcel in) {
93        mClassName = in.readString();
94        mIndex = in.readInt();
95        mFromLayout = in.readInt() != 0;
96        mFragmentId = in.readInt();
97        mContainerId = in.readInt();
98        mTag = in.readString();
99        mRetainInstance = in.readInt() != 0;
100        mDetached = in.readInt() != 0;
101        mArguments = in.readBundle();
102        mHidden = in.readInt() != 0;
103        mSavedFragmentState = in.readBundle();
104    }
105
106    public Fragment instantiate(FragmentHostCallback host, FragmentContainer container,
107            Fragment parent, FragmentManagerNonConfig childNonConfig) {
108        if (mInstance == null) {
109            final Context context = host.getContext();
110            if (mArguments != null) {
111                mArguments.setClassLoader(context.getClassLoader());
112            }
113
114            if (container != null) {
115                mInstance = container.instantiate(context, mClassName, mArguments);
116            } else {
117                mInstance = Fragment.instantiate(context, mClassName, mArguments);
118            }
119
120            if (mSavedFragmentState != null) {
121                mSavedFragmentState.setClassLoader(context.getClassLoader());
122                mInstance.mSavedFragmentState = mSavedFragmentState;
123            }
124            mInstance.setIndex(mIndex, parent);
125            mInstance.mFromLayout = mFromLayout;
126            mInstance.mRestored = true;
127            mInstance.mFragmentId = mFragmentId;
128            mInstance.mContainerId = mContainerId;
129            mInstance.mTag = mTag;
130            mInstance.mRetainInstance = mRetainInstance;
131            mInstance.mDetached = mDetached;
132            mInstance.mHidden = mHidden;
133            mInstance.mFragmentManager = host.mFragmentManager;
134            if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
135                    "Instantiated fragment " + mInstance);
136        }
137        mInstance.mChildNonConfig = childNonConfig;
138        return mInstance;
139    }
140
141    public int describeContents() {
142        return 0;
143    }
144
145    public void writeToParcel(Parcel dest, int flags) {
146        dest.writeString(mClassName);
147        dest.writeInt(mIndex);
148        dest.writeInt(mFromLayout ? 1 : 0);
149        dest.writeInt(mFragmentId);
150        dest.writeInt(mContainerId);
151        dest.writeString(mTag);
152        dest.writeInt(mRetainInstance ? 1 : 0);
153        dest.writeInt(mDetached ? 1 : 0);
154        dest.writeBundle(mArguments);
155        dest.writeInt(mHidden ? 1 : 0);
156        dest.writeBundle(mSavedFragmentState);
157    }
158
159    public static final Parcelable.Creator<FragmentState> CREATOR
160            = new Parcelable.Creator<FragmentState>() {
161        public FragmentState createFromParcel(Parcel in) {
162            return new FragmentState(in);
163        }
164
165        public FragmentState[] newArray(int size) {
166            return new FragmentState[size];
167        }
168    };
169}
170
171/**
172 * A Fragment is a piece of an application's user interface or behavior
173 * that can be placed in an {@link Activity}.  Interaction with fragments
174 * is done through {@link FragmentManager}, which can be obtained via
175 * {@link Activity#getFragmentManager() Activity.getFragmentManager()} and
176 * {@link Fragment#getFragmentManager() Fragment.getFragmentManager()}.
177 *
178 * <p>The Fragment class can be used many ways to achieve a wide variety of
179 * results. In its core, it represents a particular operation or interface
180 * that is running within a larger {@link Activity}.  A Fragment is closely
181 * tied to the Activity it is in, and can not be used apart from one.  Though
182 * Fragment defines its own lifecycle, that lifecycle is dependent on its
183 * activity: if the activity is stopped, no fragments inside of it can be
184 * started; when the activity is destroyed, all fragments will be destroyed.
185 *
186 * <p>All subclasses of Fragment must include a public no-argument constructor.
187 * The framework will often re-instantiate a fragment class when needed,
188 * in particular during state restore, and needs to be able to find this
189 * constructor to instantiate it.  If the no-argument constructor is not
190 * available, a runtime exception will occur in some cases during state
191 * restore.
192 *
193 * <p>Topics covered here:
194 * <ol>
195 * <li><a href="#OlderPlatforms">Older Platforms</a>
196 * <li><a href="#Lifecycle">Lifecycle</a>
197 * <li><a href="#Layout">Layout</a>
198 * <li><a href="#BackStack">Back Stack</a>
199 * </ol>
200 *
201 * <div class="special reference">
202 * <h3>Developer Guides</h3>
203 * <p>For more information about using fragments, read the
204 * <a href="{@docRoot}guide/components/fragments.html">Fragments</a> developer guide.</p>
205 * </div>
206 *
207 * <a name="OlderPlatforms"></a>
208 * <h3>Older Platforms</h3>
209 *
210 * While the Fragment API was introduced in
211 * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, a version of the API
212 * at is also available for use on older platforms through
213 * {@link android.support.v4.app.FragmentActivity}.  See the blog post
214 * <a href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html">
215 * Fragments For All</a> for more details.
216 *
217 * <a name="Lifecycle"></a>
218 * <h3>Lifecycle</h3>
219 *
220 * <p>Though a Fragment's lifecycle is tied to its owning activity, it has
221 * its own wrinkle on the standard activity lifecycle.  It includes basic
222 * activity lifecycle methods such as {@link #onResume}, but also important
223 * are methods related to interactions with the activity and UI generation.
224 *
225 * <p>The core series of lifecycle methods that are called to bring a fragment
226 * up to resumed state (interacting with the user) are:
227 *
228 * <ol>
229 * <li> {@link #onAttach} called once the fragment is associated with its activity.
230 * <li> {@link #onCreate} called to do initial creation of the fragment.
231 * <li> {@link #onCreateView} creates and returns the view hierarchy associated
232 * with the fragment.
233 * <li> {@link #onActivityCreated} tells the fragment that its activity has
234 * completed its own {@link Activity#onCreate Activity.onCreate()}.
235 * <li> {@link #onViewStateRestored} tells the fragment that all of the saved
236 * state of its view hierarchy has been restored.
237 * <li> {@link #onStart} makes the fragment visible to the user (based on its
238 * containing activity being started).
239 * <li> {@link #onResume} makes the fragment begin interacting with the user
240 * (based on its containing activity being resumed).
241 * </ol>
242 *
243 * <p>As a fragment is no longer being used, it goes through a reverse
244 * series of callbacks:
245 *
246 * <ol>
247 * <li> {@link #onPause} fragment is no longer interacting with the user either
248 * because its activity is being paused or a fragment operation is modifying it
249 * in the activity.
250 * <li> {@link #onStop} fragment is no longer visible to the user either
251 * because its activity is being stopped or a fragment operation is modifying it
252 * in the activity.
253 * <li> {@link #onDestroyView} allows the fragment to clean up resources
254 * associated with its View.
255 * <li> {@link #onDestroy} called to do final cleanup of the fragment's state.
256 * <li> {@link #onDetach} called immediately prior to the fragment no longer
257 * being associated with its activity.
258 * </ol>
259 *
260 * <a name="Layout"></a>
261 * <h3>Layout</h3>
262 *
263 * <p>Fragments can be used as part of your application's layout, allowing
264 * you to better modularize your code and more easily adjust your user
265 * interface to the screen it is running on.  As an example, we can look
266 * at a simple program consisting of a list of items, and display of the
267 * details of each item.</p>
268 *
269 * <p>An activity's layout XML can include <code>&lt;fragment&gt;</code> tags
270 * to embed fragment instances inside of the layout.  For example, here is
271 * a simple layout that embeds one fragment:</p>
272 *
273 * {@sample development/samples/ApiDemos/res/layout/fragment_layout.xml layout}
274 *
275 * <p>The layout is installed in the activity in the normal way:</p>
276 *
277 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
278 *      main}
279 *
280 * <p>The titles fragment, showing a list of titles, is fairly simple, relying
281 * on {@link ListFragment} for most of its work.  Note the implementation of
282 * clicking an item: depending on the current activity's layout, it can either
283 * create and display a new fragment to show the details in-place (more about
284 * this later), or start a new activity to show the details.</p>
285 *
286 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
287 *      titles}
288 *
289 * <p>The details fragment showing the contents of a selected item just
290 * displays a string of text based on an index of a string array built in to
291 * the app:</p>
292 *
293 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
294 *      details}
295 *
296 * <p>In this case when the user clicks on a title, there is no details
297 * container in the current activity, so the titles fragment's click code will
298 * launch a new activity to display the details fragment:</p>
299 *
300 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
301 *      details_activity}
302 *
303 * <p>However the screen may be large enough to show both the list of titles
304 * and details about the currently selected title.  To use such a layout on
305 * a landscape screen, this alternative layout can be placed under layout-land:</p>
306 *
307 * {@sample development/samples/ApiDemos/res/layout-land/fragment_layout.xml layout}
308 *
309 * <p>Note how the prior code will adjust to this alternative UI flow: the titles
310 * fragment will now embed the details fragment inside of this activity, and the
311 * details activity will finish itself if it is running in a configuration
312 * where the details can be shown in-place.
313 *
314 * <p>When a configuration change causes the activity hosting these fragments
315 * to restart, its new instance may use a different layout that doesn't
316 * include the same fragments as the previous layout.  In this case all of
317 * the previous fragments will still be instantiated and running in the new
318 * instance.  However, any that are no longer associated with a &lt;fragment&gt;
319 * tag in the view hierarchy will not have their content view created
320 * and will return false from {@link #isInLayout}.  (The code here also shows
321 * how you can determine if a fragment placed in a container is no longer
322 * running in a layout with that container and avoid creating its view hierarchy
323 * in that case.)
324 *
325 * <p>The attributes of the &lt;fragment&gt; tag are used to control the
326 * LayoutParams provided when attaching the fragment's view to the parent
327 * container.  They can also be parsed by the fragment in {@link #onInflate}
328 * as parameters.
329 *
330 * <p>The fragment being instantiated must have some kind of unique identifier
331 * so that it can be re-associated with a previous instance if the parent
332 * activity needs to be destroyed and recreated.  This can be provided these
333 * ways:
334 *
335 * <ul>
336 * <li>If nothing is explicitly supplied, the view ID of the container will
337 * be used.
338 * <li><code>android:tag</code> can be used in &lt;fragment&gt; to provide
339 * a specific tag name for the fragment.
340 * <li><code>android:id</code> can be used in &lt;fragment&gt; to provide
341 * a specific identifier for the fragment.
342 * </ul>
343 *
344 * <a name="BackStack"></a>
345 * <h3>Back Stack</h3>
346 *
347 * <p>The transaction in which fragments are modified can be placed on an
348 * internal back-stack of the owning activity.  When the user presses back
349 * in the activity, any transactions on the back stack are popped off before
350 * the activity itself is finished.
351 *
352 * <p>For example, consider this simple fragment that is instantiated with
353 * an integer argument and displays that in a TextView in its UI:</p>
354 *
355 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentStack.java
356 *      fragment}
357 *
358 * <p>A function that creates a new instance of the fragment, replacing
359 * whatever current fragment instance is being shown and pushing that change
360 * on to the back stack could be written as:
361 *
362 * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentStack.java
363 *      add_stack}
364 *
365 * <p>After each call to this function, a new entry is on the stack, and
366 * pressing back will pop it to return the user to whatever previous state
367 * the activity UI was in.
368 */
369public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListener {
370    private static final ArrayMap<String, Class<?>> sClassMap =
371            new ArrayMap<String, Class<?>>();
372
373    static final int INVALID_STATE = -1;   // Invalid state used as a null value.
374    static final int INITIALIZING = 0;     // Not yet created.
375    static final int CREATED = 1;          // Created.
376    static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.
377    static final int STOPPED = 3;          // Fully created, not started.
378    static final int STARTED = 4;          // Created and started, not resumed.
379    static final int RESUMED = 5;          // Created started and resumed.
380
381    private static final Transition USE_DEFAULT_TRANSITION = new TransitionSet();
382
383    int mState = INITIALIZING;
384
385    // When instantiated from saved state, this is the saved state.
386    Bundle mSavedFragmentState;
387    SparseArray<Parcelable> mSavedViewState;
388
389    // Index into active fragment array.
390    int mIndex = -1;
391
392    // Internal unique name for this fragment;
393    String mWho;
394
395    // Construction arguments;
396    Bundle mArguments;
397
398    // Target fragment.
399    Fragment mTarget;
400
401    // For use when retaining a fragment: this is the index of the last mTarget.
402    int mTargetIndex = -1;
403
404    // Target request code.
405    int mTargetRequestCode;
406
407    // True if the fragment is in the list of added fragments.
408    boolean mAdded;
409
410    // If set this fragment is being removed from its activity.
411    boolean mRemoving;
412
413    // Set to true if this fragment was instantiated from a layout file.
414    boolean mFromLayout;
415
416    // Set to true when the view has actually been inflated in its layout.
417    boolean mInLayout;
418
419    // True if this fragment has been restored from previously saved state.
420    boolean mRestored;
421
422    // True if performCreateView has been called and a matching call to performDestroyView
423    // has not yet happened.
424    boolean mPerformedCreateView;
425
426    // Number of active back stack entries this fragment is in.
427    int mBackStackNesting;
428
429    // The fragment manager we are associated with.  Set as soon as the
430    // fragment is used in a transaction; cleared after it has been removed
431    // from all transactions.
432    FragmentManagerImpl mFragmentManager;
433
434    // Activity this fragment is attached to.
435    FragmentHostCallback mHost;
436
437    // Private fragment manager for child fragments inside of this one.
438    FragmentManagerImpl mChildFragmentManager;
439
440    // For use when restoring fragment state and descendant fragments are retained.
441    // This state is set by FragmentState.instantiate and cleared in onCreate.
442    FragmentManagerNonConfig mChildNonConfig;
443
444    // If this Fragment is contained in another Fragment, this is that container.
445    Fragment mParentFragment;
446
447    // The optional identifier for this fragment -- either the container ID if it
448    // was dynamically added to the view hierarchy, or the ID supplied in
449    // layout.
450    int mFragmentId;
451
452    // When a fragment is being dynamically added to the view hierarchy, this
453    // is the identifier of the parent container it is being added to.
454    int mContainerId;
455
456    // The optional named tag for this fragment -- usually used to find
457    // fragments that are not part of the layout.
458    String mTag;
459
460    // Set to true when the app has requested that this fragment be hidden
461    // from the user.
462    boolean mHidden;
463
464    // Set to true when the app has requested that this fragment be detached.
465    boolean mDetached;
466
467    // If set this fragment would like its instance retained across
468    // configuration changes.
469    boolean mRetainInstance;
470
471    // If set this fragment is being retained across the current config change.
472    boolean mRetaining;
473
474    // If set this fragment has menu items to contribute.
475    boolean mHasMenu;
476
477    // Set to true to allow the fragment's menu to be shown.
478    boolean mMenuVisible = true;
479
480    // Used to verify that subclasses call through to super class.
481    boolean mCalled;
482
483    // The parent container of the fragment after dynamically added to UI.
484    ViewGroup mContainer;
485
486    // The View generated for this fragment.
487    View mView;
488
489    // Whether this fragment should defer starting until after other fragments
490    // have been started and their loaders are finished.
491    boolean mDeferStart;
492
493    // Hint provided by the app that this fragment is currently visible to the user.
494    boolean mUserVisibleHint = true;
495
496    LoaderManagerImpl mLoaderManager;
497    boolean mLoadersStarted;
498    boolean mCheckedForLoaderManager;
499
500    // The animation and transition information for the fragment. This will be null
501    // unless the elements are explicitly accessed and should remain null for Fragments
502    // without Views.
503    AnimationInfo mAnimationInfo;
504
505    // True if the View was added, and its animation has yet to be run. This could
506    // also indicate that the fragment view hasn't been made visible, even if there is no
507    // animation for this fragment.
508    boolean mIsNewlyAdded;
509
510    // True if mHidden has been changed and the animation should be scheduled.
511    boolean mHiddenChanged;
512
513    // The cached value from onGetLayoutInflater(Bundle) that will be returned from
514    // getLayoutInflater()
515    LayoutInflater mLayoutInflater;
516
517    /**
518     * State information that has been retrieved from a fragment instance
519     * through {@link FragmentManager#saveFragmentInstanceState(Fragment)
520     * FragmentManager.saveFragmentInstanceState}.
521     */
522    public static class SavedState implements Parcelable {
523        final Bundle mState;
524
525        SavedState(Bundle state) {
526            mState = state;
527        }
528
529        SavedState(Parcel in, ClassLoader loader) {
530            mState = in.readBundle();
531            if (loader != null && mState != null) {
532                mState.setClassLoader(loader);
533            }
534        }
535
536        @Override
537        public int describeContents() {
538            return 0;
539        }
540
541        @Override
542        public void writeToParcel(Parcel dest, int flags) {
543            dest.writeBundle(mState);
544        }
545
546        public static final Parcelable.ClassLoaderCreator<SavedState> CREATOR
547                = new Parcelable.ClassLoaderCreator<SavedState>() {
548            public SavedState createFromParcel(Parcel in) {
549                return new SavedState(in, null);
550            }
551
552            public SavedState createFromParcel(Parcel in, ClassLoader loader) {
553                return new SavedState(in, loader);
554            }
555
556            public SavedState[] newArray(int size) {
557                return new SavedState[size];
558            }
559        };
560    }
561
562    /**
563     * Thrown by {@link Fragment#instantiate(Context, String, Bundle)} when
564     * there is an instantiation failure.
565     */
566    static public class InstantiationException extends AndroidRuntimeException {
567        public InstantiationException(String msg, Exception cause) {
568            super(msg, cause);
569        }
570    }
571
572    /**
573     * Default constructor.  <strong>Every</strong> fragment must have an
574     * empty constructor, so it can be instantiated when restoring its
575     * activity's state.  It is strongly recommended that subclasses do not
576     * have other constructors with parameters, since these constructors
577     * will not be called when the fragment is re-instantiated; instead,
578     * arguments can be supplied by the caller with {@link #setArguments}
579     * and later retrieved by the Fragment with {@link #getArguments}.
580     *
581     * <p>Applications should generally not implement a constructor. Prefer
582     * {@link #onAttach(Context)} instead. It is the first place application code can run where
583     * the fragment is ready to be used - the point where the fragment is actually associated with
584     * its context. Some applications may also want to implement {@link #onInflate} to retrieve
585     * attributes from a layout resource, although note this happens when the fragment is attached.
586     */
587    public Fragment() {
588    }
589
590    /**
591     * Like {@link #instantiate(Context, String, Bundle)} but with a null
592     * argument Bundle.
593     */
594    public static Fragment instantiate(Context context, String fname) {
595        return instantiate(context, fname, null);
596    }
597
598    /**
599     * Create a new instance of a Fragment with the given class name.  This is
600     * the same as calling its empty constructor.
601     *
602     * @param context The calling context being used to instantiate the fragment.
603     * This is currently just used to get its ClassLoader.
604     * @param fname The class name of the fragment to instantiate.
605     * @param args Bundle of arguments to supply to the fragment, which it
606     * can retrieve with {@link #getArguments()}.  May be null.
607     * @return Returns a new fragment instance.
608     * @throws InstantiationException If there is a failure in instantiating
609     * the given fragment class.  This is a runtime exception; it is not
610     * normally expected to happen.
611     */
612    public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) {
613        try {
614            Class<?> clazz = sClassMap.get(fname);
615            if (clazz == null) {
616                // Class not found in the cache, see if it's real, and try to add it
617                clazz = context.getClassLoader().loadClass(fname);
618                if (!Fragment.class.isAssignableFrom(clazz)) {
619                    throw new InstantiationException("Trying to instantiate a class " + fname
620                            + " that is not a Fragment", new ClassCastException());
621                }
622                sClassMap.put(fname, clazz);
623            }
624            Fragment f = (Fragment) clazz.getConstructor().newInstance();
625            if (args != null) {
626                args.setClassLoader(f.getClass().getClassLoader());
627                f.setArguments(args);
628            }
629            return f;
630        } catch (ClassNotFoundException e) {
631            throw new InstantiationException("Unable to instantiate fragment " + fname
632                    + ": make sure class name exists, is public, and has an"
633                    + " empty constructor that is public", e);
634        } catch (java.lang.InstantiationException e) {
635            throw new InstantiationException("Unable to instantiate fragment " + fname
636                    + ": make sure class name exists, is public, and has an"
637                    + " empty constructor that is public", e);
638        } catch (IllegalAccessException e) {
639            throw new InstantiationException("Unable to instantiate fragment " + fname
640                    + ": make sure class name exists, is public, and has an"
641                    + " empty constructor that is public", e);
642        } catch (NoSuchMethodException e) {
643            throw new InstantiationException("Unable to instantiate fragment " + fname
644                    + ": could not find Fragment constructor", e);
645        } catch (InvocationTargetException e) {
646            throw new InstantiationException("Unable to instantiate fragment " + fname
647                    + ": calling Fragment constructor caused an exception", e);
648        }
649    }
650
651    final void restoreViewState(Bundle savedInstanceState) {
652        if (mSavedViewState != null) {
653            mView.restoreHierarchyState(mSavedViewState);
654            mSavedViewState = null;
655        }
656        mCalled = false;
657        onViewStateRestored(savedInstanceState);
658        if (!mCalled) {
659            throw new SuperNotCalledException("Fragment " + this
660                    + " did not call through to super.onViewStateRestored()");
661        }
662    }
663
664    final void setIndex(int index, Fragment parent) {
665        mIndex = index;
666        if (parent != null) {
667            mWho = parent.mWho + ":" + mIndex;
668        } else {
669            mWho = "android:fragment:" + mIndex;
670        }
671    }
672
673    final boolean isInBackStack() {
674        return mBackStackNesting > 0;
675    }
676
677    /**
678     * Subclasses can not override equals().
679     */
680    @Override final public boolean equals(Object o) {
681        return super.equals(o);
682    }
683
684    /**
685     * Subclasses can not override hashCode().
686     */
687    @Override final public int hashCode() {
688        return super.hashCode();
689    }
690
691    @Override
692    public String toString() {
693        StringBuilder sb = new StringBuilder(128);
694        DebugUtils.buildShortClassTag(this, sb);
695        if (mIndex >= 0) {
696            sb.append(" #");
697            sb.append(mIndex);
698        }
699        if (mFragmentId != 0) {
700            sb.append(" id=0x");
701            sb.append(Integer.toHexString(mFragmentId));
702        }
703        if (mTag != null) {
704            sb.append(" ");
705            sb.append(mTag);
706        }
707        sb.append('}');
708        return sb.toString();
709    }
710
711    /**
712     * Return the identifier this fragment is known by.  This is either
713     * the android:id value supplied in a layout or the container view ID
714     * supplied when adding the fragment.
715     */
716    final public int getId() {
717        return mFragmentId;
718    }
719
720    /**
721     * Get the tag name of the fragment, if specified.
722     */
723    final public String getTag() {
724        return mTag;
725    }
726
727    /**
728     * Supply the construction arguments for this fragment.
729     * The arguments supplied here will be retained across fragment destroy and
730     * creation.
731     *
732     * <p>This method cannot be called if the fragment is added to a FragmentManager and
733     * if {@link #isStateSaved()} would return true. Prior to {@link Build.VERSION_CODES#O},
734     * this method may only be called if the fragment has not yet been added to a FragmentManager.
735     * </p>
736     */
737    public void setArguments(Bundle args) {
738        // The isStateSaved requirement below was only added in Android O and is compatible
739        // because it loosens previous requirements rather than making them more strict.
740        // See method javadoc.
741        if (mIndex >= 0 && isStateSaved()) {
742            throw new IllegalStateException("Fragment already active");
743        }
744        mArguments = args;
745    }
746
747    /**
748     * Return the arguments supplied to {@link #setArguments}, if any.
749     */
750    final public Bundle getArguments() {
751        return mArguments;
752    }
753
754    /**
755     * Returns true if this fragment is added and its state has already been saved
756     * by its host. Any operations that would change saved state should not be performed
757     * if this method returns true, and some operations such as {@link #setArguments(Bundle)}
758     * will fail.
759     *
760     * @return true if this fragment's state has already been saved by its host
761     */
762    public final boolean isStateSaved() {
763        if (mFragmentManager == null) {
764            return false;
765        }
766        return mFragmentManager.isStateSaved();
767    }
768
769    /**
770     * Set the initial saved state that this Fragment should restore itself
771     * from when first being constructed, as returned by
772     * {@link FragmentManager#saveFragmentInstanceState(Fragment)
773     * FragmentManager.saveFragmentInstanceState}.
774     *
775     * @param state The state the fragment should be restored from.
776     */
777    public void setInitialSavedState(SavedState state) {
778        if (mIndex >= 0) {
779            throw new IllegalStateException("Fragment already active");
780        }
781        mSavedFragmentState = state != null && state.mState != null
782                ? state.mState : null;
783    }
784
785    /**
786     * Optional target for this fragment.  This may be used, for example,
787     * if this fragment is being started by another, and when done wants to
788     * give a result back to the first.  The target set here is retained
789     * across instances via {@link FragmentManager#putFragment
790     * FragmentManager.putFragment()}.
791     *
792     * @param fragment The fragment that is the target of this one.
793     * @param requestCode Optional request code, for convenience if you
794     * are going to call back with {@link #onActivityResult(int, int, Intent)}.
795     */
796    public void setTargetFragment(Fragment fragment, int requestCode) {
797        // Don't allow a caller to set a target fragment in another FragmentManager,
798        // but there's a snag: people do set target fragments before fragments get added.
799        // We'll have the FragmentManager check that for validity when we move
800        // the fragments to a valid state.
801        final FragmentManager mine = getFragmentManager();
802        final FragmentManager theirs = fragment != null ? fragment.getFragmentManager() : null;
803        if (mine != null && theirs != null && mine != theirs) {
804            throw new IllegalArgumentException("Fragment " + fragment
805                    + " must share the same FragmentManager to be set as a target fragment");
806        }
807
808        // Don't let someone create a cycle.
809        for (Fragment check = fragment; check != null; check = check.getTargetFragment()) {
810            if (check == this) {
811                throw new IllegalArgumentException("Setting " + fragment + " as the target of "
812                        + this + " would create a target cycle");
813            }
814        }
815        mTarget = fragment;
816        mTargetRequestCode = requestCode;
817    }
818
819    /**
820     * Return the target fragment set by {@link #setTargetFragment}.
821     */
822    final public Fragment getTargetFragment() {
823        return mTarget;
824    }
825
826    /**
827     * Return the target request code set by {@link #setTargetFragment}.
828     */
829    final public int getTargetRequestCode() {
830        return mTargetRequestCode;
831    }
832
833    /**
834     * Return the {@link Context} this fragment is currently associated with.
835     */
836    public Context getContext() {
837        return mHost == null ? null : mHost.getContext();
838    }
839
840    /**
841     * Return the Activity this fragment is currently associated with.
842     */
843    final public Activity getActivity() {
844        return mHost == null ? null : mHost.getActivity();
845    }
846
847    /**
848     * Return the host object of this fragment. May return {@code null} if the fragment
849     * isn't currently being hosted.
850     */
851    @Nullable
852    final public Object getHost() {
853        return mHost == null ? null : mHost.onGetHost();
854    }
855
856    /**
857     * Return <code>getActivity().getResources()</code>.
858     */
859    final public Resources getResources() {
860        if (mHost == null) {
861            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
862        }
863        return mHost.getContext().getResources();
864    }
865
866    /**
867     * Return a localized, styled CharSequence from the application's package's
868     * default string table.
869     *
870     * @param resId Resource id for the CharSequence text
871     */
872    public final CharSequence getText(@StringRes int resId) {
873        return getResources().getText(resId);
874    }
875
876    /**
877     * Return a localized string from the application's package's
878     * default string table.
879     *
880     * @param resId Resource id for the string
881     */
882    public final String getString(@StringRes int resId) {
883        return getResources().getString(resId);
884    }
885
886    /**
887     * Return a localized formatted string from the application's package's
888     * default string table, substituting the format arguments as defined in
889     * {@link java.util.Formatter} and {@link java.lang.String#format}.
890     *
891     * @param resId Resource id for the format string
892     * @param formatArgs The format arguments that will be used for substitution.
893     */
894
895    public final String getString(@StringRes int resId, Object... formatArgs) {
896        return getResources().getString(resId, formatArgs);
897    }
898
899    /**
900     * Return the FragmentManager for interacting with fragments associated
901     * with this fragment's activity.  Note that this will be non-null slightly
902     * before {@link #getActivity()}, during the time from when the fragment is
903     * placed in a {@link FragmentTransaction} until it is committed and
904     * attached to its activity.
905     *
906     * <p>If this Fragment is a child of another Fragment, the FragmentManager
907     * returned here will be the parent's {@link #getChildFragmentManager()}.
908     */
909    final public FragmentManager getFragmentManager() {
910        return mFragmentManager;
911    }
912
913    /**
914     * Return a private FragmentManager for placing and managing Fragments
915     * inside of this Fragment.
916     */
917    final public FragmentManager getChildFragmentManager() {
918        if (mChildFragmentManager == null) {
919            instantiateChildFragmentManager();
920            if (mState >= RESUMED) {
921                mChildFragmentManager.dispatchResume();
922            } else if (mState >= STARTED) {
923                mChildFragmentManager.dispatchStart();
924            } else if (mState >= ACTIVITY_CREATED) {
925                mChildFragmentManager.dispatchActivityCreated();
926            } else if (mState >= CREATED) {
927                mChildFragmentManager.dispatchCreate();
928            }
929        }
930        return mChildFragmentManager;
931    }
932
933    /**
934     * Returns the parent Fragment containing this Fragment.  If this Fragment
935     * is attached directly to an Activity, returns null.
936     */
937    final public Fragment getParentFragment() {
938        return mParentFragment;
939    }
940
941    /**
942     * Return true if the fragment is currently added to its activity.
943     */
944    final public boolean isAdded() {
945        return mHost != null && mAdded;
946    }
947
948    /**
949     * Return true if the fragment has been explicitly detached from the UI.
950     * That is, {@link FragmentTransaction#detach(Fragment)
951     * FragmentTransaction.detach(Fragment)} has been used on it.
952     */
953    final public boolean isDetached() {
954        return mDetached;
955    }
956
957    /**
958     * Return true if this fragment is currently being removed from its
959     * activity.  This is  <em>not</em> whether its activity is finishing, but
960     * rather whether it is in the process of being removed from its activity.
961     */
962    final public boolean isRemoving() {
963        return mRemoving;
964    }
965
966    /**
967     * Return true if the layout is included as part of an activity view
968     * hierarchy via the &lt;fragment&gt; tag.  This will always be true when
969     * fragments are created through the &lt;fragment&gt; tag, <em>except</em>
970     * in the case where an old fragment is restored from a previous state and
971     * it does not appear in the layout of the current state.
972     */
973    final public boolean isInLayout() {
974        return mInLayout;
975    }
976
977    /**
978     * Return true if the fragment is in the resumed state.  This is true
979     * for the duration of {@link #onResume()} and {@link #onPause()} as well.
980     */
981    final public boolean isResumed() {
982        return mState >= RESUMED;
983    }
984
985    /**
986     * Return true if the fragment is currently visible to the user.  This means
987     * it: (1) has been added, (2) has its view attached to the window, and
988     * (3) is not hidden.
989     */
990    final public boolean isVisible() {
991        return isAdded() && !isHidden() && mView != null
992                && mView.getWindowToken() != null && mView.getVisibility() == View.VISIBLE;
993    }
994
995    /**
996     * Return true if the fragment has been hidden.  By default fragments
997     * are shown.  You can find out about changes to this state with
998     * {@link #onHiddenChanged}.  Note that the hidden state is orthogonal
999     * to other states -- that is, to be visible to the user, a fragment
1000     * must be both started and not hidden.
1001     */
1002    final public boolean isHidden() {
1003        return mHidden;
1004    }
1005
1006    /**
1007     * Called when the hidden state (as returned by {@link #isHidden()} of
1008     * the fragment has changed.  Fragments start out not hidden; this will
1009     * be called whenever the fragment changes state from that.
1010     * @param hidden True if the fragment is now hidden, false otherwise.
1011     */
1012    public void onHiddenChanged(boolean hidden) {
1013    }
1014
1015    /**
1016     * Control whether a fragment instance is retained across Activity
1017     * re-creation (such as from a configuration change).  This can only
1018     * be used with fragments not in the back stack.  If set, the fragment
1019     * lifecycle will be slightly different when an activity is recreated:
1020     * <ul>
1021     * <li> {@link #onDestroy()} will not be called (but {@link #onDetach()} still
1022     * will be, because the fragment is being detached from its current activity).
1023     * <li> {@link #onCreate(Bundle)} will not be called since the fragment
1024     * is not being re-created.
1025     * <li> {@link #onAttach(Activity)} and {@link #onActivityCreated(Bundle)} <b>will</b>
1026     * still be called.
1027     * </ul>
1028     */
1029    public void setRetainInstance(boolean retain) {
1030        mRetainInstance = retain;
1031    }
1032
1033    final public boolean getRetainInstance() {
1034        return mRetainInstance;
1035    }
1036
1037    /**
1038     * Report that this fragment would like to participate in populating
1039     * the options menu by receiving a call to {@link #onCreateOptionsMenu}
1040     * and related methods.
1041     *
1042     * @param hasMenu If true, the fragment has menu items to contribute.
1043     */
1044    public void setHasOptionsMenu(boolean hasMenu) {
1045        if (mHasMenu != hasMenu) {
1046            mHasMenu = hasMenu;
1047            if (isAdded() && !isHidden()) {
1048                mFragmentManager.invalidateOptionsMenu();
1049            }
1050        }
1051    }
1052
1053    /**
1054     * Set a hint for whether this fragment's menu should be visible.  This
1055     * is useful if you know that a fragment has been placed in your view
1056     * hierarchy so that the user can not currently seen it, so any menu items
1057     * it has should also not be shown.
1058     *
1059     * @param menuVisible The default is true, meaning the fragment's menu will
1060     * be shown as usual.  If false, the user will not see the menu.
1061     */
1062    public void setMenuVisibility(boolean menuVisible) {
1063        if (mMenuVisible != menuVisible) {
1064            mMenuVisible = menuVisible;
1065            if (mHasMenu && isAdded() && !isHidden()) {
1066                mFragmentManager.invalidateOptionsMenu();
1067            }
1068        }
1069    }
1070
1071    /**
1072     * Set a hint to the system about whether this fragment's UI is currently visible
1073     * to the user. This hint defaults to true and is persistent across fragment instance
1074     * state save and restore.
1075     *
1076     * <p>An app may set this to false to indicate that the fragment's UI is
1077     * scrolled out of visibility or is otherwise not directly visible to the user.
1078     * This may be used by the system to prioritize operations such as fragment lifecycle updates
1079     * or loader ordering behavior.</p>
1080     *
1081     * <p><strong>Note:</strong> This method may be called outside of the fragment lifecycle
1082     * and thus has no ordering guarantees with regard to fragment lifecycle method calls.</p>
1083     *
1084     * <p><strong>Note:</strong> Prior to Android N there was a platform bug that could cause
1085     * <code>setUserVisibleHint</code> to bring a fragment up to the started state before its
1086     * <code>FragmentTransaction</code> had been committed. As some apps relied on this behavior,
1087     * it is preserved for apps that declare a <code>targetSdkVersion</code> of 23 or lower.</p>
1088     *
1089     * @param isVisibleToUser true if this fragment's UI is currently visible to the user (default),
1090     *                        false if it is not.
1091     */
1092    public void setUserVisibleHint(boolean isVisibleToUser) {
1093        // Prior to Android N we were simply checking if this fragment had a FragmentManager
1094        // set before we would trigger a deferred start. Unfortunately this also gets set before
1095        // a fragment transaction is committed, so if setUserVisibleHint was called before a
1096        // transaction commit, we would start the fragment way too early. FragmentPagerAdapter
1097        // triggers this situation.
1098        // Unfortunately some apps relied on this timing in overrides of setUserVisibleHint
1099        // on their own fragments, and expected, however erroneously, that after a call to
1100        // super.setUserVisibleHint their onStart methods had been run.
1101        // We preserve this behavior for apps targeting old platform versions below.
1102        boolean useBrokenAddedCheck = false;
1103        Context context = getContext();
1104        if (mFragmentManager != null && mFragmentManager.mHost != null) {
1105            context = mFragmentManager.mHost.getContext();
1106        }
1107        if (context != null) {
1108            useBrokenAddedCheck = context.getApplicationInfo().targetSdkVersion <= VERSION_CODES.M;
1109        }
1110
1111        final boolean performDeferredStart;
1112        if (useBrokenAddedCheck) {
1113            performDeferredStart = !mUserVisibleHint && isVisibleToUser && mState < STARTED
1114                    && mFragmentManager != null;
1115        } else {
1116            performDeferredStart = !mUserVisibleHint && isVisibleToUser && mState < STARTED
1117                    && mFragmentManager != null && isAdded();
1118        }
1119
1120        if (performDeferredStart) {
1121            mFragmentManager.performPendingDeferredStart(this);
1122        }
1123
1124        mUserVisibleHint = isVisibleToUser;
1125        mDeferStart = mState < STARTED && !isVisibleToUser;
1126    }
1127
1128    /**
1129     * @return The current value of the user-visible hint on this fragment.
1130     * @see #setUserVisibleHint(boolean)
1131     */
1132    public boolean getUserVisibleHint() {
1133        return mUserVisibleHint;
1134    }
1135
1136    /**
1137     * Return the LoaderManager for this fragment, creating it if needed.
1138     */
1139    public LoaderManager getLoaderManager() {
1140        if (mLoaderManager != null) {
1141            return mLoaderManager;
1142        }
1143        if (mHost == null) {
1144            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
1145        }
1146        mCheckedForLoaderManager = true;
1147        mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, true);
1148        return mLoaderManager;
1149    }
1150
1151    /**
1152     * Call {@link Activity#startActivity(Intent)} from the fragment's
1153     * containing Activity.
1154     *
1155     * @param intent The intent to start.
1156     */
1157    public void startActivity(Intent intent) {
1158        startActivity(intent, null);
1159    }
1160
1161    /**
1162     * Call {@link Activity#startActivity(Intent, Bundle)} from the fragment's
1163     * containing Activity.
1164     *
1165     * @param intent The intent to start.
1166     * @param options Additional options for how the Activity should be started.
1167     * See {@link android.content.Context#startActivity(Intent, Bundle)}
1168     * Context.startActivity(Intent, Bundle)} for more details.
1169     */
1170    public void startActivity(Intent intent, Bundle options) {
1171        if (mHost == null) {
1172            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
1173        }
1174        if (options != null) {
1175            mHost.onStartActivityFromFragment(this, intent, -1, options);
1176        } else {
1177            // Note we want to go through this call for compatibility with
1178            // applications that may have overridden the method.
1179            mHost.onStartActivityFromFragment(this, intent, -1, null /*options*/);
1180        }
1181    }
1182
1183    /**
1184     * Call {@link Activity#startActivityForResult(Intent, int)} from the fragment's
1185     * containing Activity.
1186     */
1187    public void startActivityForResult(Intent intent, int requestCode) {
1188        startActivityForResult(intent, requestCode, null);
1189    }
1190
1191    /**
1192     * Call {@link Activity#startActivityForResult(Intent, int, Bundle)} from the fragment's
1193     * containing Activity.
1194     */
1195    public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
1196        if (mHost == null) {
1197            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
1198        }
1199        mHost.onStartActivityFromFragment(this, intent, requestCode, options);
1200    }
1201
1202    /**
1203     * @hide
1204     * Call {@link Activity#startActivityForResultAsUser(Intent, int, UserHandle)} from the
1205     * fragment's containing Activity.
1206     */
1207    public void startActivityForResultAsUser(
1208            Intent intent, int requestCode, Bundle options, UserHandle user) {
1209        if (mHost == null) {
1210            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
1211        }
1212        mHost.onStartActivityAsUserFromFragment(this, intent, requestCode, options, user);
1213    }
1214
1215    /**
1216     * Call {@link Activity#startIntentSenderForResult(IntentSender, int, Intent, int, int, int,
1217     * Bundle)} from the fragment's containing Activity.
1218     */
1219    public void startIntentSenderForResult(IntentSender intent, int requestCode,
1220            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
1221            Bundle options) throws IntentSender.SendIntentException {
1222        if (mHost == null) {
1223            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
1224        }
1225        mHost.onStartIntentSenderFromFragment(this, intent, requestCode, fillInIntent, flagsMask,
1226                flagsValues, extraFlags, options);
1227    }
1228
1229    /**
1230     * Receive the result from a previous call to
1231     * {@link #startActivityForResult(Intent, int)}.  This follows the
1232     * related Activity API as described there in
1233     * {@link Activity#onActivityResult(int, int, Intent)}.
1234     *
1235     * @param requestCode The integer request code originally supplied to
1236     *                    startActivityForResult(), allowing you to identify who this
1237     *                    result came from.
1238     * @param resultCode The integer result code returned by the child activity
1239     *                   through its setResult().
1240     * @param data An Intent, which can return result data to the caller
1241     *               (various data can be attached to Intent "extras").
1242     */
1243    public void onActivityResult(int requestCode, int resultCode, Intent data) {
1244    }
1245
1246    /**
1247     * Requests permissions to be granted to this application. These permissions
1248     * must be requested in your manifest, they should not be granted to your app,
1249     * and they should have protection level {@link android.content.pm.PermissionInfo
1250     * #PROTECTION_DANGEROUS dangerous}, regardless whether they are declared by
1251     * the platform or a third-party app.
1252     * <p>
1253     * Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL}
1254     * are granted at install time if requested in the manifest. Signature permissions
1255     * {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at
1256     * install time if requested in the manifest and the signature of your app matches
1257     * the signature of the app declaring the permissions.
1258     * </p>
1259     * <p>
1260     * If your app does not have the requested permissions the user will be presented
1261     * with UI for accepting them. After the user has accepted or rejected the
1262     * requested permissions you will receive a callback on {@link
1263     * #onRequestPermissionsResult(int, String[], int[])} reporting whether the
1264     * permissions were granted or not.
1265     * </p>
1266     * <p>
1267     * Note that requesting a permission does not guarantee it will be granted and
1268     * your app should be able to run without having this permission.
1269     * </p>
1270     * <p>
1271     * This method may start an activity allowing the user to choose which permissions
1272     * to grant and which to reject. Hence, you should be prepared that your activity
1273     * may be paused and resumed. Further, granting some permissions may require
1274     * a restart of you application. In such a case, the system will recreate the
1275     * activity stack before delivering the result to {@link
1276     * #onRequestPermissionsResult(int, String[], int[])}.
1277     * </p>
1278     * <p>
1279     * When checking whether you have a permission you should use {@link
1280     * android.content.Context#checkSelfPermission(String)}.
1281     * </p>
1282     * <p>
1283     * Calling this API for permissions already granted to your app would show UI
1284     * to the user to decide whether the app can still hold these permissions. This
1285     * can be useful if the way your app uses data guarded by the permissions
1286     * changes significantly.
1287     * </p>
1288     * <p>
1289     * You cannot request a permission if your activity sets {@link
1290     * android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
1291     * <code>true</code> because in this case the activity would not receive
1292     * result callbacks including {@link #onRequestPermissionsResult(int, String[], int[])}.
1293     * </p>
1294     * <p>
1295     * A sample permissions request looks like this:
1296     * </p>
1297     * <code><pre><p>
1298     * private void showContacts() {
1299     *     if (getActivity().checkSelfPermission(Manifest.permission.READ_CONTACTS)
1300     *             != PackageManager.PERMISSION_GRANTED) {
1301     *         requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
1302     *                 PERMISSIONS_REQUEST_READ_CONTACTS);
1303     *     } else {
1304     *         doShowContacts();
1305     *     }
1306     * }
1307     *
1308     * {@literal @}Override
1309     * public void onRequestPermissionsResult(int requestCode, String[] permissions,
1310     *         int[] grantResults) {
1311     *     if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS
1312     *             && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
1313     *         doShowContacts();
1314     *     }
1315     * }
1316     * </code></pre></p>
1317     *
1318     * @param permissions The requested permissions. Must me non-null and not empty.
1319     * @param requestCode Application specific request code to match with a result
1320     *    reported to {@link #onRequestPermissionsResult(int, String[], int[])}.
1321     *    Should be >= 0.
1322     *
1323     * @see #onRequestPermissionsResult(int, String[], int[])
1324     * @see android.content.Context#checkSelfPermission(String)
1325     */
1326    public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
1327        if (mHost == null) {
1328            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
1329        }
1330        mHost.onRequestPermissionsFromFragment(this, permissions,requestCode);
1331    }
1332
1333    /**
1334     * Callback for the result from requesting permissions. This method
1335     * is invoked for every call on {@link #requestPermissions(String[], int)}.
1336     * <p>
1337     * <strong>Note:</strong> It is possible that the permissions request interaction
1338     * with the user is interrupted. In this case you will receive empty permissions
1339     * and results arrays which should be treated as a cancellation.
1340     * </p>
1341     *
1342     * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
1343     * @param permissions The requested permissions. Never null.
1344     * @param grantResults The grant results for the corresponding permissions
1345     *     which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED}
1346     *     or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
1347     *
1348     * @see #requestPermissions(String[], int)
1349     */
1350    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
1351            @NonNull int[] grantResults) {
1352        /* callback - do nothing */
1353    }
1354
1355    /**
1356     * Gets whether you should show UI with rationale for requesting a permission.
1357     * You should do this only if you do not have the permission and the context in
1358     * which the permission is requested does not clearly communicate to the user
1359     * what would be the benefit from granting this permission.
1360     * <p>
1361     * For example, if you write a camera app, requesting the camera permission
1362     * would be expected by the user and no rationale for why it is requested is
1363     * needed. If however, the app needs location for tagging photos then a non-tech
1364     * savvy user may wonder how location is related to taking photos. In this case
1365     * you may choose to show UI with rationale of requesting this permission.
1366     * </p>
1367     *
1368     * @param permission A permission your app wants to request.
1369     * @return Whether you can show permission rationale UI.
1370     *
1371     * @see Context#checkSelfPermission(String)
1372     * @see #requestPermissions(String[], int)
1373     * @see #onRequestPermissionsResult(int, String[], int[])
1374     */
1375    public boolean shouldShowRequestPermissionRationale(@NonNull String permission) {
1376        if (mHost != null) {
1377            return mHost.getContext().getPackageManager()
1378                    .shouldShowRequestPermissionRationale(permission);
1379        }
1380        return false;
1381    }
1382
1383    /**
1384     * Returns the LayoutInflater used to inflate Views of this Fragment. The default
1385     * implementation will throw an exception if the Fragment is not attached.
1386     *
1387     * @return The LayoutInflater used to inflate Views of this Fragment.
1388     */
1389    public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
1390        if (mHost == null) {
1391            throw new IllegalStateException("onGetLayoutInflater() cannot be executed until the "
1392                    + "Fragment is attached to the FragmentManager.");
1393        }
1394        final LayoutInflater result = mHost.onGetLayoutInflater();
1395        if (mHost.onUseFragmentManagerInflaterFactory()) {
1396            getChildFragmentManager(); // Init if needed; use raw implementation below.
1397            result.setPrivateFactory(mChildFragmentManager.getLayoutInflaterFactory());
1398        }
1399        return result;
1400    }
1401
1402    /**
1403     * Returns the cached LayoutInflater used to inflate Views of this Fragment. If
1404     * {@link #onGetLayoutInflater(Bundle)} has not been called {@link #onGetLayoutInflater(Bundle)}
1405     * will be called with a {@code null} argument and that value will be cached.
1406     * <p>
1407     * The cached LayoutInflater will be replaced immediately prior to
1408     * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} and cleared immediately after
1409     * {@link #onDetach()}.
1410     *
1411     * @return The LayoutInflater used to inflate Views of this Fragment.
1412     */
1413    public final LayoutInflater getLayoutInflater() {
1414        if (mLayoutInflater == null) {
1415            return performGetLayoutInflater(null);
1416        }
1417        return mLayoutInflater;
1418    }
1419
1420    /**
1421     * Calls {@link #onGetLayoutInflater(Bundle)} and caches the result for use by
1422     * {@link #getLayoutInflater()}.
1423     *
1424     * @param savedInstanceState If the fragment is being re-created from
1425     * a previous saved state, this is the state.
1426     * @return The LayoutInflater used to inflate Views of this Fragment.
1427     */
1428    LayoutInflater performGetLayoutInflater(Bundle savedInstanceState) {
1429        LayoutInflater layoutInflater = onGetLayoutInflater(savedInstanceState);
1430        mLayoutInflater = layoutInflater;
1431        return mLayoutInflater;
1432    }
1433
1434    /**
1435     * @deprecated Use {@link #onInflate(Context, AttributeSet, Bundle)} instead.
1436     */
1437    @Deprecated
1438    @CallSuper
1439    public void onInflate(AttributeSet attrs, Bundle savedInstanceState) {
1440        mCalled = true;
1441    }
1442
1443    /**
1444     * Called when a fragment is being created as part of a view layout
1445     * inflation, typically from setting the content view of an activity.  This
1446     * may be called immediately after the fragment is created from a <fragment>
1447     * tag in a layout file.  Note this is <em>before</em> the fragment's
1448     * {@link #onAttach(Activity)} has been called; all you should do here is
1449     * parse the attributes and save them away.
1450     *
1451     * <p>This is called every time the fragment is inflated, even if it is
1452     * being inflated into a new instance with saved state.  It typically makes
1453     * sense to re-parse the parameters each time, to allow them to change with
1454     * different configurations.</p>
1455     *
1456     * <p>Here is a typical implementation of a fragment that can take parameters
1457     * both through attributes supplied here as well from {@link #getArguments()}:</p>
1458     *
1459     * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentArguments.java
1460     *      fragment}
1461     *
1462     * <p>Note that parsing the XML attributes uses a "styleable" resource.  The
1463     * declaration for the styleable used here is:</p>
1464     *
1465     * {@sample development/samples/ApiDemos/res/values/attrs.xml fragment_arguments}
1466     *
1467     * <p>The fragment can then be declared within its activity's content layout
1468     * through a tag like this:</p>
1469     *
1470     * {@sample development/samples/ApiDemos/res/layout/fragment_arguments.xml from_attributes}
1471     *
1472     * <p>This fragment can also be created dynamically from arguments given
1473     * at runtime in the arguments Bundle; here is an example of doing so at
1474     * creation of the containing activity:</p>
1475     *
1476     * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentArguments.java
1477     *      create}
1478     *
1479     * @param context The Context that is inflating this fragment.
1480     * @param attrs The attributes at the tag where the fragment is
1481     * being created.
1482     * @param savedInstanceState If the fragment is being re-created from
1483     * a previous saved state, this is the state.
1484     */
1485    @CallSuper
1486    public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
1487        onInflate(attrs, savedInstanceState);
1488        mCalled = true;
1489
1490        TypedArray a = context.obtainStyledAttributes(attrs,
1491                com.android.internal.R.styleable.Fragment);
1492        setEnterTransition(loadTransition(context, a, getEnterTransition(), null,
1493                com.android.internal.R.styleable.Fragment_fragmentEnterTransition));
1494        setReturnTransition(loadTransition(context, a, getReturnTransition(),
1495                USE_DEFAULT_TRANSITION,
1496                com.android.internal.R.styleable.Fragment_fragmentReturnTransition));
1497        setExitTransition(loadTransition(context, a, getExitTransition(), null,
1498                com.android.internal.R.styleable.Fragment_fragmentExitTransition));
1499
1500        setReenterTransition(loadTransition(context, a, getReenterTransition(),
1501                USE_DEFAULT_TRANSITION,
1502                com.android.internal.R.styleable.Fragment_fragmentReenterTransition));
1503        setSharedElementEnterTransition(loadTransition(context, a,
1504                getSharedElementEnterTransition(), null,
1505                com.android.internal.R.styleable.Fragment_fragmentSharedElementEnterTransition));
1506        setSharedElementReturnTransition(loadTransition(context, a,
1507                getSharedElementReturnTransition(), USE_DEFAULT_TRANSITION,
1508                com.android.internal.R.styleable.Fragment_fragmentSharedElementReturnTransition));
1509        boolean isEnterSet;
1510        boolean isReturnSet;
1511        if (mAnimationInfo == null) {
1512            isEnterSet = false;
1513            isReturnSet = false;
1514        } else {
1515            isEnterSet = mAnimationInfo.mAllowEnterTransitionOverlap != null;
1516            isReturnSet = mAnimationInfo.mAllowReturnTransitionOverlap != null;
1517        }
1518        if (!isEnterSet) {
1519            setAllowEnterTransitionOverlap(a.getBoolean(
1520                    com.android.internal.R.styleable.Fragment_fragmentAllowEnterTransitionOverlap,
1521                    true));
1522        }
1523        if (!isReturnSet) {
1524            setAllowReturnTransitionOverlap(a.getBoolean(
1525                    com.android.internal.R.styleable.Fragment_fragmentAllowReturnTransitionOverlap,
1526                    true));
1527        }
1528        a.recycle();
1529
1530        final Activity hostActivity = mHost == null ? null : mHost.getActivity();
1531        if (hostActivity != null) {
1532            mCalled = false;
1533            onInflate(hostActivity, attrs, savedInstanceState);
1534        }
1535    }
1536
1537    /**
1538     * @deprecated Use {@link #onInflate(Context, AttributeSet, Bundle)} instead.
1539     */
1540    @Deprecated
1541    @CallSuper
1542    public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
1543        mCalled = true;
1544    }
1545
1546    /**
1547     * Called when a fragment is attached as a child of this fragment.
1548     *
1549     * <p>This is called after the attached fragment's <code>onAttach</code> and before
1550     * the attached fragment's <code>onCreate</code> if the fragment has not yet had a previous
1551     * call to <code>onCreate</code>.</p>
1552     *
1553     * @param childFragment child fragment being attached
1554     */
1555    public void onAttachFragment(Fragment childFragment) {
1556    }
1557
1558    /**
1559     * Called when a fragment is first attached to its context.
1560     * {@link #onCreate(Bundle)} will be called after this.
1561     */
1562    @CallSuper
1563    public void onAttach(Context context) {
1564        mCalled = true;
1565        final Activity hostActivity = mHost == null ? null : mHost.getActivity();
1566        if (hostActivity != null) {
1567            mCalled = false;
1568            onAttach(hostActivity);
1569        }
1570    }
1571
1572    /**
1573     * @deprecated Use {@link #onAttach(Context)} instead.
1574     */
1575    @Deprecated
1576    @CallSuper
1577    public void onAttach(Activity activity) {
1578        mCalled = true;
1579    }
1580
1581    /**
1582     * Called when a fragment loads an animation.
1583     */
1584    public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
1585        return null;
1586    }
1587
1588    /**
1589     * Called to do initial creation of a fragment.  This is called after
1590     * {@link #onAttach(Activity)} and before
1591     * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}, but is not called if the fragment
1592     * instance is retained across Activity re-creation (see {@link #setRetainInstance(boolean)}).
1593     *
1594     * <p>Note that this can be called while the fragment's activity is
1595     * still in the process of being created.  As such, you can not rely
1596     * on things like the activity's content view hierarchy being initialized
1597     * at this point.  If you want to do work once the activity itself is
1598     * created, see {@link #onActivityCreated(Bundle)}.
1599     *
1600     * <p>If your app's <code>targetSdkVersion</code> is {@link android.os.Build.VERSION_CODES#M}
1601     * or lower, child fragments being restored from the savedInstanceState are restored after
1602     * <code>onCreate</code> returns. When targeting {@link android.os.Build.VERSION_CODES#N} or
1603     * above and running on an N or newer platform version
1604     * they are restored by <code>Fragment.onCreate</code>.</p>
1605     *
1606     * @param savedInstanceState If the fragment is being re-created from
1607     * a previous saved state, this is the state.
1608     */
1609    @CallSuper
1610    public void onCreate(@Nullable Bundle savedInstanceState) {
1611        mCalled = true;
1612        final Context context = getContext();
1613        final int version = context != null ? context.getApplicationInfo().targetSdkVersion : 0;
1614        if (version >= Build.VERSION_CODES.N) {
1615            restoreChildFragmentState(savedInstanceState, true);
1616            if (mChildFragmentManager != null
1617                    && !mChildFragmentManager.isStateAtLeast(Fragment.CREATED)) {
1618                mChildFragmentManager.dispatchCreate();
1619            }
1620        }
1621    }
1622
1623    void restoreChildFragmentState(@Nullable Bundle savedInstanceState, boolean provideNonConfig) {
1624        if (savedInstanceState != null) {
1625            Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
1626            if (p != null) {
1627                if (mChildFragmentManager == null) {
1628                    instantiateChildFragmentManager();
1629                }
1630                mChildFragmentManager.restoreAllState(p, provideNonConfig ? mChildNonConfig : null);
1631                mChildNonConfig = null;
1632                mChildFragmentManager.dispatchCreate();
1633            }
1634        }
1635    }
1636
1637    /**
1638     * Called to have the fragment instantiate its user interface view.
1639     * This is optional, and non-graphical fragments can return null (which
1640     * is the default implementation).  This will be called between
1641     * {@link #onCreate(Bundle)} and {@link #onActivityCreated(Bundle)}.
1642     *
1643     * <p>If you return a View from here, you will later be called in
1644     * {@link #onDestroyView} when the view is being released.
1645     *
1646     * @param inflater The LayoutInflater object that can be used to inflate
1647     * any views in the fragment,
1648     * @param container If non-null, this is the parent view that the fragment's
1649     * UI should be attached to.  The fragment should not add the view itself,
1650     * but this can be used to generate the LayoutParams of the view.
1651     * @param savedInstanceState If non-null, this fragment is being re-constructed
1652     * from a previous saved state as given here.
1653     *
1654     * @return Return the View for the fragment's UI, or null.
1655     */
1656    @Nullable
1657    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
1658            Bundle savedInstanceState) {
1659        return null;
1660    }
1661
1662    /**
1663     * Called immediately after {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
1664     * has returned, but before any saved state has been restored in to the view.
1665     * This gives subclasses a chance to initialize themselves once
1666     * they know their view hierarchy has been completely created.  The fragment's
1667     * view hierarchy is not however attached to its parent at this point.
1668     * @param view The View returned by {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
1669     * @param savedInstanceState If non-null, this fragment is being re-constructed
1670     * from a previous saved state as given here.
1671     */
1672    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
1673    }
1674
1675    /**
1676     * Get the root view for the fragment's layout (the one returned by {@link #onCreateView}),
1677     * if provided.
1678     *
1679     * @return The fragment's root view, or null if it has no layout.
1680     */
1681    @Nullable
1682    public View getView() {
1683        return mView;
1684    }
1685
1686    /**
1687     * Called when the fragment's activity has been created and this
1688     * fragment's view hierarchy instantiated.  It can be used to do final
1689     * initialization once these pieces are in place, such as retrieving
1690     * views or restoring state.  It is also useful for fragments that use
1691     * {@link #setRetainInstance(boolean)} to retain their instance,
1692     * as this callback tells the fragment when it is fully associated with
1693     * the new activity instance.  This is called after {@link #onCreateView}
1694     * and before {@link #onViewStateRestored(Bundle)}.
1695     *
1696     * @param savedInstanceState If the fragment is being re-created from
1697     * a previous saved state, this is the state.
1698     */
1699    @CallSuper
1700    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
1701        mCalled = true;
1702    }
1703
1704    /**
1705     * Called when all saved state has been restored into the view hierarchy
1706     * of the fragment.  This can be used to do initialization based on saved
1707     * state that you are letting the view hierarchy track itself, such as
1708     * whether check box widgets are currently checked.  This is called
1709     * after {@link #onActivityCreated(Bundle)} and before
1710     * {@link #onStart()}.
1711     *
1712     * @param savedInstanceState If the fragment is being re-created from
1713     * a previous saved state, this is the state.
1714     */
1715    @CallSuper
1716    public void onViewStateRestored(Bundle savedInstanceState) {
1717        mCalled = true;
1718    }
1719
1720    /**
1721     * Called when the Fragment is visible to the user.  This is generally
1722     * tied to {@link Activity#onStart() Activity.onStart} of the containing
1723     * Activity's lifecycle.
1724     */
1725    @CallSuper
1726    public void onStart() {
1727        mCalled = true;
1728
1729        if (!mLoadersStarted) {
1730            mLoadersStarted = true;
1731            if (!mCheckedForLoaderManager) {
1732                mCheckedForLoaderManager = true;
1733                mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
1734            } else if (mLoaderManager != null) {
1735                mLoaderManager.doStart();
1736            }
1737        }
1738    }
1739
1740    /**
1741     * Called when the fragment is visible to the user and actively running.
1742     * This is generally
1743     * tied to {@link Activity#onResume() Activity.onResume} of the containing
1744     * Activity's lifecycle.
1745     */
1746    @CallSuper
1747    public void onResume() {
1748        mCalled = true;
1749    }
1750
1751    /**
1752     * Called to ask the fragment to save its current dynamic state, so it
1753     * can later be reconstructed in a new instance of its process is
1754     * restarted.  If a new instance of the fragment later needs to be
1755     * created, the data you place in the Bundle here will be available
1756     * in the Bundle given to {@link #onCreate(Bundle)},
1757     * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}, and
1758     * {@link #onActivityCreated(Bundle)}.
1759     *
1760     * <p>This corresponds to {@link Activity#onSaveInstanceState(Bundle)
1761     * Activity.onSaveInstanceState(Bundle)} and most of the discussion there
1762     * applies here as well.  Note however: <em>this method may be called
1763     * at any time before {@link #onDestroy()}</em>.  There are many situations
1764     * where a fragment may be mostly torn down (such as when placed on the
1765     * back stack with no UI showing), but its state will not be saved until
1766     * its owning activity actually needs to save its state.
1767     *
1768     * @param outState Bundle in which to place your saved state.
1769     */
1770    public void onSaveInstanceState(Bundle outState) {
1771    }
1772
1773    /**
1774     * Called when the Fragment's activity changes from fullscreen mode to multi-window mode and
1775     * visa-versa. This is generally tied to {@link Activity#onMultiWindowModeChanged} of the
1776     * containing Activity. This method provides the same configuration that will be sent in the
1777     * following {@link #onConfigurationChanged(Configuration)} call after the activity enters this
1778     * mode.
1779     *
1780     * @param isInMultiWindowMode True if the activity is in multi-window mode.
1781     * @param newConfig The new configuration of the activity with the state
1782     *                  {@param isInMultiWindowMode}.
1783     */
1784    public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
1785        onMultiWindowModeChanged(isInMultiWindowMode);
1786    }
1787
1788    /**
1789     * Called when the Fragment's activity changes from fullscreen mode to multi-window mode and
1790     * visa-versa. This is generally tied to {@link Activity#onMultiWindowModeChanged} of the
1791     * containing Activity.
1792     *
1793     * @param isInMultiWindowMode True if the activity is in multi-window mode.
1794     *
1795     * @deprecated Use {@link #onMultiWindowModeChanged(boolean, Configuration)} instead.
1796     */
1797    @Deprecated
1798    public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
1799    }
1800
1801    /**
1802     * Called by the system when the activity changes to and from picture-in-picture mode. This is
1803     * generally tied to {@link Activity#onPictureInPictureModeChanged} of the containing Activity.
1804     * This method provides the same configuration that will be sent in the following
1805     * {@link #onConfigurationChanged(Configuration)} call after the activity enters this mode.
1806     *
1807     * @param isInPictureInPictureMode True if the activity is in picture-in-picture mode.
1808     * @param newConfig The new configuration of the activity with the state
1809     *                  {@param isInPictureInPictureMode}.
1810     */
1811    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode,
1812            Configuration newConfig) {
1813        onPictureInPictureModeChanged(isInPictureInPictureMode);
1814    }
1815
1816    /**
1817     * Called by the system when the activity changes to and from picture-in-picture mode. This is
1818     * generally tied to {@link Activity#onPictureInPictureModeChanged} of the containing Activity.
1819     *
1820     * @param isInPictureInPictureMode True if the activity is in picture-in-picture mode.
1821     *
1822     * @deprecated Use {@link #onPictureInPictureModeChanged(boolean, Configuration)} instead.
1823     */
1824    @Deprecated
1825    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
1826    }
1827
1828    @CallSuper
1829    public void onConfigurationChanged(Configuration newConfig) {
1830        mCalled = true;
1831    }
1832
1833    /**
1834     * Called when the Fragment is no longer resumed.  This is generally
1835     * tied to {@link Activity#onPause() Activity.onPause} of the containing
1836     * Activity's lifecycle.
1837     */
1838    @CallSuper
1839    public void onPause() {
1840        mCalled = true;
1841    }
1842
1843    /**
1844     * Called when the Fragment is no longer started.  This is generally
1845     * tied to {@link Activity#onStop() Activity.onStop} of the containing
1846     * Activity's lifecycle.
1847     */
1848    @CallSuper
1849    public void onStop() {
1850        mCalled = true;
1851    }
1852
1853    @CallSuper
1854    public void onLowMemory() {
1855        mCalled = true;
1856    }
1857
1858    @CallSuper
1859    public void onTrimMemory(int level) {
1860        mCalled = true;
1861    }
1862
1863    /**
1864     * Called when the view previously created by {@link #onCreateView} has
1865     * been detached from the fragment.  The next time the fragment needs
1866     * to be displayed, a new view will be created.  This is called
1867     * after {@link #onStop()} and before {@link #onDestroy()}.  It is called
1868     * <em>regardless</em> of whether {@link #onCreateView} returned a
1869     * non-null view.  Internally it is called after the view's state has
1870     * been saved but before it has been removed from its parent.
1871     */
1872    @CallSuper
1873    public void onDestroyView() {
1874        mCalled = true;
1875    }
1876
1877    /**
1878     * Called when the fragment is no longer in use.  This is called
1879     * after {@link #onStop()} and before {@link #onDetach()}.
1880     */
1881    @CallSuper
1882    public void onDestroy() {
1883        mCalled = true;
1884        //Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager
1885        //        + " mLoaderManager=" + mLoaderManager);
1886        if (!mCheckedForLoaderManager) {
1887            mCheckedForLoaderManager = true;
1888            mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
1889        }
1890        if (mLoaderManager != null) {
1891            mLoaderManager.doDestroy();
1892        }
1893    }
1894
1895    /**
1896     * Called by the fragment manager once this fragment has been removed,
1897     * so that we don't have any left-over state if the application decides
1898     * to re-use the instance.  This only clears state that the framework
1899     * internally manages, not things the application sets.
1900     */
1901    void initState() {
1902        mIndex = -1;
1903        mWho = null;
1904        mAdded = false;
1905        mRemoving = false;
1906        mFromLayout = false;
1907        mInLayout = false;
1908        mRestored = false;
1909        mBackStackNesting = 0;
1910        mFragmentManager = null;
1911        mChildFragmentManager = null;
1912        mHost = null;
1913        mFragmentId = 0;
1914        mContainerId = 0;
1915        mTag = null;
1916        mHidden = false;
1917        mDetached = false;
1918        mRetaining = false;
1919        mLoaderManager = null;
1920        mLoadersStarted = false;
1921        mCheckedForLoaderManager = false;
1922    }
1923
1924    /**
1925     * Called when the fragment is no longer attached to its activity.  This is called after
1926     * {@link #onDestroy()}, except in the cases where the fragment instance is retained across
1927     * Activity re-creation (see {@link #setRetainInstance(boolean)}), in which case it is called
1928     * after {@link #onStop()}.
1929     */
1930    @CallSuper
1931    public void onDetach() {
1932        mCalled = true;
1933    }
1934
1935    /**
1936     * Initialize the contents of the Activity's standard options menu.  You
1937     * should place your menu items in to <var>menu</var>.  For this method
1938     * to be called, you must have first called {@link #setHasOptionsMenu}.  See
1939     * {@link Activity#onCreateOptionsMenu(Menu) Activity.onCreateOptionsMenu}
1940     * for more information.
1941     *
1942     * @param menu The options menu in which you place your items.
1943     *
1944     * @see #setHasOptionsMenu
1945     * @see #onPrepareOptionsMenu
1946     * @see #onOptionsItemSelected
1947     */
1948    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
1949    }
1950
1951    /**
1952     * Prepare the Screen's standard options menu to be displayed.  This is
1953     * called right before the menu is shown, every time it is shown.  You can
1954     * use this method to efficiently enable/disable items or otherwise
1955     * dynamically modify the contents.  See
1956     * {@link Activity#onPrepareOptionsMenu(Menu) Activity.onPrepareOptionsMenu}
1957     * for more information.
1958     *
1959     * @param menu The options menu as last shown or first initialized by
1960     *             onCreateOptionsMenu().
1961     *
1962     * @see #setHasOptionsMenu
1963     * @see #onCreateOptionsMenu
1964     */
1965    public void onPrepareOptionsMenu(Menu menu) {
1966    }
1967
1968    /**
1969     * Called when this fragment's option menu items are no longer being
1970     * included in the overall options menu.  Receiving this call means that
1971     * the menu needed to be rebuilt, but this fragment's items were not
1972     * included in the newly built menu (its {@link #onCreateOptionsMenu(Menu, MenuInflater)}
1973     * was not called).
1974     */
1975    public void onDestroyOptionsMenu() {
1976    }
1977
1978    /**
1979     * This hook is called whenever an item in your options menu is selected.
1980     * The default implementation simply returns false to have the normal
1981     * processing happen (calling the item's Runnable or sending a message to
1982     * its Handler as appropriate).  You can use this method for any items
1983     * for which you would like to do processing without those other
1984     * facilities.
1985     *
1986     * <p>Derived classes should call through to the base class for it to
1987     * perform the default menu handling.
1988     *
1989     * @param item The menu item that was selected.
1990     *
1991     * @return boolean Return false to allow normal menu processing to
1992     *         proceed, true to consume it here.
1993     *
1994     * @see #onCreateOptionsMenu
1995     */
1996    public boolean onOptionsItemSelected(MenuItem item) {
1997        return false;
1998    }
1999
2000    /**
2001     * This hook is called whenever the options menu is being closed (either by the user canceling
2002     * the menu with the back/menu button, or when an item is selected).
2003     *
2004     * @param menu The options menu as last shown or first initialized by
2005     *             onCreateOptionsMenu().
2006     */
2007    public void onOptionsMenuClosed(Menu menu) {
2008    }
2009
2010    /**
2011     * Called when a context menu for the {@code view} is about to be shown.
2012     * Unlike {@link #onCreateOptionsMenu}, this will be called every
2013     * time the context menu is about to be shown and should be populated for
2014     * the view (or item inside the view for {@link AdapterView} subclasses,
2015     * this can be found in the {@code menuInfo})).
2016     * <p>
2017     * Use {@link #onContextItemSelected(android.view.MenuItem)} to know when an
2018     * item has been selected.
2019     * <p>
2020     * The default implementation calls up to
2021     * {@link Activity#onCreateContextMenu Activity.onCreateContextMenu}, though
2022     * you can not call this implementation if you don't want that behavior.
2023     * <p>
2024     * It is not safe to hold onto the context menu after this method returns.
2025     * {@inheritDoc}
2026     */
2027    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
2028        getActivity().onCreateContextMenu(menu, v, menuInfo);
2029    }
2030
2031    /**
2032     * Registers a context menu to be shown for the given view (multiple views
2033     * can show the context menu). This method will set the
2034     * {@link OnCreateContextMenuListener} on the view to this fragment, so
2035     * {@link #onCreateContextMenu(ContextMenu, View, ContextMenuInfo)} will be
2036     * called when it is time to show the context menu.
2037     *
2038     * @see #unregisterForContextMenu(View)
2039     * @param view The view that should show a context menu.
2040     */
2041    public void registerForContextMenu(View view) {
2042        view.setOnCreateContextMenuListener(this);
2043    }
2044
2045    /**
2046     * Prevents a context menu to be shown for the given view. This method will
2047     * remove the {@link OnCreateContextMenuListener} on the view.
2048     *
2049     * @see #registerForContextMenu(View)
2050     * @param view The view that should stop showing a context menu.
2051     */
2052    public void unregisterForContextMenu(View view) {
2053        view.setOnCreateContextMenuListener(null);
2054    }
2055
2056    /**
2057     * This hook is called whenever an item in a context menu is selected. The
2058     * default implementation simply returns false to have the normal processing
2059     * happen (calling the item's Runnable or sending a message to its Handler
2060     * as appropriate). You can use this method for any items for which you
2061     * would like to do processing without those other facilities.
2062     * <p>
2063     * Use {@link MenuItem#getMenuInfo()} to get extra information set by the
2064     * View that added this menu item.
2065     * <p>
2066     * Derived classes should call through to the base class for it to perform
2067     * the default menu handling.
2068     *
2069     * @param item The context menu item that was selected.
2070     * @return boolean Return false to allow normal context menu processing to
2071     *         proceed, true to consume it here.
2072     */
2073    public boolean onContextItemSelected(MenuItem item) {
2074        return false;
2075    }
2076
2077    /**
2078     * When custom transitions are used with Fragments, the enter transition callback
2079     * is called when this Fragment is attached or detached when not popping the back stack.
2080     *
2081     * @param callback Used to manipulate the shared element transitions on this Fragment
2082     *                 when added not as a pop from the back stack.
2083     */
2084    public void setEnterSharedElementCallback(SharedElementCallback callback) {
2085        if (callback == null) {
2086            if (mAnimationInfo == null) {
2087                return; // already a null callback
2088            }
2089            callback = SharedElementCallback.NULL_CALLBACK;
2090        }
2091        ensureAnimationInfo().mEnterTransitionCallback = callback;
2092    }
2093
2094    /**
2095     * When custom transitions are used with Fragments, the exit transition callback
2096     * is called when this Fragment is attached or detached when popping the back stack.
2097     *
2098     * @param callback Used to manipulate the shared element transitions on this Fragment
2099     *                 when added as a pop from the back stack.
2100     */
2101    public void setExitSharedElementCallback(SharedElementCallback callback) {
2102        if (callback == null) {
2103            if (mAnimationInfo == null) {
2104                return; // already a null callback
2105            }
2106            callback = SharedElementCallback.NULL_CALLBACK;
2107        }
2108        ensureAnimationInfo().mExitTransitionCallback = callback;
2109    }
2110
2111    /**
2112     * Sets the Transition that will be used to move Views into the initial scene. The entering
2113     * Views will be those that are regular Views or ViewGroups that have
2114     * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
2115     * {@link android.transition.Visibility} as entering is governed by changing visibility from
2116     * {@link View#INVISIBLE} to {@link View#VISIBLE}. If <code>transition</code> is null,
2117     * entering Views will remain unaffected.
2118     *
2119     * @param transition The Transition to use to move Views into the initial Scene.
2120     * @attr ref android.R.styleable#Fragment_fragmentEnterTransition
2121     */
2122    public void setEnterTransition(Transition transition) {
2123        if (shouldChangeTransition(transition, null)) {
2124            ensureAnimationInfo().mEnterTransition = transition;
2125        }
2126    }
2127
2128    /**
2129     * Returns the Transition that will be used to move Views into the initial scene. The entering
2130     * Views will be those that are regular Views or ViewGroups that have
2131     * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
2132     * {@link android.transition.Visibility} as entering is governed by changing visibility from
2133     * {@link View#INVISIBLE} to {@link View#VISIBLE}.
2134     *
2135     * @return the Transition to use to move Views into the initial Scene.
2136     * @attr ref android.R.styleable#Fragment_fragmentEnterTransition
2137     */
2138    public Transition getEnterTransition() {
2139        if (mAnimationInfo == null) {
2140            return null;
2141        }
2142        return mAnimationInfo.mEnterTransition;
2143    }
2144
2145    /**
2146     * Sets the Transition that will be used to move Views out of the scene when the Fragment is
2147     * preparing to be removed, hidden, or detached because of popping the back stack. The exiting
2148     * Views will be those that are regular Views or ViewGroups that have
2149     * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
2150     * {@link android.transition.Visibility} as entering is governed by changing visibility from
2151     * {@link View#VISIBLE} to {@link View#INVISIBLE}. If <code>transition</code> is null,
2152     * entering Views will remain unaffected. If nothing is set, the default will be to
2153     * use the same value as set in {@link #setEnterTransition(android.transition.Transition)}.
2154     *
2155     * @param transition The Transition to use to move Views out of the Scene when the Fragment
2156     *                   is preparing to close.
2157     * @attr ref android.R.styleable#Fragment_fragmentExitTransition
2158     */
2159    public void setReturnTransition(Transition transition) {
2160        if (shouldChangeTransition(transition, USE_DEFAULT_TRANSITION)) {
2161            ensureAnimationInfo().mReturnTransition = transition;
2162        }
2163    }
2164
2165    /**
2166     * Returns the Transition that will be used to move Views out of the scene when the Fragment is
2167     * preparing to be removed, hidden, or detached because of popping the back stack. The exiting
2168     * Views will be those that are regular Views or ViewGroups that have
2169     * {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
2170     * {@link android.transition.Visibility} as entering is governed by changing visibility from
2171     * {@link View#VISIBLE} to {@link View#INVISIBLE}. If <code>transition</code> is null,
2172     * entering Views will remain unaffected.
2173     *
2174     * @return the Transition to use to move Views out of the Scene when the Fragment
2175     *         is preparing to close.
2176     * @attr ref android.R.styleable#Fragment_fragmentExitTransition
2177     */
2178    public Transition getReturnTransition() {
2179        if (mAnimationInfo == null) {
2180            return null;
2181        }
2182        return mAnimationInfo.mReturnTransition == USE_DEFAULT_TRANSITION ? getEnterTransition()
2183                : mAnimationInfo.mReturnTransition;
2184    }
2185
2186    /**
2187     * Sets the Transition that will be used to move Views out of the scene when the
2188     * fragment is removed, hidden, or detached when not popping the back stack.
2189     * The exiting Views will be those that are regular Views or ViewGroups that
2190     * have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
2191     * {@link android.transition.Visibility} as exiting is governed by changing visibility
2192     * from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will
2193     * remain unaffected.
2194     *
2195     * @param transition The Transition to use to move Views out of the Scene when the Fragment
2196     *                   is being closed not due to popping the back stack.
2197     * @attr ref android.R.styleable#Fragment_fragmentExitTransition
2198     */
2199    public void setExitTransition(Transition transition) {
2200        if (shouldChangeTransition(transition, null)) {
2201            ensureAnimationInfo().mExitTransition = transition;
2202        }
2203    }
2204
2205    /**
2206     * Returns the Transition that will be used to move Views out of the scene when the
2207     * fragment is removed, hidden, or detached when not popping the back stack.
2208     * The exiting Views will be those that are regular Views or ViewGroups that
2209     * have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
2210     * {@link android.transition.Visibility} as exiting is governed by changing visibility
2211     * from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will
2212     * remain unaffected.
2213     *
2214     * @return the Transition to use to move Views out of the Scene when the Fragment
2215     *         is being closed not due to popping the back stack.
2216     * @attr ref android.R.styleable#Fragment_fragmentExitTransition
2217     */
2218    public Transition getExitTransition() {
2219        if (mAnimationInfo == null) {
2220            return null;
2221        }
2222        return mAnimationInfo.mExitTransition;
2223    }
2224
2225    /**
2226     * Sets the Transition that will be used to move Views in to the scene when returning due
2227     * to popping a back stack. The entering Views will be those that are regular Views
2228     * or ViewGroups that have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions
2229     * will extend {@link android.transition.Visibility} as exiting is governed by changing
2230     * visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null,
2231     * the views will remain unaffected. If nothing is set, the default will be to use the same
2232     * transition as {@link #setExitTransition(android.transition.Transition)}.
2233     *
2234     * @param transition The Transition to use to move Views into the scene when reentering from a
2235     *                   previously-started Activity.
2236     * @attr ref android.R.styleable#Fragment_fragmentReenterTransition
2237     */
2238    public void setReenterTransition(Transition transition) {
2239        if (shouldChangeTransition(transition, USE_DEFAULT_TRANSITION)) {
2240            ensureAnimationInfo().mReenterTransition = transition;
2241        }
2242    }
2243
2244    /**
2245     * Returns the Transition that will be used to move Views in to the scene when returning due
2246     * to popping a back stack. The entering Views will be those that are regular Views
2247     * or ViewGroups that have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions
2248     * will extend {@link android.transition.Visibility} as exiting is governed by changing
2249     * visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null,
2250     * the views will remain unaffected. If nothing is set, the default will be to use the same
2251     * transition as {@link #setExitTransition(android.transition.Transition)}.
2252     *
2253     * @return the Transition to use to move Views into the scene when reentering from a
2254     *                   previously-started Activity.
2255     * @attr ref android.R.styleable#Fragment_fragmentReenterTransition
2256     */
2257    public Transition getReenterTransition() {
2258        if (mAnimationInfo == null) {
2259            return null;
2260        }
2261        return mAnimationInfo.mReenterTransition == USE_DEFAULT_TRANSITION ? getExitTransition()
2262                : mAnimationInfo.mReenterTransition;
2263    }
2264
2265    /**
2266     * Sets the Transition that will be used for shared elements transferred into the content
2267     * Scene. Typical Transitions will affect size and location, such as
2268     * {@link android.transition.ChangeBounds}. A null
2269     * value will cause transferred shared elements to blink to the final position.
2270     *
2271     * @param transition The Transition to use for shared elements transferred into the content
2272     *                   Scene.
2273     * @attr ref android.R.styleable#Fragment_fragmentSharedElementEnterTransition
2274     */
2275    public void setSharedElementEnterTransition(Transition transition) {
2276        if (shouldChangeTransition(transition, null)) {
2277            ensureAnimationInfo().mSharedElementEnterTransition = transition;
2278        }
2279    }
2280
2281    /**
2282     * Returns the Transition that will be used for shared elements transferred into the content
2283     * Scene. Typical Transitions will affect size and location, such as
2284     * {@link android.transition.ChangeBounds}. A null
2285     * value will cause transferred shared elements to blink to the final position.
2286     *
2287     * @return The Transition to use for shared elements transferred into the content
2288     *                   Scene.
2289     * @attr ref android.R.styleable#Fragment_fragmentSharedElementEnterTransition
2290     */
2291    public Transition getSharedElementEnterTransition() {
2292        if (mAnimationInfo == null) {
2293            return null;
2294        }
2295        return mAnimationInfo.mSharedElementEnterTransition;
2296    }
2297
2298    /**
2299     * Sets the Transition that will be used for shared elements transferred back during a
2300     * pop of the back stack. This Transition acts in the leaving Fragment.
2301     * Typical Transitions will affect size and location, such as
2302     * {@link android.transition.ChangeBounds}. A null
2303     * value will cause transferred shared elements to blink to the final position.
2304     * If no value is set, the default will be to use the same value as
2305     * {@link #setSharedElementEnterTransition(android.transition.Transition)}.
2306     *
2307     * @param transition The Transition to use for shared elements transferred out of the content
2308     *                   Scene.
2309     * @attr ref android.R.styleable#Fragment_fragmentSharedElementReturnTransition
2310     */
2311    public void setSharedElementReturnTransition(Transition transition) {
2312        if (shouldChangeTransition(transition, USE_DEFAULT_TRANSITION)) {
2313            ensureAnimationInfo().mSharedElementReturnTransition = transition;
2314        }
2315    }
2316
2317    /**
2318     * Return the Transition that will be used for shared elements transferred back during a
2319     * pop of the back stack. This Transition acts in the leaving Fragment.
2320     * Typical Transitions will affect size and location, such as
2321     * {@link android.transition.ChangeBounds}. A null
2322     * value will cause transferred shared elements to blink to the final position.
2323     * If no value is set, the default will be to use the same value as
2324     * {@link #setSharedElementEnterTransition(android.transition.Transition)}.
2325     *
2326     * @return The Transition to use for shared elements transferred out of the content
2327     *                   Scene.
2328     * @attr ref android.R.styleable#Fragment_fragmentSharedElementReturnTransition
2329     */
2330    public Transition getSharedElementReturnTransition() {
2331        if (mAnimationInfo == null) {
2332            return null;
2333        }
2334        return mAnimationInfo.mSharedElementReturnTransition == USE_DEFAULT_TRANSITION
2335                ? getSharedElementEnterTransition()
2336                : mAnimationInfo.mSharedElementReturnTransition;
2337    }
2338
2339    /**
2340     * Sets whether the the exit transition and enter transition overlap or not.
2341     * When true, the enter transition will start as soon as possible. When false, the
2342     * enter transition will wait until the exit transition completes before starting.
2343     *
2344     * @param allow true to start the enter transition when possible or false to
2345     *              wait until the exiting transition completes.
2346     * @attr ref android.R.styleable#Fragment_fragmentAllowEnterTransitionOverlap
2347     */
2348    public void setAllowEnterTransitionOverlap(boolean allow) {
2349        ensureAnimationInfo().mAllowEnterTransitionOverlap = allow;
2350    }
2351
2352    /**
2353     * Returns whether the the exit transition and enter transition overlap or not.
2354     * When true, the enter transition will start as soon as possible. When false, the
2355     * enter transition will wait until the exit transition completes before starting.
2356     *
2357     * @return true when the enter transition should start as soon as possible or false to
2358     * when it should wait until the exiting transition completes.
2359     * @attr ref android.R.styleable#Fragment_fragmentAllowEnterTransitionOverlap
2360     */
2361    public boolean getAllowEnterTransitionOverlap() {
2362        return (mAnimationInfo == null || mAnimationInfo.mAllowEnterTransitionOverlap == null)
2363                ? true : mAnimationInfo.mAllowEnterTransitionOverlap;
2364    }
2365
2366    /**
2367     * Sets whether the the return transition and reenter transition overlap or not.
2368     * When true, the reenter transition will start as soon as possible. When false, the
2369     * reenter transition will wait until the return transition completes before starting.
2370     *
2371     * @param allow true to start the reenter transition when possible or false to wait until the
2372     *              return transition completes.
2373     * @attr ref android.R.styleable#Fragment_fragmentAllowReturnTransitionOverlap
2374     */
2375    public void setAllowReturnTransitionOverlap(boolean allow) {
2376        ensureAnimationInfo().mAllowReturnTransitionOverlap = allow;
2377    }
2378
2379    /**
2380     * Returns whether the the return transition and reenter transition overlap or not.
2381     * When true, the reenter transition will start as soon as possible. When false, the
2382     * reenter transition will wait until the return transition completes before starting.
2383     *
2384     * @return true to start the reenter transition when possible or false to wait until the
2385     *         return transition completes.
2386     * @attr ref android.R.styleable#Fragment_fragmentAllowReturnTransitionOverlap
2387     */
2388    public boolean getAllowReturnTransitionOverlap() {
2389        return (mAnimationInfo == null || mAnimationInfo.mAllowReturnTransitionOverlap == null)
2390                ? true : mAnimationInfo.mAllowReturnTransitionOverlap;
2391    }
2392
2393    /**
2394     * Postpone the entering Fragment transition until {@link #startPostponedEnterTransition()}
2395     * or {@link FragmentManager#executePendingTransactions()} has been called.
2396     * <p>
2397     * This method gives the Fragment the ability to delay Fragment animations
2398     * until all data is loaded. Until then, the added, shown, and
2399     * attached Fragments will be INVISIBLE and removed, hidden, and detached Fragments won't
2400     * be have their Views removed. The transaction runs when all postponed added Fragments in the
2401     * transaction have called {@link #startPostponedEnterTransition()}.
2402     * <p>
2403     * This method should be called before being added to the FragmentTransaction or
2404     * in {@link #onCreate(Bundle), {@link #onAttach(Context)}, or
2405     * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}}.
2406     * {@link #startPostponedEnterTransition()} must be called to allow the Fragment to
2407     * start the transitions.
2408     * <p>
2409     * When a FragmentTransaction is started that may affect a postponed FragmentTransaction,
2410     * based on which containers are in their operations, the postponed FragmentTransaction
2411     * will have its start triggered. The early triggering may result in faulty or nonexistent
2412     * animations in the postponed transaction. FragmentTransactions that operate only on
2413     * independent containers will not interfere with each other's postponement.
2414     * <p>
2415     * Calling postponeEnterTransition on Fragments with a null View will not postpone the
2416     * transition. Likewise, postponement only works if FragmentTransaction optimizations are
2417     * enabled.
2418     *
2419     * @see Activity#postponeEnterTransition()
2420     * @see FragmentTransaction#setAllowOptimization(boolean)
2421     */
2422    public void postponeEnterTransition() {
2423        ensureAnimationInfo().mEnterTransitionPostponed = true;
2424    }
2425
2426    /**
2427     * Begin postponed transitions after {@link #postponeEnterTransition()} was called.
2428     * If postponeEnterTransition() was called, you must call startPostponedEnterTransition()
2429     * or {@link FragmentManager#executePendingTransactions()} to complete the FragmentTransaction.
2430     * If postponement was interrupted with {@link FragmentManager#executePendingTransactions()},
2431     * before {@code startPostponedEnterTransition()}, animations may not run or may execute
2432     * improperly.
2433     *
2434     * @see Activity#startPostponedEnterTransition()
2435     */
2436    public void startPostponedEnterTransition() {
2437        if (mFragmentManager == null || mFragmentManager.mHost == null) {
2438                ensureAnimationInfo().mEnterTransitionPostponed = false;
2439        } else if (Looper.myLooper() != mFragmentManager.mHost.getHandler().getLooper()) {
2440            mFragmentManager.mHost.getHandler().
2441                    postAtFrontOfQueue(this::callStartTransitionListener);
2442        } else {
2443            callStartTransitionListener();
2444        }
2445    }
2446
2447    /**
2448     * Calls the start transition listener. This must be called on the UI thread.
2449     */
2450    private void callStartTransitionListener() {
2451        final OnStartEnterTransitionListener listener;
2452        if (mAnimationInfo == null) {
2453            listener = null;
2454        } else {
2455            mAnimationInfo.mEnterTransitionPostponed = false;
2456            listener = mAnimationInfo.mStartEnterTransitionListener;
2457            mAnimationInfo.mStartEnterTransitionListener = null;
2458        }
2459        if (listener != null) {
2460            listener.onStartEnterTransition();
2461        }
2462    }
2463
2464    /**
2465     * Returns true if mAnimationInfo is not null or the transition differs from the default value.
2466     * This is broken out to ensure mAnimationInfo is properly locked when checking.
2467     */
2468    private boolean shouldChangeTransition(Transition transition, Transition defaultValue) {
2469        if (transition == defaultValue) {
2470            return mAnimationInfo != null;
2471        }
2472        return true;
2473    }
2474
2475    /**
2476     * Print the Fragments's state into the given stream.
2477     *
2478     * @param prefix Text to print at the front of each line.
2479     * @param fd The raw file descriptor that the dump is being sent to.
2480     * @param writer The PrintWriter to which you should dump your state.  This will be
2481     * closed for you after you return.
2482     * @param args additional arguments to the dump request.
2483     */
2484    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
2485        writer.print(prefix); writer.print("mFragmentId=#");
2486        writer.print(Integer.toHexString(mFragmentId));
2487        writer.print(" mContainerId=#");
2488        writer.print(Integer.toHexString(mContainerId));
2489        writer.print(" mTag="); writer.println(mTag);
2490        writer.print(prefix); writer.print("mState="); writer.print(mState);
2491        writer.print(" mIndex="); writer.print(mIndex);
2492        writer.print(" mWho="); writer.print(mWho);
2493        writer.print(" mBackStackNesting="); writer.println(mBackStackNesting);
2494        writer.print(prefix); writer.print("mAdded="); writer.print(mAdded);
2495        writer.print(" mRemoving="); writer.print(mRemoving);
2496        writer.print(" mFromLayout="); writer.print(mFromLayout);
2497        writer.print(" mInLayout="); writer.println(mInLayout);
2498        writer.print(prefix); writer.print("mHidden="); writer.print(mHidden);
2499        writer.print(" mDetached="); writer.print(mDetached);
2500        writer.print(" mMenuVisible="); writer.print(mMenuVisible);
2501        writer.print(" mHasMenu="); writer.println(mHasMenu);
2502        writer.print(prefix); writer.print("mRetainInstance="); writer.print(mRetainInstance);
2503        writer.print(" mRetaining="); writer.print(mRetaining);
2504        writer.print(" mUserVisibleHint="); writer.println(mUserVisibleHint);
2505        if (mFragmentManager != null) {
2506            writer.print(prefix); writer.print("mFragmentManager=");
2507            writer.println(mFragmentManager);
2508        }
2509        if (mHost != null) {
2510            writer.print(prefix); writer.print("mHost=");
2511            writer.println(mHost);
2512        }
2513        if (mParentFragment != null) {
2514            writer.print(prefix); writer.print("mParentFragment=");
2515            writer.println(mParentFragment);
2516        }
2517        if (mArguments != null) {
2518            writer.print(prefix); writer.print("mArguments="); writer.println(mArguments);
2519        }
2520        if (mSavedFragmentState != null) {
2521            writer.print(prefix); writer.print("mSavedFragmentState=");
2522            writer.println(mSavedFragmentState);
2523        }
2524        if (mSavedViewState != null) {
2525            writer.print(prefix); writer.print("mSavedViewState=");
2526            writer.println(mSavedViewState);
2527        }
2528        if (mTarget != null) {
2529            writer.print(prefix); writer.print("mTarget="); writer.print(mTarget);
2530            writer.print(" mTargetRequestCode=");
2531            writer.println(mTargetRequestCode);
2532        }
2533        if (getNextAnim() != 0) {
2534            writer.print(prefix); writer.print("mNextAnim="); writer.println(getNextAnim());
2535        }
2536        if (mContainer != null) {
2537            writer.print(prefix); writer.print("mContainer="); writer.println(mContainer);
2538        }
2539        if (mView != null) {
2540            writer.print(prefix); writer.print("mView="); writer.println(mView);
2541        }
2542        if (getAnimatingAway() != null) {
2543            writer.print(prefix); writer.print("mAnimatingAway=");
2544            writer.println(getAnimatingAway());
2545            writer.print(prefix); writer.print("mStateAfterAnimating=");
2546            writer.println(getStateAfterAnimating());
2547        }
2548        if (mLoaderManager != null) {
2549            writer.print(prefix); writer.println("Loader Manager:");
2550            mLoaderManager.dump(prefix + "  ", fd, writer, args);
2551        }
2552        if (mChildFragmentManager != null) {
2553            writer.print(prefix); writer.println("Child " + mChildFragmentManager + ":");
2554            mChildFragmentManager.dump(prefix + "  ", fd, writer, args);
2555        }
2556    }
2557
2558    Fragment findFragmentByWho(String who) {
2559        if (who.equals(mWho)) {
2560            return this;
2561        }
2562        if (mChildFragmentManager != null) {
2563            return mChildFragmentManager.findFragmentByWho(who);
2564        }
2565        return null;
2566    }
2567
2568    void instantiateChildFragmentManager() {
2569        mChildFragmentManager = new FragmentManagerImpl();
2570        mChildFragmentManager.attachController(mHost, new FragmentContainer() {
2571            @Override
2572            @Nullable
2573            public <T extends View> T onFindViewById(int id) {
2574                if (mView == null) {
2575                    throw new IllegalStateException("Fragment does not have a view");
2576                }
2577                return mView.findViewById(id);
2578            }
2579
2580            @Override
2581            public boolean onHasView() {
2582                return (mView != null);
2583            }
2584        }, this);
2585    }
2586
2587    void performCreate(Bundle savedInstanceState) {
2588        if (mChildFragmentManager != null) {
2589            mChildFragmentManager.noteStateNotSaved();
2590        }
2591        mState = CREATED;
2592        mCalled = false;
2593        onCreate(savedInstanceState);
2594        if (!mCalled) {
2595            throw new SuperNotCalledException("Fragment " + this
2596                    + " did not call through to super.onCreate()");
2597        }
2598        final Context context = getContext();
2599        final int version = context != null ? context.getApplicationInfo().targetSdkVersion : 0;
2600        if (version < Build.VERSION_CODES.N) {
2601            restoreChildFragmentState(savedInstanceState, false);
2602        }
2603    }
2604
2605    View performCreateView(LayoutInflater inflater, ViewGroup container,
2606            Bundle savedInstanceState) {
2607        if (mChildFragmentManager != null) {
2608            mChildFragmentManager.noteStateNotSaved();
2609        }
2610        mPerformedCreateView = true;
2611        return onCreateView(inflater, container, savedInstanceState);
2612    }
2613
2614    void performActivityCreated(Bundle savedInstanceState) {
2615        if (mChildFragmentManager != null) {
2616            mChildFragmentManager.noteStateNotSaved();
2617        }
2618        mState = ACTIVITY_CREATED;
2619        mCalled = false;
2620        onActivityCreated(savedInstanceState);
2621        if (!mCalled) {
2622            throw new SuperNotCalledException("Fragment " + this
2623                    + " did not call through to super.onActivityCreated()");
2624        }
2625        if (mChildFragmentManager != null) {
2626            mChildFragmentManager.dispatchActivityCreated();
2627        }
2628    }
2629
2630    void performStart() {
2631        if (mChildFragmentManager != null) {
2632            mChildFragmentManager.noteStateNotSaved();
2633            mChildFragmentManager.execPendingActions();
2634        }
2635        mState = STARTED;
2636        mCalled = false;
2637        onStart();
2638        if (!mCalled) {
2639            throw new SuperNotCalledException("Fragment " + this
2640                    + " did not call through to super.onStart()");
2641        }
2642        if (mChildFragmentManager != null) {
2643            mChildFragmentManager.dispatchStart();
2644        }
2645        if (mLoaderManager != null) {
2646            mLoaderManager.doReportStart();
2647        }
2648    }
2649
2650    void performResume() {
2651        if (mChildFragmentManager != null) {
2652            mChildFragmentManager.noteStateNotSaved();
2653            mChildFragmentManager.execPendingActions();
2654        }
2655        mState = RESUMED;
2656        mCalled = false;
2657        onResume();
2658        if (!mCalled) {
2659            throw new SuperNotCalledException("Fragment " + this
2660                    + " did not call through to super.onResume()");
2661        }
2662        if (mChildFragmentManager != null) {
2663            mChildFragmentManager.dispatchResume();
2664            mChildFragmentManager.execPendingActions();
2665        }
2666    }
2667
2668    void noteStateNotSaved() {
2669        if (mChildFragmentManager != null) {
2670            mChildFragmentManager.noteStateNotSaved();
2671        }
2672    }
2673
2674    @Deprecated
2675    void performMultiWindowModeChanged(boolean isInMultiWindowMode) {
2676        onMultiWindowModeChanged(isInMultiWindowMode);
2677        if (mChildFragmentManager != null) {
2678            mChildFragmentManager.dispatchMultiWindowModeChanged(isInMultiWindowMode);
2679        }
2680    }
2681
2682    void performMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
2683        onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
2684        if (mChildFragmentManager != null) {
2685            mChildFragmentManager.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig);
2686        }
2687    }
2688
2689    @Deprecated
2690    void performPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
2691        onPictureInPictureModeChanged(isInPictureInPictureMode);
2692        if (mChildFragmentManager != null) {
2693            mChildFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode);
2694        }
2695    }
2696
2697    void performPictureInPictureModeChanged(boolean isInPictureInPictureMode,
2698            Configuration newConfig) {
2699        onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
2700        if (mChildFragmentManager != null) {
2701            mChildFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode,
2702                    newConfig);
2703        }
2704    }
2705
2706    void performConfigurationChanged(Configuration newConfig) {
2707        onConfigurationChanged(newConfig);
2708        if (mChildFragmentManager != null) {
2709            mChildFragmentManager.dispatchConfigurationChanged(newConfig);
2710        }
2711    }
2712
2713    void performLowMemory() {
2714        onLowMemory();
2715        if (mChildFragmentManager != null) {
2716            mChildFragmentManager.dispatchLowMemory();
2717        }
2718    }
2719
2720    void performTrimMemory(int level) {
2721        onTrimMemory(level);
2722        if (mChildFragmentManager != null) {
2723            mChildFragmentManager.dispatchTrimMemory(level);
2724        }
2725    }
2726
2727    boolean performCreateOptionsMenu(Menu menu, MenuInflater inflater) {
2728        boolean show = false;
2729        if (!mHidden) {
2730            if (mHasMenu && mMenuVisible) {
2731                show = true;
2732                onCreateOptionsMenu(menu, inflater);
2733            }
2734            if (mChildFragmentManager != null) {
2735                show |= mChildFragmentManager.dispatchCreateOptionsMenu(menu, inflater);
2736            }
2737        }
2738        return show;
2739    }
2740
2741    boolean performPrepareOptionsMenu(Menu menu) {
2742        boolean show = false;
2743        if (!mHidden) {
2744            if (mHasMenu && mMenuVisible) {
2745                show = true;
2746                onPrepareOptionsMenu(menu);
2747            }
2748            if (mChildFragmentManager != null) {
2749                show |= mChildFragmentManager.dispatchPrepareOptionsMenu(menu);
2750            }
2751        }
2752        return show;
2753    }
2754
2755    boolean performOptionsItemSelected(MenuItem item) {
2756        if (!mHidden) {
2757            if (mHasMenu && mMenuVisible) {
2758                if (onOptionsItemSelected(item)) {
2759                    return true;
2760                }
2761            }
2762            if (mChildFragmentManager != null) {
2763                if (mChildFragmentManager.dispatchOptionsItemSelected(item)) {
2764                    return true;
2765                }
2766            }
2767        }
2768        return false;
2769    }
2770
2771    boolean performContextItemSelected(MenuItem item) {
2772        if (!mHidden) {
2773            if (onContextItemSelected(item)) {
2774                return true;
2775            }
2776            if (mChildFragmentManager != null) {
2777                if (mChildFragmentManager.dispatchContextItemSelected(item)) {
2778                    return true;
2779                }
2780            }
2781        }
2782        return false;
2783    }
2784
2785    void performOptionsMenuClosed(Menu menu) {
2786        if (!mHidden) {
2787            if (mHasMenu && mMenuVisible) {
2788                onOptionsMenuClosed(menu);
2789            }
2790            if (mChildFragmentManager != null) {
2791                mChildFragmentManager.dispatchOptionsMenuClosed(menu);
2792            }
2793        }
2794    }
2795
2796    void performSaveInstanceState(Bundle outState) {
2797        onSaveInstanceState(outState);
2798        if (mChildFragmentManager != null) {
2799            Parcelable p = mChildFragmentManager.saveAllState();
2800            if (p != null) {
2801                outState.putParcelable(Activity.FRAGMENTS_TAG, p);
2802            }
2803        }
2804    }
2805
2806    void performPause() {
2807        if (mChildFragmentManager != null) {
2808            mChildFragmentManager.dispatchPause();
2809        }
2810        mState = STARTED;
2811        mCalled = false;
2812        onPause();
2813        if (!mCalled) {
2814            throw new SuperNotCalledException("Fragment " + this
2815                    + " did not call through to super.onPause()");
2816        }
2817    }
2818
2819    void performStop() {
2820        if (mChildFragmentManager != null) {
2821            mChildFragmentManager.dispatchStop();
2822        }
2823        mState = STOPPED;
2824        mCalled = false;
2825        onStop();
2826        if (!mCalled) {
2827            throw new SuperNotCalledException("Fragment " + this
2828                    + " did not call through to super.onStop()");
2829        }
2830
2831        if (mLoadersStarted) {
2832            mLoadersStarted = false;
2833            if (!mCheckedForLoaderManager) {
2834                mCheckedForLoaderManager = true;
2835                mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
2836            }
2837            if (mLoaderManager != null) {
2838                if (mHost.getRetainLoaders()) {
2839                    mLoaderManager.doRetain();
2840                } else {
2841                    mLoaderManager.doStop();
2842                }
2843            }
2844        }
2845    }
2846
2847    void performDestroyView() {
2848        if (mChildFragmentManager != null) {
2849            mChildFragmentManager.dispatchDestroyView();
2850        }
2851        mState = CREATED;
2852        mCalled = false;
2853        onDestroyView();
2854        if (!mCalled) {
2855            throw new SuperNotCalledException("Fragment " + this
2856                    + " did not call through to super.onDestroyView()");
2857        }
2858        if (mLoaderManager != null) {
2859            mLoaderManager.doReportNextStart();
2860        }
2861        mPerformedCreateView = false;
2862    }
2863
2864    void performDestroy() {
2865        if (mChildFragmentManager != null) {
2866            mChildFragmentManager.dispatchDestroy();
2867        }
2868        mState = INITIALIZING;
2869        mCalled = false;
2870        onDestroy();
2871        if (!mCalled) {
2872            throw new SuperNotCalledException("Fragment " + this
2873                    + " did not call through to super.onDestroy()");
2874        }
2875        mChildFragmentManager = null;
2876    }
2877
2878    void performDetach() {
2879        mCalled = false;
2880        onDetach();
2881        mLayoutInflater = null;
2882        if (!mCalled) {
2883            throw new SuperNotCalledException("Fragment " + this
2884                    + " did not call through to super.onDetach()");
2885        }
2886
2887        // Destroy the child FragmentManager if we still have it here.
2888        // We won't unless we're retaining our instance and if we do,
2889        // our child FragmentManager instance state will have already been saved.
2890        if (mChildFragmentManager != null) {
2891            if (!mRetaining) {
2892                throw new IllegalStateException("Child FragmentManager of " + this + " was not "
2893                        + " destroyed and this fragment is not retaining instance");
2894            }
2895            mChildFragmentManager.dispatchDestroy();
2896            mChildFragmentManager = null;
2897        }
2898    }
2899
2900    void setOnStartEnterTransitionListener(OnStartEnterTransitionListener listener) {
2901        ensureAnimationInfo();
2902        if (listener == mAnimationInfo.mStartEnterTransitionListener) {
2903            return;
2904        }
2905        if (listener != null && mAnimationInfo.mStartEnterTransitionListener != null) {
2906            throw new IllegalStateException("Trying to set a replacement " +
2907                    "startPostponedEnterTransition on " + this);
2908        }
2909        if (mAnimationInfo.mEnterTransitionPostponed) {
2910            mAnimationInfo.mStartEnterTransitionListener = listener;
2911        }
2912        if (listener != null) {
2913            listener.startListening();
2914        }
2915    }
2916
2917    private static Transition loadTransition(Context context, TypedArray typedArray,
2918            Transition currentValue, Transition defaultValue, int id) {
2919        if (currentValue != defaultValue) {
2920            return currentValue;
2921        }
2922        int transitionId = typedArray.getResourceId(id, 0);
2923        Transition transition = defaultValue;
2924        if (transitionId != 0 && transitionId != com.android.internal.R.transition.no_transition) {
2925            TransitionInflater inflater = TransitionInflater.from(context);
2926            transition = inflater.inflateTransition(transitionId);
2927            if (transition instanceof TransitionSet &&
2928                    ((TransitionSet)transition).getTransitionCount() == 0) {
2929                transition = null;
2930            }
2931        }
2932        return transition;
2933    }
2934
2935    private AnimationInfo ensureAnimationInfo() {
2936        if (mAnimationInfo == null) {
2937            mAnimationInfo = new AnimationInfo();
2938        }
2939        return mAnimationInfo;
2940    }
2941
2942    int getNextAnim() {
2943        if (mAnimationInfo == null) {
2944            return 0;
2945        }
2946        return mAnimationInfo.mNextAnim;
2947    }
2948
2949    void setNextAnim(int animResourceId) {
2950        if (mAnimationInfo == null && animResourceId == 0) {
2951            return; // no change!
2952        }
2953        ensureAnimationInfo().mNextAnim = animResourceId;
2954    }
2955
2956    int getNextTransition() {
2957        if (mAnimationInfo == null) {
2958            return 0;
2959        }
2960        return mAnimationInfo.mNextTransition;
2961    }
2962
2963    void setNextTransition(int nextTransition, int nextTransitionStyle) {
2964        if (mAnimationInfo == null && nextTransition == 0 && nextTransitionStyle == 0) {
2965            return; // no change!
2966        }
2967        ensureAnimationInfo();
2968        mAnimationInfo.mNextTransition = nextTransition;
2969        mAnimationInfo.mNextTransitionStyle = nextTransitionStyle;
2970    }
2971
2972    int getNextTransitionStyle() {
2973        if (mAnimationInfo == null) {
2974            return 0;
2975        }
2976        return mAnimationInfo.mNextTransitionStyle;
2977    }
2978
2979    SharedElementCallback getEnterTransitionCallback() {
2980        if (mAnimationInfo == null) {
2981            return SharedElementCallback.NULL_CALLBACK;
2982        }
2983        return mAnimationInfo.mEnterTransitionCallback;
2984    }
2985
2986    SharedElementCallback getExitTransitionCallback() {
2987        if (mAnimationInfo == null) {
2988            return SharedElementCallback.NULL_CALLBACK;
2989        }
2990        return mAnimationInfo.mExitTransitionCallback;
2991    }
2992
2993    Animator getAnimatingAway() {
2994        if (mAnimationInfo == null) {
2995            return null;
2996        }
2997        return mAnimationInfo.mAnimatingAway;
2998    }
2999
3000    void setAnimatingAway(Animator animator) {
3001        ensureAnimationInfo().mAnimatingAway = animator;
3002    }
3003
3004    int getStateAfterAnimating() {
3005        if (mAnimationInfo == null) {
3006            return 0;
3007        }
3008        return mAnimationInfo.mStateAfterAnimating;
3009    }
3010
3011    void setStateAfterAnimating(int state) {
3012        ensureAnimationInfo().mStateAfterAnimating = state;
3013    }
3014
3015    boolean isPostponed() {
3016        if (mAnimationInfo == null) {
3017            return false;
3018        }
3019        return mAnimationInfo.mEnterTransitionPostponed;
3020    }
3021
3022    boolean isHideReplaced() {
3023        if (mAnimationInfo == null) {
3024            return false;
3025        }
3026        return mAnimationInfo.mIsHideReplaced;
3027    }
3028
3029    void setHideReplaced(boolean replaced) {
3030        ensureAnimationInfo().mIsHideReplaced = replaced;
3031    }
3032
3033    /**
3034     * Used internally to be notified when {@link #startPostponedEnterTransition()} has
3035     * been called. This listener will only be called once and then be removed from the
3036     * listeners.
3037     */
3038    interface OnStartEnterTransitionListener {
3039        void onStartEnterTransition();
3040        void startListening();
3041    }
3042
3043    /**
3044     * Contains all the animation and transition information for a fragment. This will only
3045     * be instantiated for Fragments that have Views.
3046     */
3047    static class AnimationInfo {
3048        // Non-null if the fragment's view hierarchy is currently animating away,
3049        // meaning we need to wait a bit on completely destroying it.  This is the
3050        // animation that is running.
3051        Animator mAnimatingAway;
3052
3053        // If mAnimatingAway != null, this is the state we should move to once the
3054        // animation is done.
3055        int mStateAfterAnimating;
3056
3057        // If app has requested a specific animation, this is the one to use.
3058        int mNextAnim;
3059
3060        // If app has requested a specific transition, this is the one to use.
3061        int mNextTransition;
3062
3063        // If app has requested a specific transition style, this is the one to use.
3064        int mNextTransitionStyle;
3065
3066        private Transition mEnterTransition = null;
3067        private Transition mReturnTransition = USE_DEFAULT_TRANSITION;
3068        private Transition mExitTransition = null;
3069        private Transition mReenterTransition = USE_DEFAULT_TRANSITION;
3070        private Transition mSharedElementEnterTransition = null;
3071        private Transition mSharedElementReturnTransition = USE_DEFAULT_TRANSITION;
3072        private Boolean mAllowReturnTransitionOverlap;
3073        private Boolean mAllowEnterTransitionOverlap;
3074
3075        SharedElementCallback mEnterTransitionCallback = SharedElementCallback.NULL_CALLBACK;
3076        SharedElementCallback mExitTransitionCallback = SharedElementCallback.NULL_CALLBACK;
3077
3078        // True when postponeEnterTransition has been called and startPostponeEnterTransition
3079        // hasn't been called yet.
3080        boolean mEnterTransitionPostponed;
3081
3082        // Listener to wait for startPostponeEnterTransition. After being called, it will
3083        // be set to null
3084        OnStartEnterTransitionListener mStartEnterTransitionListener;
3085
3086        // True if the View was hidden, but the transition is handling the hide
3087        boolean mIsHideReplaced;
3088    }
3089}
3090