FragmentManager.java revision 464b6f3c93dda03359ec2d37c8205065922f2994
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2011 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
58451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * you may not use this file except in compliance with the License.
68451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * You may obtain a copy of the License at
78451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
98451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
118451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
128451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * See the License for the specific language governing permissions and
148451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.support.v4.app;
18f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn
19f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackbornimport android.content.Context;
20f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackbornimport android.content.res.Configuration;
21f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackbornimport android.os.Bundle;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
25ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlettimport android.os.Parcelable;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.support.v4.util.DebugUtils;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.support.v4.util.LogWriter;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.AccelerateInterpolator;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.AlphaAnimation;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.Animation;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.AnimationSet;
34ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlettimport android.view.animation.AnimationUtils;
350c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Feltimport android.view.animation.DecelerateInterpolator;
36f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Feltimport android.view.animation.Interpolator;
370c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Feltimport android.view.animation.ScaleAnimation;
380c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Feltimport android.view.animation.Animation.AnimationListener;
395c13d89c1332fcc499379b9064b891187b75ca32Chet Haaseimport android.view.Menu;
400c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Feltimport android.view.MenuInflater;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MenuItem;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Static library support version of the framework's {@link android.app.FragmentManager}.
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Used to write apps that run on platforms prior to Android 3.0.  When running
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on Android 3.0 or above, this implementation is still used; it does not try
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to switch to the framework's implementation.  See the framework SDK
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * documentation for a class overview.
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Your activity must derive from {@link FragmentActivity} to use this.
583d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed */
59c511bee87cda99a252d1a62487f47c8f05aee78cFabrice Di Megliopublic abstract class FragmentManager {
60c511bee87cda99a252d1a62487f47c8f05aee78cFabrice Di Meglio    /**
613d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed     * Representation of an entry on the fragment back stack, as created
623d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed     * with {@link FragmentTransaction#addToBackStack(String)
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * FragmentTransaction.addToBackStack()}.  Entries can later be
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * retrieved with {@link FragmentManager#getBackStackEntryAt(int)
650c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     * FragmentManager.getBackStackEntry()}.
660c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     *
670c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt     * <p>Note that you should never hold on to a BackStackEntry object;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the identifier as returned by {@link #getId} is the only thing that
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be persisted across activity instances.
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface BackStackEntry {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Return the unique identifier for the entry.  This is the only
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * representation of the entry that will persist across activity
753d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed         * instances.
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getId();
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Get the name that was supplied to
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * {@link FragmentTransaction#addToBackStack(String)
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * FragmentTransaction.addToBackStack(String)} when creating this entry.
838451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes         */
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String getName();
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
863d63e0119dc763ed0a06fd7498375746fd391d80Mike Reed        /**
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Return the full bread crumb title resource identifier for the entry,
888451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes         * or 0 if it does not have one.
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getBreadCrumbTitleRes();
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
928451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        /**
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Return the short bread crumb title resource identifier for the entry,
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * or 0 if it does not have one.
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int getBreadCrumbShortTitleRes();
978451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Return the full bread crumb title for the entry, or null if it
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * does not have one.
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1028451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        public CharSequence getBreadCrumbTitle();
103f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn
104f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn        /**
105f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn         * Return the short bread crumb title for the entry, or null if it
106f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn         * does not have one.
107f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn         */
108f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn        public CharSequence getBreadCrumbShortTitle();
109f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn    }
110f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn
111f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn    /**
112f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn     * Interface to watch for changes to the back stack.
113f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn     */
114f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn    public interface OnBackStackChangedListener {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called whenever the contents of the back stack change.
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onBackStackChanged();
1198451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Start a series of edit operations on the Fragments associated with
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this FragmentManager.
1248451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     *
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Note: A fragment transaction can only be created/committed prior
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to an activity saving its state.  If you try to commit a transaction
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after {@link FragmentActivity#onSaveInstanceState FragmentActivity.onSaveInstanceState()}
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (and prior to a following {@link FragmentActivity#onStart FragmentActivity.onStart}
1298451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * or {@link FragmentActivity#onResume FragmentActivity.onResume()}, you will get an error.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is because the framework takes care of saving your current fragments
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the state, and if changes are made after the state is saved then they
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be lost.</p>
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1348451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    public abstract FragmentTransaction beginTransaction();
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** @hide -- remove once prebuilts are in. */
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Deprecated
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public FragmentTransaction openTransaction() {
1398451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        return beginTransaction();
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * After a {@link FragmentTransaction} is committed with
1448451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * {@link FragmentTransaction#commit FragmentTransaction.commit()}, it
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is scheduled to be executed asynchronously on the process's main thread.
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If you want to immediately executing any such pending operations, you
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can call this function (only from the main thread) to do so.  Note that
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * all callbacks and other related behavior will be done from within this
1498451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * call, so be careful about where this is called from.
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true if there were any pending transactions to be
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * executed.
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1548451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    public abstract boolean executePendingTransactions();
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Finds a fragment that was identified by the given id either when inflated
1588451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * from XML or as the container ID when added in a transaction.  This first
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * searches through fragments that are currently added to the manager's
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * activity; if no such fragment is found, then all fragments currently
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * on the back stack associated with this ID are searched.
1628451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * @return The fragment if found or null otherwise.
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Fragment findFragmentById(int id);
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1678451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * Finds a fragment that was identified by the given tag either when inflated
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from XML or as supplied when added in a transaction.  This first
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * searches through fragments that are currently added to the manager's
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * activity; if no such fragment is found, then all fragments currently
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * on the back stack are searched.
1728451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * @return The fragment if found or null otherwise.
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Fragment findFragmentByTag(String tag);
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1778451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * Flag for {@link #popBackStack(String, int)}
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and {@link #popBackStack(int, int)}: If set, and the name or ID of
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a back stack entry has been supplied, then all matching entries will
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be consumed until one that doesn't match is found or the bottom of
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the stack is reached.  Otherwise, all entries up to but not including that entry
1828451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * will be removed.
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int POP_BACK_STACK_INCLUSIVE = 1<<0;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1878451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * Pop the top state off the back stack.  Returns true if there was one
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to pop, else false.  This function is asynchronous -- it enqueues the
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * request to pop, but the action will not be performed until the application
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns to its event loop.
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1928451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    public abstract void popBackStack();
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Like {@link #popBackStack()}, but performs the operation immediately
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inside of the call.  This is like calling {@link #executePendingTransactions()}
1978451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * afterwards.
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true if there was something popped, else false.
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract boolean popBackStackImmediate();
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2028451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    /**
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Pop the last fragment transition from the manager's fragment
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * back stack.  If there is nothing to pop, false is returned.
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This function is asynchronous -- it enqueues the
2068451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * request to pop, but the action will not be performed until the application
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns to its event loop.
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param name If non-null, this is the name of a previous back state
2108451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * to look for; if found, all states up to that state will be popped.  The
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the named state itself is popped. If null, only the top state is popped.
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
2148451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     */
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract void popBackStack(String name, int flags);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2188451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * Like {@link #popBackStack(String, int)}, but performs the operation immediately
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inside of the call.  This is like calling {@link #executePendingTransactions()}
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * afterwards.
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true if there was something popped, else false.
2228451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     */
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract boolean popBackStackImmediate(String name, int flags);
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2268451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * Pop all back stack states up to the one with the given identifier.
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This function is asynchronous -- it enqueues the
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * request to pop, but the action will not be performed until the application
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * returns to its event loop.
2308451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     *
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id Identifier of the stated to be popped. If no identifier exists,
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * false is returned.
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The identifier is the number returned by
2348451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * {@link FragmentTransaction#commit() FragmentTransaction.commit()}.  The
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the named state itself is popped.
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
2388451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     */
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract void popBackStack(int id, int flags);
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2428451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * Like {@link #popBackStack(int, int)}, but performs the operation immediately
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inside of the call.  This is like calling {@link #executePendingTransactions()}
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * afterwards.
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true if there was something popped, else false.
2468451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     */
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract boolean popBackStackImmediate(int id, int flags);
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2508451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * Return the number of entries currently in the back stack.
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract int getBackStackEntryCount();
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2548451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    /**
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the BackStackEntry at index <var>index</var> in the back stack;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * entries start index 0 being the bottom of the stack.
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2588451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    public abstract BackStackEntry getBackStackEntryAt(int index);
259ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett
260ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    /**
261ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * Add a new listener for changes to the fragment back stack.
262ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     */
263ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    public abstract void addOnBackStackChangedListener(OnBackStackChangedListener listener);
264ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett
265ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    /**
266ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * Remove a listener that was previously added with
267ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * {@link #addOnBackStackChangedListener(OnBackStackChangedListener)}.
268ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     */
269ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    public abstract void removeOnBackStackChangedListener(OnBackStackChangedListener listener);
270ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett
271ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    /**
272ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * Put a reference to a fragment in a Bundle.  This Bundle can be
273ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * persisted as saved state, and when later restoring
274ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * {@link #getFragment(Bundle, String)} will return the current
275ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * instance of the same fragment.
276ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     *
277ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * @param bundle The bundle in which to put the fragment reference.
278ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * @param key The name of the entry in the bundle.
279ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * @param fragment The Fragment whose reference is to be stored.
280ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     */
281ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    public abstract void putFragment(Bundle bundle, String key, Fragment fragment);
282ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett
283ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    /**
284ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * Retrieve the current Fragment instance for a reference previously
285ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * placed with {@link #putFragment(Bundle, String, Fragment)}.
286ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     *
287ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * @param bundle The bundle from which to retrieve the fragment reference.
288ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * @param key The name of the entry in the bundle.
289ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * @return Returns the current Fragment instance that is associated with
290ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * the given reference.
291ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     */
292ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    public abstract Fragment getFragment(Bundle bundle, String key);
293ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett
294ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    /**
295ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * Save the current instance state of the given Fragment.  This can be
296ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * used later when creating a new instance of the Fragment and adding
297ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * it to the fragment manager, to have it create itself to match the
298ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * current state returned here.  Note that there are limits on how
299517825f1a9f14f92908bd7859b91b927c2eec6d9Fabrice Di Meglio     * this can be used:
300ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     *
301ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * <ul>
302ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * <li>The Fragment must currently be attached to the FragmentManager.
303ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett     * <li>A new Fragment created using this saved state must be the same class
304517825f1a9f14f92908bd7859b91b927c2eec6d9Fabrice Di Meglio     * type as the Fragment it was created from.
305517825f1a9f14f92908bd7859b91b927c2eec6d9Fabrice Di Meglio     * <li>The saved state can not contain dependencies on other fragments --
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that is it can't use {@link #putFragment(Bundle, String, Fragment)} to
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * store a fragment reference because that reference may not be valid when
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this saved state is later used.  Likewise the Fragment's target and
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * result code are not included in this state.
3108451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * </ul>
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param f The Fragment whose state is to be saved.
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The generated state.  This will be null if there was no
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * interesting state created by the fragment.
3158451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     */
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract Fragment.SavedState saveFragmentInstanceState(Fragment f);
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Print the FragmentManager's state into the given stream.
3208451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     *
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param prefix Text to print at the front of each line.
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param fd The raw file descriptor that the dump is being sent to.
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param writer A PrintWriter to which the dump is to be set.
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param args Additional arguments to the dump request.
3258451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     */
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Control whether the framework's internal fragment manager debugging
3308451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes     * logs are turned on.  If enabled, you will see output in logcat as
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the framework performs fragment operations.
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static void enableDebugLogging(boolean enabled) {
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        FragmentManagerImpl.DEBUG = enabled;
3358451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfinal class FragmentManagerState implements Parcelable {
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FragmentState[] mActive;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int[] mAdded;
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    BackStackState[] mBackStack;
3428451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public FragmentManagerState() {
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public FragmentManagerState(Parcel in) {
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mActive = in.createTypedArray(FragmentState.CREATOR);
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAdded = in.createIntArray();
3498451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        mBackStack = in.createTypedArray(BackStackState.CREATOR);
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int describeContents() {
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void writeToParcel(Parcel dest, int flags) {
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dest.writeTypedArray(mActive, flags);
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dest.writeIntArray(mAdded);
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dest.writeTypedArray(mBackStack, flags);
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final Parcelable.Creator<FragmentManagerState> CREATOR
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            = new Parcelable.Creator<FragmentManagerState>() {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public FragmentManagerState createFromParcel(Parcel in) {
3658451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            return new FragmentManagerState(in);
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public FragmentManagerState[] newArray(int size) {
3698451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            return new FragmentManagerState[size];
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Container for fragments associated with an activity.
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfinal class FragmentManagerImpl extends FragmentManager {
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static boolean DEBUG = false;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String TAG = "FragmentManager";
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final boolean HONEYCOMB = android.os.Build.VERSION.SDK_INT >= 11;
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String TARGET_STATE_TAG = "android:target_state";
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String VIEW_STATE_TAG = "android:view_state";
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint";
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ArrayList<Runnable> mPendingActions;
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Runnable[] mTmpActions;
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mExecutingActions;
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3928451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    ArrayList<Fragment> mActive;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ArrayList<Fragment> mAdded;
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ArrayList<Integer> mAvailIndices;
3956ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    ArrayList<BackStackRecord> mBackStack;
3966ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    ArrayList<Fragment> mCreatedMenus;
3976ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Must be accessed while locked.
3994f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio    ArrayList<BackStackRecord> mBackStackIndices;
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ArrayList<Integer> mAvailBackStackIndices;
4014f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio
402b02d0ca5553300063e4332192632312600caf4b9Fabrice Di Meglio    ArrayList<OnBackStackChangedListener> mBackStackChangeListeners;
4038fb507171f68d4170cfeb1187ee7d1f70f98917dFabrice Di Meglio
40479df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio    int mCurState = Fragment.INITIALIZING;
405b02d0ca5553300063e4332192632312600caf4b9Fabrice Di Meglio    FragmentActivity mActivity;
4064f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio
4074f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio    boolean mNeedMenuInvalidate;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mStateSaved;
4098451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    boolean mDestroyed;
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String mNoTransactionsBecause;
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mHavePendingDeferredStart;
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4138451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    // Temporary vars for state save and restore.
41451f383d65f9ee3c7d73d0508b576550e7998c5b5Fabrice Di Meglio    Bundle mStateBundle = null;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SparseArray<Parcelable> mStateArray = null;
41651f383d65f9ee3c7d73d0508b576550e7998c5b5Fabrice Di Meglio
4176ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    Runnable mExecCommit = new Runnable() {
4186ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        @Override
4196ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        public void run() {
4206ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            execPendingActions();
4216ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        }
4226ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    };
4236ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio
4246ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    @Override
4256ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    public FragmentTransaction beginTransaction() {
4264f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio        return new BackStackRecord(this);
4278451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
42851f383d65f9ee3c7d73d0508b576550e7998c5b5Fabrice Di Meglio
42979df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio    @Override
4304f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio    public boolean executePendingTransactions() {
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return execPendingActions();
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4348451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    @Override
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void popBackStack() {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enqueueAction(new Runnable() {
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @Override public void run() {
4388451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes                popBackStackState(mActivity.mHandler, null, -1, 0);
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4406ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        }, false);
4416ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    }
4426ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio
4436ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    @Override
4446ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    public boolean popBackStackImmediate() {
4456ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        checkStateLoss();
4464f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio        executePendingTransactions();
4476ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        return popBackStackState(mActivity.mHandler, null, -1, 0);
4488fb507171f68d4170cfeb1187ee7d1f70f98917dFabrice Di Meglio    }
44979df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio
450b02d0ca5553300063e4332192632312600caf4b9Fabrice Di Meglio    @Override
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void popBackStack(final String name, final int flags) {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        enqueueAction(new Runnable() {
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @Override public void run() {
4548451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes                popBackStackState(mActivity.mHandler, name, -1, flags);
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4566ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        }, false);
4576ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    }
4586ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio
4596ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    @Override
4606ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    public boolean popBackStackImmediate(String name, int flags) {
4616ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        checkStateLoss();
4626ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        executePendingTransactions();
4636ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        return popBackStackState(mActivity.mHandler, name, -1, flags);
4646ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    }
4656ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio
4666ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    @Override
4676ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    public void popBackStack(final int id, final int flags) {
4686ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        if (id < 0) {
4696ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            throw new IllegalArgumentException("Bad id: " + id);
4706ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        }
4716ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        enqueueAction(new Runnable() {
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @Override public void run() {
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                popBackStackState(mActivity.mHandler, null, id, flags);
4746ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            }
4758fb507171f68d4170cfeb1187ee7d1f70f98917dFabrice Di Meglio        }, false);
47679df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio    }
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean popBackStackImmediate(int id, int flags) {
4808451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        checkStateLoss();
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        executePendingTransactions();
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (id < 0) {
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("Bad id: " + id);
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4858451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        return popBackStackState(mActivity.mHandler, null, id, flags);
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4888451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    @Override
4899f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio    public int getBackStackEntryCount() {
4909f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        return mBackStack != null ? mBackStack.size() : 0;
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public BackStackEntry getBackStackEntryAt(int index) {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBackStack.get(index);
4960c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    }
4979f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio
4989f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio    @Override
4996ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    public void addOnBackStackChangedListener(OnBackStackChangedListener listener) {
5006ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        if (mBackStackChangeListeners == null) {
5016ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            mBackStackChangeListeners = new ArrayList<OnBackStackChangedListener>();
5026ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        }
5036ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        mBackStackChangeListeners.add(listener);
5046ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    }
5056ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio
5066ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    @Override
5076ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    public void removeOnBackStackChangedListener(OnBackStackChangedListener listener) {
5086ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        if (mBackStackChangeListeners != null) {
5096ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            mBackStackChangeListeners.remove(listener);
5106ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        }
5116ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    }
5126ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio
5136ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    @Override
5146ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    public void putFragment(Bundle bundle, String key, Fragment fragment) {
5159f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        if (fragment.mIndex < 0) {
5165c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio            throw new IllegalStateException("Fragment " + fragment
517a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio                    + " is not currently in the FragmentManager");
518a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio        }
519a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio        bundle.putInt(key, fragment.mIndex);
520a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    }
5215c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio
5225c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    @Override
523eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio    public Fragment getFragment(Bundle bundle, String key) {
5245c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio        int index = bundle.getInt(key, -1);
5259f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        if (index == -1) {
5269f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio            return null;
5279f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        }
5289f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        if (index >= mActive.size()) {
5299f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio            throw new IllegalStateException("Fragement no longer exists for key "
5309f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio                    + key + ": index " + index);
5319f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        }
5329f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        Fragment f = mActive.get(index);
5339f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        if (f == null) {
5349f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio            throw new IllegalStateException("Fragement no longer exists for key "
5359f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio                    + key + ": index " + index);
5369f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio        }
537f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        return f;
538f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt    }
5390c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
5406ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    @Override
5416ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) {
5426ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        if (fragment.mIndex < 0) {
5436ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            throw new IllegalStateException("Fragment " + fragment
5446ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                    + " is not currently in the FragmentManager");
5456ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        }
5466ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        if (fragment.mState > Fragment.INITIALIZING) {
5476ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            Bundle result = saveFragmentBasicState(fragment);
5486ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            return result != null ? new Fragment.SavedState(result) : null;
5496ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        }
5506ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        return null;
5516ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    }
5526ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio
5536ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    @Override
5546ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio    public String toString() {
5556ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        StringBuilder sb = new StringBuilder(128);
5566ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        sb.append("FragmentManager{");
5570c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        sb.append(Integer.toHexString(System.identityHashCode(this)));
5586ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        sb.append(" in ");
5590c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        DebugUtils.buildShortClassTag(mActivity, sb);
560f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        sb.append("}}");
56179df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio        return sb.toString();
5620c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    }
5630c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
5640c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    @Override
5650c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
5660c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        String innerPrefix = prefix + "    ";
5670c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
5680c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        int N;
569eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio        if (mActive != null) {
570eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio            N = mActive.size();
571eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio            if (N > 0) {
5726ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                writer.print(prefix); writer.print("Active Fragments in ");
5736ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                        writer.print(Integer.toHexString(System.identityHashCode(this)));
5746ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                        writer.println(":");
5756ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                for (int i=0; i<N; i++) {
5766ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                    Fragment f = mActive.get(i);
5776ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                    writer.print(prefix); writer.print("  #"); writer.print(i);
5786ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                            writer.print(": "); writer.println(f);
5796ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                    if (f != null) {
5806ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                        f.dump(innerPrefix, fd, writer, args);
5816ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                    }
5826ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                }
5836ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            }
5846ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        }
5856ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio
5866ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio        if (mAdded != null) {
5876ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            N = mAdded.size();
5886ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio            if (N > 0) {
5896ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                writer.print(prefix); writer.println("Added Fragments:");
590eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio                for (int i=0; i<N; i++) {
5916ab90ed017fb52aac4493a2fac897299d345874fFabrice Di Meglio                    Fragment f = mAdded.get(i);
592eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio                    writer.print(prefix); writer.print("  #"); writer.print(i);
593eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio                            writer.print(": "); writer.println(f.toString());
594eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio                }
595eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio            }
596eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio        }
597eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio
598eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio        if (mCreatedMenus != null) {
599eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio            N = mCreatedMenus.size();
600eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio            if (N > 0) {
601eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio                writer.print(prefix); writer.println("Fragments Created Menus:");
6020a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                for (int i=0; i<N; i++) {
6030c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                    Fragment f = mCreatedMenus.get(i);
6040a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                    writer.print(prefix); writer.print("  #"); writer.print(i);
6050c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                            writer.print(": "); writer.println(f.toString());
6060a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                }
6070a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio            }
6080a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio        }
6090a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio
6100a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio        if (mBackStack != null) {
6110c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            N = mBackStack.size();
6120c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            if (N > 0) {
6130c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                writer.print(prefix); writer.println("Back Stack:");
6140c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                for (int i=0; i<N; i++) {
6150a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                    BackStackRecord bs = mBackStack.get(i);
6160c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                    writer.print(prefix); writer.print("  #"); writer.print(i);
6170a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                            writer.print(": "); writer.println(bs.toString());
6180c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                    bs.dump(innerPrefix, fd, writer, args);
6190a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                }
6200a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio            }
6210a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio        }
6220a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio
6230a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio        synchronized (this) {
624eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio            if (mBackStackIndices != null) {
625eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio                N = mBackStackIndices.size();
626eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio                if (N > 0) {
627eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio                    writer.print(prefix); writer.println("Back Stack Indices:");
6280c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                    for (int i=0; i<N; i++) {
6290c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                        BackStackRecord bs = mBackStackIndices.get(i);
6304f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio                        writer.print(prefix); writer.print("  #"); writer.print(i);
6319c418dbc56efd334c68872d281f75138e16eae46Fabrice Di Meglio                                writer.print(": "); writer.println(bs);
6324f810c8535055bd9a8d89a7d1ba0a7c712a8843dFabrice Di Meglio                    }
63379df5323e7ed541b854cea5684a89e8be8c2dfc9Fabrice Di Meglio                }
6340c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            }
6350c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
6360c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            if (mAvailBackStackIndices != null && mAvailBackStackIndices.size() > 0) {
6370c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                writer.print(prefix); writer.print("mAvailBackStackIndices: ");
6380c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                        writer.println(Arrays.toString(mAvailBackStackIndices.toArray()));
6390c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            }
6400c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        }
6410c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
6420c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        if (mPendingActions != null) {
6430c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            N = mPendingActions.size();
6440c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            if (N > 0) {
6450c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                writer.print(prefix); writer.println("Pending Actions:");
6460c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                for (int i=0; i<N; i++) {
6470c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                    Runnable r = mPendingActions.get(i);
6480c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                    writer.print(prefix); writer.print("  #"); writer.print(i);
6490c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                            writer.print(": "); writer.println(r);
6500c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                }
6510c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            }
6520c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        }
6530c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
6540c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        writer.print(prefix); writer.println("FragmentManager misc state:");
6550c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        writer.print(prefix); writer.print("  mCurState="); writer.print(mCurState);
6560c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                writer.print(" mStateSaved="); writer.print(mStateSaved);
6570c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                writer.print(" mDestroyed="); writer.println(mDestroyed);
6580c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        if (mNeedMenuInvalidate) {
6590c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            writer.print(prefix); writer.print("  mNeedMenuInvalidate=");
6600c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                    writer.println(mNeedMenuInvalidate);
6610c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        }
6620c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        if (mNoTransactionsBecause != null) {
6630c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            writer.print(prefix); writer.print("  mNoTransactionsBecause=");
6640c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                    writer.println(mNoTransactionsBecause);
6650c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        }
6660c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        if (mAvailIndices != null && mAvailIndices.size() > 0) {
6670c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            writer.print(prefix); writer.print("  mAvailIndices: ");
6680c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                    writer.println(Arrays.toString(mAvailIndices.toArray()));
6690c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        }
6700c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    }
6710c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
6720c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f);
6730c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    static final Interpolator DECELERATE_CUBIC = new DecelerateInterpolator(1.5f);
6740c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    static final Interpolator ACCELERATE_QUINT = new AccelerateInterpolator(2.5f);
6750c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    static final Interpolator ACCELERATE_CUBIC = new AccelerateInterpolator(1.5f);
6760c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
6770c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    static final int ANIM_DUR = 220;
6780c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt
6790c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt    static Animation makeOpenCloseAnimation(Context context, float startScale,
6800c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt            float endScale, float startAlpha, float endAlpha) {
6810c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        AnimationSet set = new AnimationSet(false);
6820c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        ScaleAnimation scale = new ScaleAnimation(startScale, endScale, startScale, endScale,
6830c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                Animation.RELATIVE_TO_SELF, .5f, Animation.RELATIVE_TO_SELF, .5f);
6840c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        scale.setInterpolator(DECELERATE_QUINT);
6850c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        scale.setDuration(ANIM_DUR);
6860c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        set.addAnimation(scale);
6870c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        AlphaAnimation alpha = new AlphaAnimation(startAlpha, endAlpha);
6880c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        alpha.setInterpolator(DECELERATE_CUBIC);
6890c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt        alpha.setDuration(ANIM_DUR);
690f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        set.addAnimation(alpha);
691f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        return set;
692f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt    }
693f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt
694f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt    static Animation makeFadeAnimation(Context context, float start, float end) {
695f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        AlphaAnimation anim = new AlphaAnimation(start, end);
696f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        anim.setInterpolator(DECELERATE_CUBIC);
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anim.setDuration(ANIM_DUR);
698f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        return anim;
699f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt    }
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
701f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt    Animation loadAnimation(Fragment fragment, int transit, boolean enter,
702f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt            int transitionStyle) {
703f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        Animation animObj = fragment.onCreateAnimation(transit, enter,
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fragment.mNextAnim);
705f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt        if (animObj != null) {
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return animObj;
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
708f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fragment.mNextAnim != 0) {
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Animation anim = AnimationUtils.loadAnimation(mActivity, fragment.mNextAnim);
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (anim != null) {
7128451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes                return anim;
7138451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            }
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (transit == 0) {
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int styleIndex = transitToStyleIndex(transit, enter);
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (styleIndex < 0) {
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
725bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio        switch (styleIndex) {
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case ANIM_STYLE_OPEN_ENTER:
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return makeOpenCloseAnimation(mActivity, 1.125f, 1.0f, 0, 1);
728a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio            case ANIM_STYLE_OPEN_EXIT:
729a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio                return makeOpenCloseAnimation(mActivity, 1.0f, .975f, 1, 0);
730bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio            case ANIM_STYLE_CLOSE_ENTER:
731a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio                return makeOpenCloseAnimation(mActivity, .975f, 1.0f, 0, 1);
732bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio            case ANIM_STYLE_CLOSE_EXIT:
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return makeOpenCloseAnimation(mActivity, 1.0f, 1.075f, 1, 0);
734bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio            case ANIM_STYLE_FADE_ENTER:
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return makeFadeAnimation(mActivity, 0, 1);
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case ANIM_STYLE_FADE_EXIT:
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return makeFadeAnimation(mActivity, 1, 0);
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (transitionStyle == 0 && mActivity.getWindow() != null) {
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            transitionStyle = mActivity.getWindow().getAttributes().windowAnimations;
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (transitionStyle == 0) {
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //TypedArray attrs = mActivity.obtainStyledAttributes(transitionStyle,
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //        com.android.internal.R.styleable.FragmentAnimation);
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //int anim = attrs.getResourceId(styleIndex, 0);
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //attrs.recycle();
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //if (anim == 0) {
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //    return null;
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //}
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //return AnimatorInflater.loadAnimator(mActivity, anim);
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void performPendingDeferredStart(Fragment f) {
7618451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        if (f.mDeferStart) {
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mExecutingActions) {
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Wait until we're done executing our pending transactions
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHavePendingDeferredStart = true;
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            f.mDeferStart = false;
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            moveToState(f, mCurState, 0, 0, false);
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void moveToState(Fragment f, int newState, int transit, int transitionStyle,
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean keepActive) {
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Fragments that are not currently added will sit in the onCreate() state.
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!f.mAdded && newState > Fragment.CREATED) {
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            newState = Fragment.CREATED;
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (f.mRemoving && newState > f.mState) {
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // While removing a fragment, we can't change it to a higher state.
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            newState = f.mState;
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Defer start if requested; don't allow it to move to STARTED or higher
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // if it's not already started.
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            newState = Fragment.STOPPED;
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (f.mState < newState) {
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // For fragments that are created from a layout, when restoring from
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // state we don't want to allow them to be created until they are
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // being reloaded from the layout.
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (f.mFromLayout && !f.mInLayout) {
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (f.mAnimatingAway != null) {
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // The fragment is currently being animated...  but!  Now we
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // want to move our state back up.  Give up on waiting for the
7978451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes                // animation, move to whatever the final state should be once
798a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio                // the animation is done, and then we can proceed from there.
799a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio                f.mAnimatingAway = null;
800bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio                moveToState(f, f.mStateAfterAnimating, 0, 0, true);
801a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio            }
802bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio            switch (f.mState) {
803bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio                case Fragment.INITIALIZING:
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (f.mSavedFragmentState != null) {
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                FragmentManagerImpl.VIEW_STATE_TAG);
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mTarget = getFragment(f.mSavedFragmentState,
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                FragmentManagerImpl.TARGET_STATE_TAG);
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (f.mTarget != null) {
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            f.mTargetRequestCode = f.mSavedFragmentState.getInt(
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
8158451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes                                FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (!f.mUserVisibleHint) {
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            f.mDeferStart = true;
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (newState > Fragment.STOPPED) {
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                newState = Fragment.STOPPED;
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    f.mActivity = mActivity;
8248451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes                    f.mFragmentManager = mActivity.mFragments;
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    f.mCalled = false;
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    f.onAttach(mActivity);
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!f.mCalled) {
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        throw new SuperNotCalledException("Fragment " + f
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                + " did not call through to super.onAttach()");
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mActivity.onAttachFragment(f);
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!f.mRetaining) {
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mCalled = false;
835f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn                        f.onCreate(f.mSavedFragmentState);
836f43fa5746ee5b81a6e386d36594094d079ac8160Dianne Hackborn                        if (!f.mCalled) {
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            throw new SuperNotCalledException("Fragment " + f
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    + " did not call through to super.onCreate()");
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    f.mRetaining = false;
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (f.mFromLayout) {
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // For fragments that are part of the content view
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // layout, we need to instantiate the view immediately
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // and the inflater will take care of adding it.
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState),
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                null, f.mSavedFragmentState);
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (f.mView != null) {
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            f.mInnerView = f.mView;
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            f.mView = NoSaveStateFrameLayout.wrap(f.mView);
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (f.mHidden) f.mView.setVisibility(View.GONE);
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            f.onViewCreated(f.mView, f.mSavedFragmentState);
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            f.mInnerView = null;
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case Fragment.CREATED:
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (newState > Fragment.CREATED) {
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (!f.mFromLayout) {
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ViewGroup container = null;
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (f.mContainerId != 0) {
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                container = (ViewGroup)mActivity.findViewById(f.mContainerId);
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (container == null && !f.mRestored) {
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    throw new IllegalArgumentException("No view found for id 0x"
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            + Integer.toHexString(f.mContainerId)
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            + " for fragment " + f);
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
869517825f1a9f14f92908bd7859b91b927c2eec6d9Fabrice Di Meglio                            }
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            f.mContainer = container;
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState),
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    container, f.mSavedFragmentState);
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (f.mView != null) {
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                f.mInnerView = f.mView;
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                f.mView = NoSaveStateFrameLayout.wrap(f.mView);
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (container != null) {
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    Animation anim = loadAnimation(f, transit, true,
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            transitionStyle);
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    if (anim != null) {
880afa78967b8553443aa32579d78970a076d7581f6Dianne Hackborn                                        f.mView.startAnimation(anim);
881afa78967b8553443aa32579d78970a076d7581f6Dianne Hackborn                                    }
882afa78967b8553443aa32579d78970a076d7581f6Dianne Hackborn                                    container.addView(f.mView);
883afa78967b8553443aa32579d78970a076d7581f6Dianne Hackborn                                }
884afa78967b8553443aa32579d78970a076d7581f6Dianne Hackborn                                if (f.mHidden) f.mView.setVisibility(View.GONE);
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                f.onViewCreated(f.mView, f.mSavedFragmentState);
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            } else {
8870a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                                f.mInnerView = null;
8880a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                            }
8890a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                        }
8900a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio
8910a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                        f.mCalled = false;
8920a1413e4bf9dcda2a8abb2287e43f612a7fb2453Fabrice Di Meglio                        f.onActivityCreated(f.mSavedFragmentState);
8939f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio                        if (!f.mCalled) {
8949f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio                            throw new SuperNotCalledException("Fragment " + f
8950c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                                    + " did not call through to super.onActivityCreated()");
8960c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                        }
8970c702b88c5d0d4380930b920f5be6e66dd95a0d8Doug Felt                        if (f.mView != null) {
898f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt                            f.restoreViewState();
899f7cb1f75fdaedf996cab7c4690b080adc7bc5b97Doug Felt                        }
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mSavedFragmentState = null;
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case Fragment.ACTIVITY_CREATED:
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case Fragment.STOPPED:
9041e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy                    if (newState > Fragment.STOPPED) {
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mCalled = false;
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.performStart();
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (!f.mCalled) {
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            throw new SuperNotCalledException("Fragment " + f
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    + " did not call through to super.onStart()");
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case Fragment.STARTED:
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (newState > Fragment.STARTED) {
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mCalled = false;
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mResumed = true;
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.onResume();
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (!f.mCalled) {
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            throw new SuperNotCalledException("Fragment " + f
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    + " did not call through to super.onResume()");
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mSavedFragmentState = null;
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mSavedViewState = null;
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (f.mState > newState) {
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (f.mState) {
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case Fragment.RESUMED:
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (newState < Fragment.RESUMED) {
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mCalled = false;
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.onPause();
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (!f.mCalled) {
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            throw new SuperNotCalledException("Fragment " + f
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    + " did not call through to super.onPause()");
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        f.mResumed = false;
939                    }
940                case Fragment.STARTED:
941                    if (newState < Fragment.STARTED) {
942                        if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
943                        f.mCalled = false;
944                        f.performStop();
945                        if (!f.mCalled) {
946                            throw new SuperNotCalledException("Fragment " + f
947                                    + " did not call through to super.onStop()");
948                        }
949                    }
950                case Fragment.STOPPED:
951                    if (newState < Fragment.STOPPED) {
952                        if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
953                        f.performReallyStop();
954                    }
955                case Fragment.ACTIVITY_CREATED:
956                    if (newState < Fragment.ACTIVITY_CREATED) {
957                        if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
958                        if (f.mView != null) {
959                            // Need to save the current view state if not
960                            // done already.
961                            if (!mActivity.isFinishing() && f.mSavedViewState == null) {
962                                saveFragmentViewState(f);
963                            }
964                        }
965                        f.mCalled = false;
966                        f.performDestroyView();
967                        if (!f.mCalled) {
968                            throw new SuperNotCalledException("Fragment " + f
969                                    + " did not call through to super.onDestroyView()");
970                        }
971                        if (f.mView != null && f.mContainer != null) {
972                            Animation anim = null;
973                            if (mCurState > Fragment.INITIALIZING && !mDestroyed) {
974                                anim = loadAnimation(f, transit, false,
975                                        transitionStyle);
976                            }
977                            if (anim != null) {
978                                final Fragment fragment = f;
979                                f.mAnimatingAway = f.mView;
980                                f.mStateAfterAnimating = newState;
981                                anim.setAnimationListener(new AnimationListener() {
982                                    @Override
983                                    public void onAnimationEnd(Animation animation) {
984                                        if (fragment.mAnimatingAway != null) {
985                                            fragment.mAnimatingAway = null;
986                                            moveToState(fragment, fragment.mStateAfterAnimating,
987                                                    0, 0, false);
988                                        }
989                                    }
990                                    @Override
991                                    public void onAnimationRepeat(Animation animation) {
992                                    }
993                                    @Override
994                                    public void onAnimationStart(Animation animation) {
995                                    }
996                                });
997                                f.mView.startAnimation(anim);
998                            }
999                            f.mContainer.removeView(f.mView);
1000                        }
1001                        f.mContainer = null;
1002                        f.mView = null;
1003                        f.mInnerView = null;
1004                    }
1005                case Fragment.CREATED:
1006                    if (newState < Fragment.CREATED) {
1007                        if (mDestroyed) {
1008                            if (f.mAnimatingAway != null) {
1009                                // The fragment's containing activity is
1010                                // being destroyed, but this fragment is
1011                                // currently animating away.  Stop the
1012                                // animation right now -- it is not needed,
1013                                // and we can't wait any more on destroying
1014                                // the fragment.
1015                                View v = f.mAnimatingAway;
1016                                f.mAnimatingAway = null;
1017                                v.clearAnimation();
1018                            }
1019                        }
1020                        if (f.mAnimatingAway != null) {
1021                            // We are waiting for the fragment's view to finish
1022                            // animating away.  Just make a note of the state
1023                            // the fragment now should move to once the animation
1024                            // is done.
1025                            f.mStateAfterAnimating = newState;
1026                            newState = Fragment.CREATED;
1027                        } else {
1028                            if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
1029                            if (!f.mRetaining) {
1030                                f.mCalled = false;
1031                                f.onDestroy();
1032                                if (!f.mCalled) {
1033                                    throw new SuperNotCalledException("Fragment " + f
1034                                            + " did not call through to super.onDestroy()");
1035                                }
1036                            }
1037
1038                            f.mCalled = false;
1039                            f.onDetach();
1040                            if (!f.mCalled) {
1041                                throw new SuperNotCalledException("Fragment " + f
1042                                        + " did not call through to super.onDetach()");
1043                            }
1044                            if (!keepActive) {
1045                                if (!f.mRetaining) {
1046                                    makeInactive(f);
1047                                } else {
1048                                    f.mActivity = null;
1049                                    f.mFragmentManager = null;
1050                                }
1051                            }
1052                        }
1053                    }
1054            }
1055        }
1056
1057        f.mState = newState;
1058    }
1059
1060    void moveToState(Fragment f) {
1061        moveToState(f, mCurState, 0, 0, false);
1062    }
1063
1064    void moveToState(int newState, boolean always) {
1065        moveToState(newState, 0, 0, always);
1066    }
1067
1068    void moveToState(int newState, int transit, int transitStyle, boolean always) {
1069        if (mActivity == null && newState != Fragment.INITIALIZING) {
1070            throw new IllegalStateException("No activity");
1071        }
1072
1073        if (!always && mCurState == newState) {
1074            return;
1075        }
1076
1077        mCurState = newState;
1078        if (mActive != null) {
1079            boolean loadersRunning = false;
1080            for (int i=0; i<mActive.size(); i++) {
1081                Fragment f = mActive.get(i);
1082                if (f != null) {
1083                    moveToState(f, newState, transit, transitStyle, false);
1084                    if (f.mLoaderManager != null) {
1085                        loadersRunning |= f.mLoaderManager.hasRunningLoaders();
1086                    }
1087                }
1088            }
1089
1090            if (!loadersRunning) {
1091                startPendingDeferredFragments();
1092            }
1093
1094            if (mNeedMenuInvalidate && mActivity != null && mCurState == Fragment.RESUMED) {
1095                mActivity.supportInvalidateOptionsMenu();
1096                mNeedMenuInvalidate = false;
1097            }
1098        }
1099    }
1100
1101    void startPendingDeferredFragments() {
1102        if (mActive == null) return;
1103
1104        for (int i=0; i<mActive.size(); i++) {
1105            Fragment f = mActive.get(i);
1106            if (f != null) {
1107                performPendingDeferredStart(f);
1108            }
1109        }
1110    }
1111
1112    void makeActive(Fragment f) {
1113        if (f.mIndex >= 0) {
1114            return;
1115        }
1116
1117        if (mAvailIndices == null || mAvailIndices.size() <= 0) {
1118            if (mActive == null) {
1119                mActive = new ArrayList<Fragment>();
1120            }
1121            f.setIndex(mActive.size());
1122            mActive.add(f);
1123
1124        } else {
1125            f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1));
1126            mActive.set(f.mIndex, f);
1127        }
1128        if (DEBUG) Log.v(TAG, "Allocated fragment index " + f);
1129    }
1130
1131    void makeInactive(Fragment f) {
1132        if (f.mIndex < 0) {
1133            return;
1134        }
1135
1136        if (DEBUG) Log.v(TAG, "Freeing fragment index " + f);
1137        mActive.set(f.mIndex, null);
1138        if (mAvailIndices == null) {
1139            mAvailIndices = new ArrayList<Integer>();
1140        }
1141        mAvailIndices.add(f.mIndex);
1142        mActivity.invalidateSupportFragmentIndex(f.mIndex);
1143        f.initState();
1144    }
1145
1146    public void addFragment(Fragment fragment, boolean moveToStateNow) {
1147        if (mAdded == null) {
1148            mAdded = new ArrayList<Fragment>();
1149        }
1150        if (DEBUG) Log.v(TAG, "add: " + fragment);
1151        makeActive(fragment);
1152        if (!fragment.mDetached) {
1153            mAdded.add(fragment);
1154            fragment.mAdded = true;
1155            fragment.mRemoving = false;
1156            if (fragment.mHasMenu && fragment.mMenuVisible) {
1157                mNeedMenuInvalidate = true;
1158            }
1159            if (moveToStateNow) {
1160                moveToState(fragment);
1161            }
1162        }
1163    }
1164
1165    public void removeFragment(Fragment fragment, int transition, int transitionStyle) {
1166        if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting);
1167        final boolean inactive = !fragment.isInBackStack();
1168        if (!fragment.mDetached || inactive) {
1169            if (mAdded != null) {
1170                mAdded.remove(fragment);
1171            }
1172            if (fragment.mHasMenu && fragment.mMenuVisible) {
1173                mNeedMenuInvalidate = true;
1174            }
1175            fragment.mAdded = false;
1176            fragment.mRemoving = true;
1177            moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED,
1178                    transition, transitionStyle, false);
1179        }
1180    }
1181
1182    public void hideFragment(Fragment fragment, int transition, int transitionStyle) {
1183        if (DEBUG) Log.v(TAG, "hide: " + fragment);
1184        if (!fragment.mHidden) {
1185            fragment.mHidden = true;
1186            if (fragment.mView != null) {
1187                Animation anim = loadAnimation(fragment, transition, true,
1188                        transitionStyle);
1189                if (anim != null) {
1190                    fragment.mView.startAnimation(anim);
1191                }
1192                fragment.mView.setVisibility(View.GONE);
1193            }
1194            if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
1195                mNeedMenuInvalidate = true;
1196            }
1197            fragment.onHiddenChanged(true);
1198        }
1199    }
1200
1201    public void showFragment(Fragment fragment, int transition, int transitionStyle) {
1202        if (DEBUG) Log.v(TAG, "show: " + fragment);
1203        if (fragment.mHidden) {
1204            fragment.mHidden = false;
1205            if (fragment.mView != null) {
1206                Animation anim = loadAnimation(fragment, transition, true,
1207                        transitionStyle);
1208                if (anim != null) {
1209                    fragment.mView.startAnimation(anim);
1210                }
1211                fragment.mView.setVisibility(View.VISIBLE);
1212            }
1213            if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
1214                mNeedMenuInvalidate = true;
1215            }
1216            fragment.onHiddenChanged(false);
1217        }
1218    }
1219
1220    public void detachFragment(Fragment fragment, int transition, int transitionStyle) {
1221        if (DEBUG) Log.v(TAG, "detach: " + fragment);
1222        if (!fragment.mDetached) {
1223            fragment.mDetached = true;
1224            if (fragment.mAdded) {
1225                // We are not already in back stack, so need to remove the fragment.
1226                if (mAdded != null) {
1227                    mAdded.remove(fragment);
1228                }
1229                if (fragment.mHasMenu && fragment.mMenuVisible) {
1230                    mNeedMenuInvalidate = true;
1231                }
1232                fragment.mAdded = false;
1233                moveToState(fragment, Fragment.CREATED, transition, transitionStyle, false);
1234            }
1235        }
1236    }
1237
1238    public void attachFragment(Fragment fragment, int transition, int transitionStyle) {
1239        if (DEBUG) Log.v(TAG, "attach: " + fragment);
1240        if (fragment.mDetached) {
1241            fragment.mDetached = false;
1242            if (!fragment.mAdded) {
1243                if (mAdded == null) {
1244                    mAdded = new ArrayList<Fragment>();
1245                }
1246                mAdded.add(fragment);
1247                fragment.mAdded = true;
1248                if (fragment.mHasMenu && fragment.mMenuVisible) {
1249                    mNeedMenuInvalidate = true;
1250                }
1251                moveToState(fragment, mCurState, transition, transitionStyle, false);
1252            }
1253        }
1254    }
1255
1256    public Fragment findFragmentById(int id) {
1257        if (mAdded != null) {
1258            // First look through added fragments.
1259            for (int i=mAdded.size()-1; i>=0; i--) {
1260                Fragment f = mAdded.get(i);
1261                if (f != null && f.mFragmentId == id) {
1262                    return f;
1263                }
1264            }
1265        }
1266        if (mActive != null) {
1267            // Now for any known fragment.
1268            for (int i=mActive.size()-1; i>=0; i--) {
1269                Fragment f = mActive.get(i);
1270                if (f != null && f.mFragmentId == id) {
1271                    return f;
1272                }
1273            }
1274        }
1275        return null;
1276    }
1277
1278    public Fragment findFragmentByTag(String tag) {
1279        if (mAdded != null && tag != null) {
1280            // First look through added fragments.
1281            for (int i=mAdded.size()-1; i>=0; i--) {
1282                Fragment f = mAdded.get(i);
1283                if (f != null && tag.equals(f.mTag)) {
1284                    return f;
1285                }
1286            }
1287        }
1288        if (mActive != null && tag != null) {
1289            // Now for any known fragment.
1290            for (int i=mActive.size()-1; i>=0; i--) {
1291                Fragment f = mActive.get(i);
1292                if (f != null && tag.equals(f.mTag)) {
1293                    return f;
1294                }
1295            }
1296        }
1297        return null;
1298    }
1299
1300    public Fragment findFragmentByWho(String who) {
1301        if (mActive != null && who != null) {
1302            for (int i=mActive.size()-1; i>=0; i--) {
1303                Fragment f = mActive.get(i);
1304                if (f != null && who.equals(f.mWho)) {
1305                    return f;
1306                }
1307            }
1308        }
1309        return null;
1310    }
1311
1312    private void checkStateLoss() {
1313        if (mStateSaved) {
1314            throw new IllegalStateException(
1315                    "Can not perform this action after onSaveInstanceState");
1316        }
1317        if (mNoTransactionsBecause != null) {
1318            throw new IllegalStateException(
1319                    "Can not perform this action inside of " + mNoTransactionsBecause);
1320        }
1321    }
1322
1323    public void enqueueAction(Runnable action, boolean allowStateLoss) {
1324        if (!allowStateLoss) {
1325            checkStateLoss();
1326        }
1327        synchronized (this) {
1328            if (mActivity == null) {
1329                throw new IllegalStateException("Activity has been destroyed");
1330            }
1331            if (mPendingActions == null) {
1332                mPendingActions = new ArrayList<Runnable>();
1333            }
1334            mPendingActions.add(action);
1335            if (mPendingActions.size() == 1) {
1336                mActivity.mHandler.removeCallbacks(mExecCommit);
1337                mActivity.mHandler.post(mExecCommit);
1338            }
1339        }
1340    }
1341
1342    public int allocBackStackIndex(BackStackRecord bse) {
1343        synchronized (this) {
1344            if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) {
1345                if (mBackStackIndices == null) {
1346                    mBackStackIndices = new ArrayList<BackStackRecord>();
1347                }
1348                int index = mBackStackIndices.size();
1349                if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse);
1350                mBackStackIndices.add(bse);
1351                return index;
1352
1353            } else {
1354                int index = mAvailBackStackIndices.remove(mAvailBackStackIndices.size()-1);
1355                if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse);
1356                mBackStackIndices.set(index, bse);
1357                return index;
1358            }
1359        }
1360    }
1361
1362    public void setBackStackIndex(int index, BackStackRecord bse) {
1363        synchronized (this) {
1364            if (mBackStackIndices == null) {
1365                mBackStackIndices = new ArrayList<BackStackRecord>();
1366            }
1367            int N = mBackStackIndices.size();
1368            if (index < N) {
1369                if (DEBUG) Log.v(TAG, "Setting back stack index " + index + " to " + bse);
1370                mBackStackIndices.set(index, bse);
1371            } else {
1372                while (N < index) {
1373                    mBackStackIndices.add(null);
1374                    if (mAvailBackStackIndices == null) {
1375                        mAvailBackStackIndices = new ArrayList<Integer>();
1376                    }
1377                    if (DEBUG) Log.v(TAG, "Adding available back stack index " + N);
1378                    mAvailBackStackIndices.add(N);
1379                    N++;
1380                }
1381                if (DEBUG) Log.v(TAG, "Adding back stack index " + index + " with " + bse);
1382                mBackStackIndices.add(bse);
1383            }
1384        }
1385    }
1386
1387    public void freeBackStackIndex(int index) {
1388        synchronized (this) {
1389            mBackStackIndices.set(index, null);
1390            if (mAvailBackStackIndices == null) {
1391                mAvailBackStackIndices = new ArrayList<Integer>();
1392            }
1393            if (DEBUG) Log.v(TAG, "Freeing back stack index " + index);
1394            mAvailBackStackIndices.add(index);
1395        }
1396    }
1397
1398    /**
1399     * Only call from main thread!
1400     */
1401    public boolean execPendingActions() {
1402        if (mExecutingActions) {
1403            throw new IllegalStateException("Recursive entry to executePendingTransactions");
1404        }
1405
1406        if (Looper.myLooper() != mActivity.mHandler.getLooper()) {
1407            throw new IllegalStateException("Must be called from main thread of process");
1408        }
1409
1410        boolean didSomething = false;
1411
1412        while (true) {
1413            int numActions;
1414
1415            synchronized (this) {
1416                if (mPendingActions == null || mPendingActions.size() == 0) {
1417                    break;
1418                }
1419
1420                numActions = mPendingActions.size();
1421                if (mTmpActions == null || mTmpActions.length < numActions) {
1422                    mTmpActions = new Runnable[numActions];
1423                }
1424                mPendingActions.toArray(mTmpActions);
1425                mPendingActions.clear();
1426                mActivity.mHandler.removeCallbacks(mExecCommit);
1427            }
1428
1429            mExecutingActions = true;
1430            for (int i=0; i<numActions; i++) {
1431                mTmpActions[i].run();
1432                mTmpActions[i] = null;
1433            }
1434            mExecutingActions = false;
1435            didSomething = true;
1436        }
1437
1438        if (mHavePendingDeferredStart) {
1439            boolean loadersRunning = false;
1440            for (int i=0; i<mActive.size(); i++) {
1441                Fragment f = mActive.get(i);
1442                if (f != null && f.mLoaderManager != null) {
1443                    loadersRunning |= f.mLoaderManager.hasRunningLoaders();
1444                }
1445            }
1446            if (!loadersRunning) {
1447                mHavePendingDeferredStart = false;
1448                startPendingDeferredFragments();
1449            }
1450        }
1451        return didSomething;
1452    }
1453
1454    void reportBackStackChanged() {
1455        if (mBackStackChangeListeners != null) {
1456            for (int i=0; i<mBackStackChangeListeners.size(); i++) {
1457                mBackStackChangeListeners.get(i).onBackStackChanged();
1458            }
1459        }
1460    }
1461
1462    void addBackStackState(BackStackRecord state) {
1463        if (mBackStack == null) {
1464            mBackStack = new ArrayList<BackStackRecord>();
1465        }
1466        mBackStack.add(state);
1467        reportBackStackChanged();
1468    }
1469
1470    boolean popBackStackState(Handler handler, String name, int id, int flags) {
1471        if (mBackStack == null) {
1472            return false;
1473        }
1474        if (name == null && id < 0 && (flags&POP_BACK_STACK_INCLUSIVE) == 0) {
1475            int last = mBackStack.size()-1;
1476            if (last < 0) {
1477                return false;
1478            }
1479            final BackStackRecord bss = mBackStack.remove(last);
1480            bss.popFromBackStack(true);
1481            reportBackStackChanged();
1482        } else {
1483            int index = -1;
1484            if (name != null || id >= 0) {
1485                // If a name or ID is specified, look for that place in
1486                // the stack.
1487                index = mBackStack.size()-1;
1488                while (index >= 0) {
1489                    BackStackRecord bss = mBackStack.get(index);
1490                    if (name != null && name.equals(bss.getName())) {
1491                        break;
1492                    }
1493                    if (id >= 0 && id == bss.mIndex) {
1494                        break;
1495                    }
1496                    index--;
1497                }
1498                if (index < 0) {
1499                    return false;
1500                }
1501                if ((flags&POP_BACK_STACK_INCLUSIVE) != 0) {
1502                    index--;
1503                    // Consume all following entries that match.
1504                    while (index >= 0) {
1505                        BackStackRecord bss = mBackStack.get(index);
1506                        if ((name != null && name.equals(bss.getName()))
1507                                || (id >= 0 && id == bss.mIndex)) {
1508                            index--;
1509                            continue;
1510                        }
1511                        break;
1512                    }
1513                }
1514            }
1515            if (index == mBackStack.size()-1) {
1516                return false;
1517            }
1518            final ArrayList<BackStackRecord> states
1519                    = new ArrayList<BackStackRecord>();
1520            for (int i=mBackStack.size()-1; i>index; i--) {
1521                states.add(mBackStack.remove(i));
1522            }
1523            final int LAST = states.size()-1;
1524            for (int i=0; i<=LAST; i++) {
1525                if (DEBUG) Log.v(TAG, "Popping back stack state: " + states.get(i));
1526                states.get(i).popFromBackStack(i == LAST);
1527            }
1528            reportBackStackChanged();
1529        }
1530        return true;
1531    }
1532
1533    ArrayList<Fragment> retainNonConfig() {
1534        ArrayList<Fragment> fragments = null;
1535        if (mActive != null) {
1536            for (int i=0; i<mActive.size(); i++) {
1537                Fragment f = mActive.get(i);
1538                if (f != null && f.mRetainInstance) {
1539                    if (fragments == null) {
1540                        fragments = new ArrayList<Fragment>();
1541                    }
1542                    fragments.add(f);
1543                    f.mRetaining = true;
1544                    f.mTargetIndex = f.mTarget != null ? f.mTarget.mIndex : -1;
1545                    if (DEBUG) Log.v(TAG, "retainNonConfig: keeping retained " + f);
1546                }
1547            }
1548        }
1549        return fragments;
1550    }
1551
1552    void saveFragmentViewState(Fragment f) {
1553        if (f.mInnerView == null) {
1554            return;
1555        }
1556        if (mStateArray == null) {
1557            mStateArray = new SparseArray<Parcelable>();
1558        } else {
1559            mStateArray.clear();
1560        }
1561        f.mInnerView.saveHierarchyState(mStateArray);
1562        if (mStateArray.size() > 0) {
1563            f.mSavedViewState = mStateArray;
1564            mStateArray = null;
1565        }
1566    }
1567
1568    Bundle saveFragmentBasicState(Fragment f) {
1569        Bundle result = null;
1570
1571        if (mStateBundle == null) {
1572            mStateBundle = new Bundle();
1573        }
1574        f.onSaveInstanceState(mStateBundle);
1575        if (!mStateBundle.isEmpty()) {
1576            result = mStateBundle;
1577            mStateBundle = null;
1578        }
1579
1580        if (f.mView != null) {
1581            saveFragmentViewState(f);
1582        }
1583        if (f.mSavedViewState != null) {
1584            if (result == null) {
1585                result = new Bundle();
1586            }
1587            result.putSparseParcelableArray(
1588                    FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
1589        }
1590        if (!f.mUserVisibleHint) {
1591            if (result == null) {
1592                result = new Bundle();
1593            }
1594            // Only add this if it's not the default value
1595            result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint);
1596        }
1597
1598        return result;
1599    }
1600
1601    Parcelable saveAllState() {
1602        // Make sure all pending operations have now been executed to get
1603        // our state update-to-date.
1604        execPendingActions();
1605
1606        if (HONEYCOMB) {
1607            // As of Honeycomb, we save state after pausing.  Prior to that
1608            // it is before pausing.  With fragments this is an issue, since
1609            // there are many things you may do after pausing but before
1610            // stopping that change the fragment state.  For those older
1611            // devices, we will not at this point say that we have saved
1612            // the state, so we will allow them to continue doing fragment
1613            // transactions.  This retains the same semantics as Honeycomb,
1614            // though you do have the risk of losing the very most recent state
1615            // if the process is killed...  we'll live with that.
1616            mStateSaved = true;
1617        }
1618
1619        if (mActive == null || mActive.size() <= 0) {
1620            return null;
1621        }
1622
1623        // First collect all active fragments.
1624        int N = mActive.size();
1625        FragmentState[] active = new FragmentState[N];
1626        boolean haveFragments = false;
1627        for (int i=0; i<N; i++) {
1628            Fragment f = mActive.get(i);
1629            if (f != null) {
1630                if (f.mIndex < 0) {
1631                    String msg = "Failure saving state: active " + f
1632                            + " has cleared index: " + f.mIndex;
1633                    Log.e(TAG, msg);
1634                    dump("  ", null, new PrintWriter(new LogWriter(TAG)), new String[] { });
1635                    throw new IllegalStateException(msg);
1636                }
1637
1638                haveFragments = true;
1639
1640                FragmentState fs = new FragmentState(f);
1641                active[i] = fs;
1642
1643                if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
1644                    fs.mSavedFragmentState = saveFragmentBasicState(f);
1645
1646                    if (f.mTarget != null) {
1647                        if (f.mTarget.mIndex < 0) {
1648                            String msg = "Failure saving state: " + f
1649                                + " has target not in fragment manager: " + f.mTarget;
1650                            Log.e(TAG, msg);
1651                            dump("  ", null, new PrintWriter(new LogWriter(TAG)), new String[] { });
1652                            throw new IllegalStateException(msg);
1653                        }
1654                        if (fs.mSavedFragmentState == null) {
1655                            fs.mSavedFragmentState = new Bundle();
1656                        }
1657                        putFragment(fs.mSavedFragmentState,
1658                                FragmentManagerImpl.TARGET_STATE_TAG, f.mTarget);
1659                        if (f.mTargetRequestCode != 0) {
1660                            fs.mSavedFragmentState.putInt(
1661                                    FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG,
1662                                    f.mTargetRequestCode);
1663                        }
1664                    }
1665
1666                } else {
1667                    fs.mSavedFragmentState = f.mSavedFragmentState;
1668                }
1669
1670                if (DEBUG) Log.v(TAG, "Saved state of " + f + ": "
1671                        + fs.mSavedFragmentState);
1672            }
1673        }
1674
1675        if (!haveFragments) {
1676            if (DEBUG) Log.v(TAG, "saveAllState: no fragments!");
1677            return null;
1678        }
1679
1680        int[] added = null;
1681        BackStackState[] backStack = null;
1682
1683        // Build list of currently added fragments.
1684        if (mAdded != null) {
1685            N = mAdded.size();
1686            if (N > 0) {
1687                added = new int[N];
1688                for (int i=0; i<N; i++) {
1689                    added[i] = mAdded.get(i).mIndex;
1690                    if (added[i] < 0) {
1691                        String msg = "Failure saving state: active " + mAdded.get(i)
1692                                + " has cleared index: " + added[i];
1693                        Log.e(TAG, msg);
1694                        dump("  ", null, new PrintWriter(new LogWriter(TAG)), new String[] { });
1695                        throw new IllegalStateException(msg);
1696                    }
1697                    if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i
1698                            + ": " + mAdded.get(i));
1699                }
1700            }
1701        }
1702
1703        // Now save back stack.
1704        if (mBackStack != null) {
1705            N = mBackStack.size();
1706            if (N > 0) {
1707                backStack = new BackStackState[N];
1708                for (int i=0; i<N; i++) {
1709                    backStack[i] = new BackStackState(this, mBackStack.get(i));
1710                    if (DEBUG) Log.v(TAG, "saveAllState: adding back stack #" + i
1711                            + ": " + mBackStack.get(i));
1712                }
1713            }
1714        }
1715
1716        FragmentManagerState fms = new FragmentManagerState();
1717        fms.mActive = active;
1718        fms.mAdded = added;
1719        fms.mBackStack = backStack;
1720        return fms;
1721    }
1722
1723    void restoreAllState(Parcelable state, ArrayList<Fragment> nonConfig) {
1724        // If there is no saved state at all, then there can not be
1725        // any nonConfig fragments either, so that is that.
1726        if (state == null) return;
1727        FragmentManagerState fms = (FragmentManagerState)state;
1728        if (fms.mActive == null) return;
1729
1730        // First re-attach any non-config instances we are retaining back
1731        // to their saved state, so we don't try to instantiate them again.
1732        if (nonConfig != null) {
1733            for (int i=0; i<nonConfig.size(); i++) {
1734                Fragment f = nonConfig.get(i);
1735                if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f);
1736                FragmentState fs = fms.mActive[f.mIndex];
1737                fs.mInstance = f;
1738                f.mSavedViewState = null;
1739                f.mBackStackNesting = 0;
1740                f.mInLayout = false;
1741                f.mAdded = false;
1742                f.mTarget = null;
1743                if (fs.mSavedFragmentState != null) {
1744                    fs.mSavedFragmentState.setClassLoader(mActivity.getClassLoader());
1745                    f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray(
1746                            FragmentManagerImpl.VIEW_STATE_TAG);
1747                }
1748            }
1749        }
1750
1751        // Build the full list of active fragments, instantiating them from
1752        // their saved state.
1753        mActive = new ArrayList<Fragment>(fms.mActive.length);
1754        if (mAvailIndices != null) {
1755            mAvailIndices.clear();
1756        }
1757        for (int i=0; i<fms.mActive.length; i++) {
1758            FragmentState fs = fms.mActive[i];
1759            if (fs != null) {
1760                Fragment f = fs.instantiate(mActivity);
1761                if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": " + f);
1762                mActive.add(f);
1763                // Now that the fragment is instantiated (or came from being
1764                // retained above), clear mInstance in case we end up re-restoring
1765                // from this FragmentState again.
1766                fs.mInstance = null;
1767            } else {
1768                if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": (null)");
1769                mActive.add(null);
1770                if (mAvailIndices == null) {
1771                    mAvailIndices = new ArrayList<Integer>();
1772                }
1773                if (DEBUG) Log.v(TAG, "restoreAllState: adding avail #" + i);
1774                mAvailIndices.add(i);
1775            }
1776        }
1777
1778        // Update the target of all retained fragments.
1779        if (nonConfig != null) {
1780            for (int i=0; i<nonConfig.size(); i++) {
1781                Fragment f = nonConfig.get(i);
1782                if (f.mTargetIndex >= 0) {
1783                    if (f.mTargetIndex < mActive.size()) {
1784                        f.mTarget = mActive.get(f.mTargetIndex);
1785                    } else {
1786                        Log.w(TAG, "Re-attaching retained fragment " + f
1787                                + " target no longer exists: " + f.mTargetIndex);
1788                        f.mTarget = null;
1789                    }
1790                }
1791            }
1792        }
1793
1794        // Build the list of currently added fragments.
1795        if (fms.mAdded != null) {
1796            mAdded = new ArrayList<Fragment>(fms.mAdded.length);
1797            for (int i=0; i<fms.mAdded.length; i++) {
1798                Fragment f = mActive.get(fms.mAdded[i]);
1799                if (f == null) {
1800                    throw new IllegalStateException(
1801                            "No instantiated fragment for index #" + fms.mAdded[i]);
1802                }
1803                f.mAdded = true;
1804                if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f);
1805                mAdded.add(f);
1806            }
1807        } else {
1808            mAdded = null;
1809        }
1810
1811        // Build the back stack.
1812        if (fms.mBackStack != null) {
1813            mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length);
1814            for (int i=0; i<fms.mBackStack.length; i++) {
1815                BackStackRecord bse = fms.mBackStack[i].instantiate(this);
1816                if (DEBUG) Log.v(TAG, "restoreAllState: adding bse #" + i
1817                        + " (index " + bse.mIndex + "): " + bse);
1818                mBackStack.add(bse);
1819                if (bse.mIndex >= 0) {
1820                    setBackStackIndex(bse.mIndex, bse);
1821                }
1822            }
1823        } else {
1824            mBackStack = null;
1825        }
1826    }
1827
1828    public void attachActivity(FragmentActivity activity) {
1829        if (mActivity != null) throw new IllegalStateException();
1830        mActivity = activity;
1831    }
1832
1833    public void noteStateNotSaved() {
1834        mStateSaved = false;
1835    }
1836
1837    public void dispatchCreate() {
1838        mStateSaved = false;
1839        moveToState(Fragment.CREATED, false);
1840    }
1841
1842    public void dispatchActivityCreated() {
1843        mStateSaved = false;
1844        moveToState(Fragment.ACTIVITY_CREATED, false);
1845    }
1846
1847    public void dispatchStart() {
1848        mStateSaved = false;
1849        moveToState(Fragment.STARTED, false);
1850    }
1851
1852    public void dispatchResume() {
1853        mStateSaved = false;
1854        moveToState(Fragment.RESUMED, false);
1855    }
1856
1857    public void dispatchPause() {
1858        moveToState(Fragment.STARTED, false);
1859    }
1860
1861    public void dispatchStop() {
1862        // See saveAllState() for the explanation of this.  We do this for
1863        // all platform versions, to keep our behavior more consistent between
1864        // them.
1865        mStateSaved = true;
1866
1867        moveToState(Fragment.STOPPED, false);
1868    }
1869
1870    public void dispatchReallyStop() {
1871        moveToState(Fragment.ACTIVITY_CREATED, false);
1872    }
1873
1874    public void dispatchDestroy() {
1875        mDestroyed = true;
1876        execPendingActions();
1877        moveToState(Fragment.INITIALIZING, false);
1878        mActivity = null;
1879    }
1880
1881    public void dispatchConfigurationChanged(Configuration newConfig) {
1882        if (mAdded != null) {
1883            for (int i=0; i<mAdded.size(); i++) {
1884                Fragment f = mAdded.get(i);
1885                if (f != null) {
1886                    f.onConfigurationChanged(newConfig);
1887                }
1888            }
1889        }
1890    }
1891
1892    public void dispatchLowMemory() {
1893        if (mAdded != null) {
1894            for (int i=0; i<mAdded.size(); i++) {
1895                Fragment f = mAdded.get(i);
1896                if (f != null) {
1897                    f.onLowMemory();
1898                }
1899            }
1900        }
1901    }
1902
1903    public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
1904        boolean show = false;
1905        ArrayList<Fragment> newMenus = null;
1906        if (mAdded != null) {
1907            for (int i=0; i<mAdded.size(); i++) {
1908                Fragment f = mAdded.get(i);
1909                if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
1910                    show = true;
1911                    f.onCreateOptionsMenu(menu, inflater);
1912                    if (newMenus == null) {
1913                        newMenus = new ArrayList<Fragment>();
1914                    }
1915                    newMenus.add(f);
1916                }
1917            }
1918        }
1919
1920        if (mCreatedMenus != null) {
1921            for (int i=0; i<mCreatedMenus.size(); i++) {
1922                Fragment f = mCreatedMenus.get(i);
1923                if (newMenus == null || !newMenus.contains(f)) {
1924                    f.onDestroyOptionsMenu();
1925                }
1926            }
1927        }
1928
1929        mCreatedMenus = newMenus;
1930
1931        return show;
1932    }
1933
1934    public boolean dispatchPrepareOptionsMenu(Menu menu) {
1935        boolean show = false;
1936        if (mAdded != null) {
1937            for (int i=0; i<mAdded.size(); i++) {
1938                Fragment f = mAdded.get(i);
1939                if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
1940                    show = true;
1941                    f.onPrepareOptionsMenu(menu);
1942                }
1943            }
1944        }
1945        return show;
1946    }
1947
1948    public boolean dispatchOptionsItemSelected(MenuItem item) {
1949        if (mAdded != null) {
1950            for (int i=0; i<mAdded.size(); i++) {
1951                Fragment f = mAdded.get(i);
1952                if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
1953                    if (f.onOptionsItemSelected(item)) {
1954                        return true;
1955                    }
1956                }
1957            }
1958        }
1959        return false;
1960    }
1961
1962    public boolean dispatchContextItemSelected(MenuItem item) {
1963        if (mAdded != null) {
1964            for (int i=0; i<mAdded.size(); i++) {
1965                Fragment f = mAdded.get(i);
1966                if (f != null && !f.mHidden && f.mUserVisibleHint) {
1967                    if (f.onContextItemSelected(item)) {
1968                        return true;
1969                    }
1970                }
1971            }
1972        }
1973        return false;
1974    }
1975
1976    public void dispatchOptionsMenuClosed(Menu menu) {
1977        if (mAdded != null) {
1978            for (int i=0; i<mAdded.size(); i++) {
1979                Fragment f = mAdded.get(i);
1980                if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
1981                    f.onOptionsMenuClosed(menu);
1982                }
1983            }
1984        }
1985    }
1986
1987    public static int reverseTransit(int transit) {
1988        int rev = 0;
1989        switch (transit) {
1990            case FragmentTransaction.TRANSIT_FRAGMENT_OPEN:
1991                rev = FragmentTransaction.TRANSIT_FRAGMENT_CLOSE;
1992                break;
1993            case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE:
1994                rev = FragmentTransaction.TRANSIT_FRAGMENT_OPEN;
1995                break;
1996            case FragmentTransaction.TRANSIT_FRAGMENT_FADE:
1997                rev = FragmentTransaction.TRANSIT_FRAGMENT_FADE;
1998                break;
1999        }
2000        return rev;
2001
2002    }
2003
2004    public static final int ANIM_STYLE_OPEN_ENTER = 1;
2005    public static final int ANIM_STYLE_OPEN_EXIT = 2;
2006    public static final int ANIM_STYLE_CLOSE_ENTER = 3;
2007    public static final int ANIM_STYLE_CLOSE_EXIT = 4;
2008    public static final int ANIM_STYLE_FADE_ENTER = 5;
2009    public static final int ANIM_STYLE_FADE_EXIT = 6;
2010
2011    public static int transitToStyleIndex(int transit, boolean enter) {
2012        int animAttr = -1;
2013        switch (transit) {
2014            case FragmentTransaction.TRANSIT_FRAGMENT_OPEN:
2015                animAttr = enter ? ANIM_STYLE_OPEN_ENTER : ANIM_STYLE_OPEN_EXIT;
2016                break;
2017            case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE:
2018                animAttr = enter ? ANIM_STYLE_CLOSE_ENTER : ANIM_STYLE_CLOSE_EXIT;
2019                break;
2020            case FragmentTransaction.TRANSIT_FRAGMENT_FADE:
2021                animAttr = enter ? ANIM_STYLE_FADE_ENTER : ANIM_STYLE_FADE_EXIT;
2022                break;
2023        }
2024        return animAttr;
2025    }
2026}
2027