15ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn/*
25ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn * Copyright (C) 2010 The Android Open Source Project
35ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn *
45ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
55ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn * you may not use this file except in compliance with the License.
65ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn * You may obtain a copy of the License at
75ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn *
85ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
95ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn *
105ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
115ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
125ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn * See the License for the specific language governing permissions and
145ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn * limitations under the License.
155ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn */
165ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
175ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackbornpackage android.app;
185ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
19d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport com.android.internal.util.FastPrintWriter;
20d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
21d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.graphics.Rect;
225ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackbornimport android.os.Parcel;
235ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackbornimport android.os.Parcelable;
24c6669ca63299219d815464129dac051ab2404286Dianne Hackbornimport android.text.TextUtils;
25d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.transition.Transition;
26d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.transition.TransitionManager;
27d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.transition.TransitionSet;
28c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mountimport android.transition.TransitionUtils;
29d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.util.ArrayMap;
30445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackbornimport android.util.Log;
31f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackbornimport android.util.LogWriter;
32d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.util.Pair;
33c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mountimport android.util.SparseArray;
34d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.view.View;
35d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mountimport android.view.ViewGroup;
36c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mountimport android.view.ViewTreeObserver;
375ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
3830d7189067524000c738c188c4ff91f84f474d25Dianne Hackbornimport java.io.FileDescriptor;
3930d7189067524000c738c188c4ff91f84f474d25Dianne Hackbornimport java.io.PrintWriter;
405ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackbornimport java.util.ArrayList;
417ce5d75dc920823d83e2e34fefc3875dc8868411George Mountimport java.util.List;
425ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
435ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackbornfinal class BackStackState implements Parcelable {
445ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    final int[] mOps;
455ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    final int mTransition;
465ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    final int mTransitionStyle;
475ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    final String mName;
48dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    final int mIndex;
49c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    final int mBreadCrumbTitleRes;
50c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    final CharSequence mBreadCrumbTitleText;
51c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    final int mBreadCrumbShortTitleRes;
52c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    final CharSequence mBreadCrumbShortTitleText;
53d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    final ArrayList<String> mSharedElementSourceNames;
54d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    final ArrayList<String> mSharedElementTargetNames;
55c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
56c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
57445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn        int numRemoved = 0;
58c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        BackStackRecord.Op op = bse.mHead;
59445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn        while (op != null) {
60d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            if (op.removed != null) {
61d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                numRemoved += op.removed.size();
62d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
63445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn            op = op.next;
64445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn        }
65d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        mOps = new int[bse.mNumOp * 7 + numRemoved];
66c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
67b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        if (!bse.mAddToBackStack) {
68b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn            throw new IllegalStateException("Not on back stack");
69b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        }
70b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn
71445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn        op = bse.mHead;
725ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        int pos = 0;
735ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        while (op != null) {
745ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            mOps[pos++] = op.cmd;
75ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn            mOps[pos++] = op.fragment != null ? op.fragment.mIndex : -1;
765ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            mOps[pos++] = op.enterAnim;
775ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            mOps[pos++] = op.exitAnim;
78bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase            mOps[pos++] = op.popEnterAnim;
79bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase            mOps[pos++] = op.popExitAnim;
80445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn            if (op.removed != null) {
81445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn                final int N = op.removed.size();
82445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn                mOps[pos++] = N;
83d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                for (int i = 0; i < N; i++) {
84445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn                    mOps[pos++] = op.removed.get(i).mIndex;
85445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn                }
86445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn            } else {
87445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn                mOps[pos++] = 0;
88445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn            }
895ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            op = op.next;
905ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
915ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mTransition = bse.mTransition;
925ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mTransitionStyle = bse.mTransitionStyle;
935ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mName = bse.mName;
94dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        mIndex = bse.mIndex;
95c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbTitleRes = bse.mBreadCrumbTitleRes;
96c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbTitleText = bse.mBreadCrumbTitleText;
97c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbShortTitleRes = bse.mBreadCrumbShortTitleRes;
98c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbShortTitleText = bse.mBreadCrumbShortTitleText;
99d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        mSharedElementSourceNames = bse.mSharedElementSourceNames;
100d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        mSharedElementTargetNames = bse.mSharedElementTargetNames;
1015ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
102c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
1035ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public BackStackState(Parcel in) {
1045ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mOps = in.createIntArray();
1055ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mTransition = in.readInt();
1065ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mTransitionStyle = in.readInt();
1075ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mName = in.readString();
108dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        mIndex = in.readInt();
109c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbTitleRes = in.readInt();
110c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
111c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbShortTitleRes = in.readInt();
112c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbShortTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
113d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        mSharedElementSourceNames = in.createStringArrayList();
114d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        mSharedElementTargetNames = in.createStringArrayList();
1155ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
116c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
117c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    public BackStackRecord instantiate(FragmentManagerImpl fm) {
118c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        BackStackRecord bse = new BackStackRecord(fm);
1195ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        int pos = 0;
120f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        int num = 0;
1215ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        while (pos < mOps.length) {
122c6669ca63299219d815464129dac051ab2404286Dianne Hackborn            BackStackRecord.Op op = new BackStackRecord.Op();
1235ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            op.cmd = mOps[pos++];
124d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            if (FragmentManagerImpl.DEBUG) {
125d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                Log.v(FragmentManagerImpl.TAG,
126d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        "Instantiate " + bse + " op #" + num + " base fragment #" + mOps[pos]);
127d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
128ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn            int findex = mOps[pos++];
129ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn            if (findex >= 0) {
130ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                Fragment f = fm.mActive.get(findex);
131ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                op.fragment = f;
132ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn            } else {
133ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                op.fragment = null;
134ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn            }
1355ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            op.enterAnim = mOps[pos++];
1365ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            op.exitAnim = mOps[pos++];
137bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase            op.popEnterAnim = mOps[pos++];
138bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase            op.popExitAnim = mOps[pos++];
139445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn            final int N = mOps[pos++];
140445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn            if (N > 0) {
141445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn                op.removed = new ArrayList<Fragment>(N);
142d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                for (int i = 0; i < N; i++) {
143d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    if (FragmentManagerImpl.DEBUG) {
144d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        Log.v(FragmentManagerImpl.TAG,
145d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                                "Instantiate " + bse + " set remove fragment #" + mOps[pos]);
146d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    }
147b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn                    Fragment r = fm.mActive.get(mOps[pos++]);
148b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn                    op.removed.add(r);
149445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn                }
150445646c52128a763b56ed7bb3bd009e2f33e3e4fDianne Hackborn            }
1515ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            bse.addOp(op);
152f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            num++;
1535ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
1545ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        bse.mTransition = mTransition;
1555ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        bse.mTransitionStyle = mTransitionStyle;
1565ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        bse.mName = mName;
157dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        bse.mIndex = mIndex;
158b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        bse.mAddToBackStack = true;
159c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        bse.mBreadCrumbTitleRes = mBreadCrumbTitleRes;
160c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        bse.mBreadCrumbTitleText = mBreadCrumbTitleText;
161c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        bse.mBreadCrumbShortTitleRes = mBreadCrumbShortTitleRes;
162c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        bse.mBreadCrumbShortTitleText = mBreadCrumbShortTitleText;
163d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        bse.mSharedElementSourceNames = mSharedElementSourceNames;
164d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        bse.mSharedElementTargetNames = mSharedElementTargetNames;
165b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        bse.bumpBackStackNesting(1);
1665ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return bse;
1675ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
168c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
1695ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public int describeContents() {
1705ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return 0;
1715ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
1725ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
1735ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public void writeToParcel(Parcel dest, int flags) {
1745ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        dest.writeIntArray(mOps);
1755ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        dest.writeInt(mTransition);
1765ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        dest.writeInt(mTransitionStyle);
1775ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        dest.writeString(mName);
178dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        dest.writeInt(mIndex);
179c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        dest.writeInt(mBreadCrumbTitleRes);
180c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        TextUtils.writeToParcel(mBreadCrumbTitleText, dest, 0);
181c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        dest.writeInt(mBreadCrumbShortTitleRes);
182c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        TextUtils.writeToParcel(mBreadCrumbShortTitleText, dest, 0);
183d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        dest.writeStringList(mSharedElementSourceNames);
184d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        dest.writeStringList(mSharedElementTargetNames);
1855ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
186c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
1875ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public static final Parcelable.Creator<BackStackState> CREATOR
1885ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            = new Parcelable.Creator<BackStackState>() {
1895ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        public BackStackState createFromParcel(Parcel in) {
1905ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            return new BackStackState(in);
1915ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
192c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
1935ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        public BackStackState[] newArray(int size) {
1945ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            return new BackStackState[size];
1955ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
1965ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    };
1975ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn}
1985ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
1995ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn/**
2005ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn * @hide Entry of an operation on the fragment back stack.
2015ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn */
202ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackbornfinal class BackStackRecord extends FragmentTransaction implements
203c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        FragmentManager.BackStackEntry, Runnable {
204f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn    static final String TAG = FragmentManagerImpl.TAG;
205c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
206b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn    final FragmentManagerImpl mManager;
207c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
2085ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    static final int OP_NULL = 0;
2095ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    static final int OP_ADD = 1;
210b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn    static final int OP_REPLACE = 2;
211b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn    static final int OP_REMOVE = 3;
212b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn    static final int OP_HIDE = 4;
213b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn    static final int OP_SHOW = 5;
21447c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn    static final int OP_DETACH = 6;
21547c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn    static final int OP_ATTACH = 7;
216c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
2175ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    static final class Op {
2185ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        Op next;
2195ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        Op prev;
2205ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        int cmd;
2215ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        Fragment fragment;
2225ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        int enterAnim;
2235ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        int exitAnim;
224bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase        int popEnterAnim;
225bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase        int popExitAnim;
226b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        ArrayList<Fragment> removed;
2275ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
228c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
2295ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    Op mHead;
2305ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    Op mTail;
2315ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    int mNumOp;
2325ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    int mEnterAnim;
2335ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    int mExitAnim;
234bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase    int mPopEnterAnim;
235bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase    int mPopExitAnim;
2365ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    int mTransition;
2375ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    int mTransitionStyle;
2385ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    boolean mAddToBackStack;
2390c24a5514c1ff143a223720a090b19a86a75945fAdam Powell    boolean mAllowAddToBackStack = true;
2405ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    String mName;
2415ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    boolean mCommitted;
242f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn    int mIndex = -1;
243c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
244c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    int mBreadCrumbTitleRes;
245c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    CharSequence mBreadCrumbTitleText;
246c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    int mBreadCrumbShortTitleRes;
247c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    CharSequence mBreadCrumbShortTitleText;
248c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
249d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    ArrayList<String> mSharedElementSourceNames;
250d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    ArrayList<String> mSharedElementTargetNames;
251d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
252f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn    @Override
253f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn    public String toString() {
254f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        StringBuilder sb = new StringBuilder(128);
255f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        sb.append("BackStackEntry{");
256f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        sb.append(Integer.toHexString(System.identityHashCode(this)));
257f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        if (mIndex >= 0) {
258f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            sb.append(" #");
259f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            sb.append(mIndex);
260d04ad541def2bca8fc2d810514ee15ab97893d35Dianne Hackborn        }
261f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        if (mName != null) {
262f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            sb.append(" ");
263f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            sb.append(mName);
26430d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn        }
265f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        sb.append("}");
266f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        return sb.toString();
267f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn    }
268f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn
269f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
270f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        dump(prefix, writer, true);
271f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn    }
272f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn
273f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn    void dump(String prefix, PrintWriter writer, boolean full) {
274f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        if (full) {
275d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            writer.print(prefix);
276d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            writer.print("mName=");
277d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            writer.print(mName);
278d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            writer.print(" mIndex=");
279d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            writer.print(mIndex);
280d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            writer.print(" mCommitted=");
281d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            writer.println(mCommitted);
282f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            if (mTransition != FragmentTransaction.TRANSIT_NONE) {
283d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(prefix);
284d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print("mTransition=#");
285d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(Integer.toHexString(mTransition));
286d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(" mTransitionStyle=#");
287d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.println(Integer.toHexString(mTransitionStyle));
288f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            }
289d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            if (mEnterAnim != 0 || mExitAnim != 0) {
290d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(prefix);
291d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print("mEnterAnim=#");
292d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(Integer.toHexString(mEnterAnim));
293d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(" mExitAnim=#");
294d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.println(Integer.toHexString(mExitAnim));
295f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            }
296d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            if (mPopEnterAnim != 0 || mPopExitAnim != 0) {
297d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(prefix);
298d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print("mPopEnterAnim=#");
299d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(Integer.toHexString(mPopEnterAnim));
300d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(" mPopExitAnim=#");
301d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.println(Integer.toHexString(mPopExitAnim));
302f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            }
303f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
304d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(prefix);
305d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print("mBreadCrumbTitleRes=#");
306d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(Integer.toHexString(mBreadCrumbTitleRes));
307d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(" mBreadCrumbTitleText=");
308d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.println(mBreadCrumbTitleText);
309f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            }
310f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
311d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(prefix);
312d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print("mBreadCrumbShortTitleRes=#");
313d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
314d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(" mBreadCrumbShortTitleText=");
315d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.println(mBreadCrumbShortTitleText);
316f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            }
31730d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn        }
31830d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn
31930d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn        if (mHead != null) {
320d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            writer.print(prefix);
321d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            writer.println("Operations:");
32230d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn            String innerPrefix = prefix + "    ";
32330d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn            Op op = mHead;
32430d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn            int num = 0;
32530d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn            while (op != null) {
326f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                String cmdStr;
327f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                switch (op.cmd) {
328d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    case OP_NULL:
329d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        cmdStr = "NULL";
330d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        break;
331d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    case OP_ADD:
332d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        cmdStr = "ADD";
333d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        break;
334d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    case OP_REPLACE:
335d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        cmdStr = "REPLACE";
336d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        break;
337d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    case OP_REMOVE:
338d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        cmdStr = "REMOVE";
339d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        break;
340d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    case OP_HIDE:
341d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        cmdStr = "HIDE";
342d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        break;
343d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    case OP_SHOW:
344d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        cmdStr = "SHOW";
345d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        break;
346d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    case OP_DETACH:
347d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        cmdStr = "DETACH";
348d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        break;
349d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    case OP_ATTACH:
350d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        cmdStr = "ATTACH";
351d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        break;
352d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    default:
353d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        cmdStr = "cmd=" + op.cmd;
354d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        break;
35530d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn                }
356d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(prefix);
357d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print("  Op #");
358d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(num);
359d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(": ");
360d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(cmdStr);
361d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.print(" ");
362d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                writer.println(op.fragment);
363f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                if (full) {
364f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                    if (op.enterAnim != 0 || op.exitAnim != 0) {
365d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        writer.print(innerPrefix);
366d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        writer.print("enterAnim=#");
367d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        writer.print(Integer.toHexString(op.enterAnim));
368d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        writer.print(" exitAnim=#");
369d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        writer.println(Integer.toHexString(op.exitAnim));
370f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                    }
371f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                    if (op.popEnterAnim != 0 || op.popExitAnim != 0) {
372d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        writer.print(innerPrefix);
373d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        writer.print("popEnterAnim=#");
374d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        writer.print(Integer.toHexString(op.popEnterAnim));
375d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        writer.print(" popExitAnim=#");
376d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        writer.println(Integer.toHexString(op.popExitAnim));
377f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                    }
378bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase                }
37930d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn                if (op.removed != null && op.removed.size() > 0) {
380d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    for (int i = 0; i < op.removed.size(); i++) {
381d2835935d2df8be70d1b37d3ef3b2fe0155b3422Dianne Hackborn                        writer.print(innerPrefix);
382d2835935d2df8be70d1b37d3ef3b2fe0155b3422Dianne Hackborn                        if (op.removed.size() == 1) {
383d2835935d2df8be70d1b37d3ef3b2fe0155b3422Dianne Hackborn                            writer.print("Removed: ");
384d2835935d2df8be70d1b37d3ef3b2fe0155b3422Dianne Hackborn                        } else {
385f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                            if (i == 0) {
386f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                                writer.println("Removed:");
387f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                            }
388d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                            writer.print(innerPrefix);
389d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                            writer.print("  #");
390d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                            writer.print(i);
391d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                            writer.print(": ");
392d2835935d2df8be70d1b37d3ef3b2fe0155b3422Dianne Hackborn                        }
393d2835935d2df8be70d1b37d3ef3b2fe0155b3422Dianne Hackborn                        writer.println(op.removed.get(i));
39430d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn                    }
39530d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn                }
39630d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn                op = op.next;
397f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn                num++;
39830d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn            }
39930d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn        }
40030d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn    }
40130d7189067524000c738c188c4ff91f84f474d25Dianne Hackborn
402c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    public BackStackRecord(FragmentManagerImpl manager) {
4035ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mManager = manager;
4045ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
405c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
406c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    public int getId() {
407c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        return mIndex;
408c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    }
409c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
410327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn    public int getBreadCrumbTitleRes() {
411327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn        return mBreadCrumbTitleRes;
412327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn    }
413327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn
414327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn    public int getBreadCrumbShortTitleRes() {
415327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn        return mBreadCrumbShortTitleRes;
416327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn    }
417327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn
418c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    public CharSequence getBreadCrumbTitle() {
419c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        if (mBreadCrumbTitleRes != 0) {
420c6669ca63299219d815464129dac051ab2404286Dianne Hackborn            return mManager.mActivity.getText(mBreadCrumbTitleRes);
421c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        }
422c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        return mBreadCrumbTitleText;
423c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    }
424c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
425c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    public CharSequence getBreadCrumbShortTitle() {
426c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        if (mBreadCrumbShortTitleRes != 0) {
427c6669ca63299219d815464129dac051ab2404286Dianne Hackborn            return mManager.mActivity.getText(mBreadCrumbShortTitleRes);
428c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        }
429c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        return mBreadCrumbShortTitleText;
430c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    }
431c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
4325ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    void addOp(Op op) {
4335ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        if (mHead == null) {
4345ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            mHead = mTail = op;
4355ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        } else {
4365ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            op.prev = mTail;
4375ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            mTail.next = op;
4385ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            mTail = op;
4395ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
4405ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        op.enterAnim = mEnterAnim;
4415ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        op.exitAnim = mExitAnim;
442bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase        op.popEnterAnim = mPopEnterAnim;
443bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase        op.popExitAnim = mPopExitAnim;
4445ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mNumOp++;
4455ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
446c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
4475ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction add(Fragment fragment, String tag) {
448b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        doAddOp(0, fragment, tag, OP_ADD);
449b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        return this;
4505ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
4515ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
4525ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction add(int containerViewId, Fragment fragment) {
453b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        doAddOp(containerViewId, fragment, null, OP_ADD);
454b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        return this;
4555ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
4565ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
4575ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
458b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        doAddOp(containerViewId, fragment, tag, OP_ADD);
459b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        return this;
460b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn    }
461b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn
462b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn    private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
4633e449ce00ed2d3b271e50bc7a52798f630973bf1Dianne Hackborn        fragment.mFragmentManager = mManager;
464c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
4655ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        if (tag != null) {
4665ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
4675ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                throw new IllegalStateException("Can't change tag of fragment "
4685ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                        + fragment + ": was " + fragment.mTag
4695ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                        + " now " + tag);
4705ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            }
4715ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            fragment.mTag = tag;
4725ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
473c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
4745ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        if (containerViewId != 0) {
4755ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
4765ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                throw new IllegalStateException("Can't change container ID of fragment "
4775ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                        + fragment + ": was " + fragment.mFragmentId
4785ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                        + " now " + containerViewId);
4795ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            }
4805ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            fragment.mContainerId = fragment.mFragmentId = containerViewId;
4815ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
482c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
4835ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        Op op = new Op();
484b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        op.cmd = opcmd;
4855ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        op.fragment = fragment;
4865ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        addOp(op);
4875ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
4885ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
4895ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction replace(int containerViewId, Fragment fragment) {
4905ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return replace(containerViewId, fragment, null);
4915ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
492c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
4935ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
4945ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        if (containerViewId == 0) {
4955ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            throw new IllegalArgumentException("Must use non-zero containerViewId");
4965ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
497c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
498b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        doAddOp(containerViewId, fragment, tag, OP_REPLACE);
499b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        return this;
5005ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
501c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
5025ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction remove(Fragment fragment) {
5035ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        Op op = new Op();
5045ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        op.cmd = OP_REMOVE;
5055ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        op.fragment = fragment;
5065ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        addOp(op);
507c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
5085ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return this;
5095ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
5105ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
5115ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction hide(Fragment fragment) {
5125ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        Op op = new Op();
5135ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        op.cmd = OP_HIDE;
5145ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        op.fragment = fragment;
5155ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        addOp(op);
516c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
5175ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return this;
5185ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
519c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
5205ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction show(Fragment fragment) {
5215ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        Op op = new Op();
5225ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        op.cmd = OP_SHOW;
5235ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        op.fragment = fragment;
5245ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        addOp(op);
525c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
5265ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return this;
5275ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
528c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
52947c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn    public FragmentTransaction detach(Fragment fragment) {
53047c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn        Op op = new Op();
53147c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn        op.cmd = OP_DETACH;
53247c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn        op.fragment = fragment;
53347c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn        addOp(op);
53447c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn
53547c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn        return this;
53647c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn    }
53747c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn
53847c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn    public FragmentTransaction attach(Fragment fragment) {
53947c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn        Op op = new Op();
54047c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn        op.cmd = OP_ATTACH;
54147c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn        op.fragment = fragment;
54247c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn        addOp(op);
54347c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn
54447c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn        return this;
54547c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn    }
54647c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn
5475ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction setCustomAnimations(int enter, int exit) {
548bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase        return setCustomAnimations(enter, exit, 0, 0);
549bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase    }
550bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase
551bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase    public FragmentTransaction setCustomAnimations(int enter, int exit,
552bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase            int popEnter, int popExit) {
5535ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mEnterAnim = enter;
5545ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mExitAnim = exit;
555bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase        mPopEnterAnim = popEnter;
556bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase        mPopExitAnim = popExit;
5575ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return this;
5585ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
559c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
5605ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction setTransition(int transition) {
5615ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mTransition = transition;
5625ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return this;
5635ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
564c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
565d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    @Override
566448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount    public FragmentTransaction addSharedElement(View sharedElement, String name) {
567448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount        String transitionName = sharedElement.getTransitionName();
568448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount        if (transitionName == null) {
569448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount            throw new IllegalArgumentException("Unique transitionNames are required for all" +
570448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount                    " sharedElements");
571448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount        }
572448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount        if (mSharedElementSourceNames == null) {
573448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount            mSharedElementSourceNames = new ArrayList<String>();
574448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount            mSharedElementTargetNames = new ArrayList<String>();
575448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount        }
576448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount        mSharedElementSourceNames.add(transitionName);
577448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount        mSharedElementTargetNames.add(name);
578448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount        return this;
579448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount    }
580448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount
581448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount    /** TODO: remove this */
582448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount    @Override
583d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    public FragmentTransaction setSharedElement(View sharedElement, String name) {
5840a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount        String transitionName = sharedElement.getTransitionName();
5850a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount        if (transitionName == null) {
5860a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount            throw new IllegalArgumentException("Unique transitionNames are required for all" +
587d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    " sharedElements");
588d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
589d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        mSharedElementSourceNames = new ArrayList<String>(1);
5900a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount        mSharedElementSourceNames.add(transitionName);
591d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
592d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        mSharedElementTargetNames = new ArrayList<String>(1);
593d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        mSharedElementTargetNames.add(name);
594d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        return this;
595d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
596d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
597448bace8612b0f9a41844339ca5db1b8eac1ac5cGeorge Mount    /** TODO: remove this */
598d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    @Override
599d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    public FragmentTransaction setSharedElements(Pair<View, String>... sharedElements) {
600d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        if (sharedElements == null || sharedElements.length == 0) {
601d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            mSharedElementSourceNames = null;
602d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            mSharedElementTargetNames = null;
603d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        } else {
604d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            ArrayList<String> sourceNames = new ArrayList<String>(sharedElements.length);
605d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            ArrayList<String> targetNames = new ArrayList<String>(sharedElements.length);
606d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            for (int i = 0; i < sharedElements.length; i++) {
6070a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount                String transitionName = sharedElements[i].first.getTransitionName();
6080a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount                if (transitionName == null) {
6090a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount                    throw new IllegalArgumentException("Unique transitionNames are required for all"
6100a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount                            + " sharedElements");
611d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
6120a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount                sourceNames.add(transitionName);
613d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                targetNames.add(sharedElements[i].second);
614d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
615d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            mSharedElementSourceNames = sourceNames;
616d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            mSharedElementTargetNames = targetNames;
617d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
618d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        return this;
619d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
620d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
6215ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction setTransitionStyle(int styleRes) {
6225ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mTransitionStyle = styleRes;
6235ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return this;
6245ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
625c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
6265ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public FragmentTransaction addToBackStack(String name) {
6270c24a5514c1ff143a223720a090b19a86a75945fAdam Powell        if (!mAllowAddToBackStack) {
6280c24a5514c1ff143a223720a090b19a86a75945fAdam Powell            throw new IllegalStateException(
6290c24a5514c1ff143a223720a090b19a86a75945fAdam Powell                    "This FragmentTransaction is not allowed to be added to the back stack.");
6300c24a5514c1ff143a223720a090b19a86a75945fAdam Powell        }
6315ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mAddToBackStack = true;
6325ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mName = name;
6335ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return this;
6345ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
6355ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn
6360c24a5514c1ff143a223720a090b19a86a75945fAdam Powell    public boolean isAddToBackStackAllowed() {
6370c24a5514c1ff143a223720a090b19a86a75945fAdam Powell        return mAllowAddToBackStack;
6380c24a5514c1ff143a223720a090b19a86a75945fAdam Powell    }
6390c24a5514c1ff143a223720a090b19a86a75945fAdam Powell
6400c24a5514c1ff143a223720a090b19a86a75945fAdam Powell    public FragmentTransaction disallowAddToBackStack() {
6410c24a5514c1ff143a223720a090b19a86a75945fAdam Powell        if (mAddToBackStack) {
6420c24a5514c1ff143a223720a090b19a86a75945fAdam Powell            throw new IllegalStateException(
6430c24a5514c1ff143a223720a090b19a86a75945fAdam Powell                    "This transaction is already being added to the back stack");
6440c24a5514c1ff143a223720a090b19a86a75945fAdam Powell        }
6450c24a5514c1ff143a223720a090b19a86a75945fAdam Powell        mAllowAddToBackStack = false;
6460c24a5514c1ff143a223720a090b19a86a75945fAdam Powell        return this;
6470c24a5514c1ff143a223720a090b19a86a75945fAdam Powell    }
6480c24a5514c1ff143a223720a090b19a86a75945fAdam Powell
649c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    public FragmentTransaction setBreadCrumbTitle(int res) {
650c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbTitleRes = res;
651c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbTitleText = null;
652c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        return this;
653c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    }
654c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
655c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    public FragmentTransaction setBreadCrumbTitle(CharSequence text) {
656c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbTitleRes = 0;
657c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbTitleText = text;
658c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        return this;
659c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    }
660c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
661c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    public FragmentTransaction setBreadCrumbShortTitle(int res) {
662c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbShortTitleRes = res;
663c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbShortTitleText = null;
664c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        return this;
665c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    }
666c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
667c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    public FragmentTransaction setBreadCrumbShortTitle(CharSequence text) {
668c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbShortTitleRes = 0;
669c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        mBreadCrumbShortTitleText = text;
670c6669ca63299219d815464129dac051ab2404286Dianne Hackborn        return this;
671c6669ca63299219d815464129dac051ab2404286Dianne Hackborn    }
672c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
673b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn    void bumpBackStackNesting(int amt) {
674b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        if (!mAddToBackStack) {
675b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn            return;
676b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        }
677d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        if (FragmentManagerImpl.DEBUG) {
678d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            Log.v(TAG, "Bump nesting in " + this
679d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    + " by " + amt);
680d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
681b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        Op op = mHead;
682b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        while (op != null) {
683ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn            if (op.fragment != null) {
684ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                op.fragment.mBackStackNesting += amt;
685d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                if (FragmentManagerImpl.DEBUG) {
686d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    Log.v(TAG, "Bump nesting of "
687d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                            + op.fragment + " to " + op.fragment.mBackStackNesting);
688d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
689ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn            }
690b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn            if (op.removed != null) {
691d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                for (int i = op.removed.size() - 1; i >= 0; i--) {
692b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn                    Fragment r = op.removed.get(i);
693b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn                    r.mBackStackNesting += amt;
694d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    if (FragmentManagerImpl.DEBUG) {
695d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        Log.v(TAG, "Bump nesting of "
696d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                                + r + " to " + r.mBackStackNesting);
697d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    }
698b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn                }
699b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn            }
700b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn            op = op.next;
701b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        }
702b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn    }
703b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn
704dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public int commit() {
705ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn        return commitInternal(false);
706ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn    }
707ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn
708ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn    public int commitAllowingStateLoss() {
709ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn        return commitInternal(true);
710ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn    }
711d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
712ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn    int commitInternal(boolean allowStateLoss) {
713d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        if (mCommitted) {
714d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            throw new IllegalStateException("commit already called");
715d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
716f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        if (FragmentManagerImpl.DEBUG) {
717f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            Log.v(TAG, "Commit: " + this);
718f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
7198c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn            PrintWriter pw = new FastPrintWriter(logw, false, 1024);
720f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            dump("  ", null, pw, null);
7218c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn            pw.flush();
722f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        }
7235ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mCommitted = true;
724dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (mAddToBackStack) {
725dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            mIndex = mManager.allocBackStackIndex(this);
726dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        } else {
727dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            mIndex = -1;
728dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
729ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn        mManager.enqueueAction(this, allowStateLoss);
730dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        return mIndex;
7315ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
732d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
7335ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public void run() {
734d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        if (FragmentManagerImpl.DEBUG) {
735d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            Log.v(TAG, "Run: " + this);
736d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
737c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
738dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (mAddToBackStack) {
739dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            if (mIndex < 0) {
740dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn                throw new IllegalStateException("addToBackStack() called after commit()");
741dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            }
742dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
743dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
744b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        bumpBackStackNesting(1);
745b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn
746c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        SparseArray<Fragment> firstOutFragments = new SparseArray<Fragment>();
747c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        SparseArray<Fragment> lastInFragments = new SparseArray<Fragment>();
748c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        calculateFragments(firstOutFragments, lastInFragments);
749ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        beginTransition(firstOutFragments, lastInFragments, false);
750d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
7515ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        Op op = mHead;
7525ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        while (op != null) {
7535ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            switch (op.cmd) {
7545ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                case OP_ADD: {
7555ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    Fragment f = op.fragment;
7565ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    f.mNextAnim = op.enterAnim;
7575ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    mManager.addFragment(f, false);
758d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
759d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
760b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                case OP_REPLACE: {
761b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                    Fragment f = op.fragment;
762b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                    if (mManager.mAdded != null) {
763d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        for (int i = 0; i < mManager.mAdded.size(); i++) {
764b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                            Fragment old = mManager.mAdded.get(i);
765d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                            if (FragmentManagerImpl.DEBUG) {
766d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                                Log.v(TAG,
767d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                                        "OP_REPLACE: adding=" + f + " old=" + old);
768d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                            }
769ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                            if (f == null || old.mContainerId == f.mContainerId) {
770ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                if (old == f) {
771ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                    op.fragment = f = null;
772ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                } else {
773ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                    if (op.removed == null) {
774ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                        op.removed = new ArrayList<Fragment>();
775ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                    }
776ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                    op.removed.add(old);
777ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                    old.mNextAnim = op.exitAnim;
778ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                    if (mAddToBackStack) {
779ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                        old.mBackStackNesting += 1;
780d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                                        if (FragmentManagerImpl.DEBUG) {
781d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                                            Log.v(TAG, "Bump nesting of "
782d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                                                    + old + " to " + old.mBackStackNesting);
783d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                                        }
784ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                    }
785ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                    mManager.removeFragment(old, mTransition, mTransitionStyle);
786b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                                }
787b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                            }
788b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                        }
789b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                    }
790ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                    if (f != null) {
791ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                        f.mNextAnim = op.enterAnim;
792ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                        mManager.addFragment(f, false);
793ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                    }
794d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
795d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
7965ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                case OP_REMOVE: {
7975ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    Fragment f = op.fragment;
7985ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    f.mNextAnim = op.exitAnim;
7995ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    mManager.removeFragment(f, mTransition, mTransitionStyle);
800d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
801d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
8025ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                case OP_HIDE: {
8035ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    Fragment f = op.fragment;
8045ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    f.mNextAnim = op.exitAnim;
8055ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    mManager.hideFragment(f, mTransition, mTransitionStyle);
806d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
807d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
8085ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                case OP_SHOW: {
8095ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    Fragment f = op.fragment;
8105ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    f.mNextAnim = op.enterAnim;
8115ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    mManager.showFragment(f, mTransition, mTransitionStyle);
812d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
813d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
81447c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                case OP_DETACH: {
81547c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                    Fragment f = op.fragment;
81647c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                    f.mNextAnim = op.exitAnim;
81747c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                    mManager.detachFragment(f, mTransition, mTransitionStyle);
818d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
819d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
82047c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                case OP_ATTACH: {
82147c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                    Fragment f = op.fragment;
82247c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                    f.mNextAnim = op.enterAnim;
82347c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                    mManager.attachFragment(f, mTransition, mTransitionStyle);
824d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
825d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
8265ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                default: {
8275ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
8285ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                }
8295ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            }
830c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
8315ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            op = op.next;
8325ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
833c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
8345ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        mManager.moveToState(mManager.mCurState, mTransition,
8355ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                mTransitionStyle, true);
836c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
8375ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        if (mAddToBackStack) {
8385ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            mManager.addBackStackState(this);
8395ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
8405ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
841c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
842c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private static void setFirstOut(SparseArray<Fragment> fragments, Fragment fragment) {
843c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (fragment != null) {
844c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            int containerId = fragment.mContainerId;
845c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            if (containerId != 0 && !fragment.isHidden() && fragment.isAdded() &&
846c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    fragment.getView() != null && fragments.get(containerId) == null) {
847c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                fragments.put(containerId, fragment);
848c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            }
849c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
850c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
851c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
852c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private void setLastIn(SparseArray<Fragment> fragments, Fragment fragment) {
853c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (fragment != null) {
854c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            int containerId = fragment.mContainerId;
855c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            if (containerId != 0) {
856c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                fragments.put(containerId, fragment);
857c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            }
858c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
859c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
860c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
861c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    /**
862c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * Finds the first removed fragment and last added fragments when going forward.
863c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * If none of the fragments have transitions, then both lists will be empty.
864c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *
865c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param firstOutFragments The list of first fragments to be removed, keyed on the
866c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *                          container ID. This list will be modified by the method.
867c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param lastInFragments The list of last fragments to be added, keyed on the
868c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *                        container ID. This list will be modified by the method.
869c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     */
870c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private void calculateFragments(SparseArray<Fragment> firstOutFragments,
871c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            SparseArray<Fragment> lastInFragments) {
8720b26e4d58ab1a60340dd7ab35ca6e3bddff9f760George Mount        if (!mManager.mContainer.hasView()) {
8730b26e4d58ab1a60340dd7ab35ca6e3bddff9f760George Mount            return; // nothing to see, so no transitions
8740b26e4d58ab1a60340dd7ab35ca6e3bddff9f760George Mount        }
875c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        Op op = mHead;
876c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        while (op != null) {
877c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            switch (op.cmd) {
878c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_ADD:
879c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setLastIn(lastInFragments, op.fragment);
880c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
881c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_REPLACE: {
882c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    Fragment f = op.fragment;
883c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    if (mManager.mAdded != null) {
884c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                        for (int i = 0; i < mManager.mAdded.size(); i++) {
885c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                            Fragment old = mManager.mAdded.get(i);
886c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                            if (f == null || old.mContainerId == f.mContainerId) {
887c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                                if (old == f) {
888c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                                    f = null;
889c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                                } else {
890c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                                    setFirstOut(firstOutFragments, old);
891c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                                }
892c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                            }
893c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                        }
894c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    }
895c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setLastIn(lastInFragments, f);
896c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
897c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                }
898c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_REMOVE:
899c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
900c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
901c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_HIDE:
902c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
903c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
904c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_SHOW:
905c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setLastIn(lastInFragments, op.fragment);
906c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
907c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_DETACH:
908c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
909c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
910c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_ATTACH:
911c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setLastIn(lastInFragments, op.fragment);
912c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
913c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            }
914c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
915c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            op = op.next;
916c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
917c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
918c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
919c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    /**
920c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * Finds the first removed fragment and last added fragments when popping the back stack.
921c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * If none of the fragments have transitions, then both lists will be empty.
922c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *
923c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param firstOutFragments The list of first fragments to be removed, keyed on the
924c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *                          container ID. This list will be modified by the method.
925c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param lastInFragments The list of last fragments to be added, keyed on the
926c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *                        container ID. This list will be modified by the method.
927c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     */
928c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    public void calculateBackFragments(SparseArray<Fragment> firstOutFragments,
929c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            SparseArray<Fragment> lastInFragments) {
9300b26e4d58ab1a60340dd7ab35ca6e3bddff9f760George Mount        if (!mManager.mContainer.hasView()) {
9310b26e4d58ab1a60340dd7ab35ca6e3bddff9f760George Mount            return; // nothing to see, so no transitions
9320b26e4d58ab1a60340dd7ab35ca6e3bddff9f760George Mount        }
933c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        Op op = mHead;
934c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        while (op != null) {
935c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            switch (op.cmd) {
936c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_ADD:
937c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
938c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
939c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_REPLACE:
940c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    if (op.removed != null) {
941c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                        for (int i = op.removed.size() - 1; i >= 0; i--) {
942c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                            setLastIn(lastInFragments, op.removed.get(i));
943c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                        }
944c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    }
945c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
946c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
947c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_REMOVE:
948c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setLastIn(lastInFragments, op.fragment);
949c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
950c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_HIDE:
951c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setLastIn(lastInFragments, op.fragment);
952c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
953c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_SHOW:
954c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
955c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
956c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_DETACH:
957c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setLastIn(lastInFragments, op.fragment);
958c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
959c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                case OP_ATTACH:
960c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
961c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    break;
962c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            }
963c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
964c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            op = op.next;
965d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
966c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
967c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
968c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    /**
969c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * When custom fragment transitions are used, this sets up the state for each transition
970c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * and begins the transition. A different transition is started for each fragment container
971c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * and consists of up to 3 different transitions: the exit transition, a shared element
972c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * transition and an enter transition.
973c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *
974c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * <p>The exit transition operates against the leaf nodes of the first fragment
975c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * with a view that was removed. If no such fragment was removed, then no exit
976c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * transition is executed. The exit transition comes from the outgoing fragment.</p>
977c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *
978c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * <p>The enter transition operates against the last fragment that was added. If
979c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * that fragment does not have a view or no fragment was added, then no enter
980c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * transition is executed. The enter transition comes from the incoming fragment.</p>
981c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *
982c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * <p>The shared element transition operates against all views and comes either
983c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * from the outgoing fragment or the incoming fragment, depending on whether this
984c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * is going forward or popping the back stack. When going forward, the incoming
985c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * fragment's enter shared element transition is used, but when going back, the
986c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * outgoing fragment's return shared element transition is used. Shared element
987c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * transitions only operate if there is both an incoming and outgoing fragment.</p>
988c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *
989c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param firstOutFragments The list of first fragments to be removed, keyed on the
990c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *                          container ID.
991c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param lastInFragments The list of last fragments to be added, keyed on the
992c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *                        container ID.
993c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param isBack true if this is popping the back stack or false if this is a
994c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *               forward operation.
995c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @return The TransitionState used to complete the operation of the transition
996ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     * in {@link #setNameOverrides(android.app.BackStackRecord.TransitionState, java.util.ArrayList,
997ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     * java.util.ArrayList)}.
998c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     */
999c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private TransitionState beginTransition(SparseArray<Fragment> firstOutFragments,
1000c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            SparseArray<Fragment> lastInFragments, boolean isBack) {
1001d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        TransitionState state = new TransitionState();
1002c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1003d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        // Adding a non-existent target view makes sure that the transitions don't target
1004d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        // any views by default. They'll only target the views we tell add. If we don't
1005d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        // add any, then no views will be targeted.
1006c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        state.nonExistentView = new View(mManager.mActivity);
1007c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1008c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        // Go over all leaving fragments.
1009c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        for (int i = 0; i < firstOutFragments.size(); i++) {
1010c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            int containerId = firstOutFragments.keyAt(i);
1011c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            configureTransitions(containerId, state, isBack, firstOutFragments,
1012ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    lastInFragments);
1013c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1014d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1015c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        // Now go over all entering fragments that didn't have a leaving fragment.
1016c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        for (int i = 0; i < lastInFragments.size(); i++) {
1017c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            int containerId = lastInFragments.keyAt(i);
1018c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            if (firstOutFragments.get(containerId) == null) {
1019c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                configureTransitions(containerId, state, isBack, firstOutFragments,
1020ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        lastInFragments);
1021d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
1022d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
1023ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        return state;
1024ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    }
1025d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1026ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    private static Transition cloneTransition(Transition transition) {
1027ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        if (transition != null) {
1028ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            transition = transition.clone();
1029c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1030ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        return transition;
1031c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
1032d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1033c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private static Transition getEnterTransition(Fragment inFragment, boolean isBack) {
1034c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (inFragment == null) {
1035c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            return null;
1036c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1037ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        return cloneTransition(isBack ? inFragment.getReenterTransition() :
1038ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                inFragment.getEnterTransition());
1039c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
1040d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1041c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private static Transition getExitTransition(Fragment outFragment, boolean isBack) {
1042c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (outFragment == null) {
1043c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            return null;
1044c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1045ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        return cloneTransition(isBack ? outFragment.getReturnTransition() :
1046ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                outFragment.getExitTransition());
1047c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
1048d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1049c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private static Transition getSharedElementTransition(Fragment inFragment, Fragment outFragment,
1050c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            boolean isBack) {
1051c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (inFragment == null || outFragment == null) {
1052c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            return null;
1053c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1054ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        return cloneTransition(isBack ? outFragment.getSharedElementReturnTransition() :
1055ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                inFragment.getSharedElementEnterTransition());
1056d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
1057d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1058ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    private static ArrayList<View> captureExitingViews(Transition exitTransition,
10597ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            Fragment outFragment, ArrayMap<String, View> namedViews, View nonExistentView) {
1060ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        ArrayList<View> viewList = null;
1061c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (exitTransition != null) {
1062ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            viewList = new ArrayList<View>();
1063c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            View root = outFragment.getView();
1064c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            root.captureTransitioningViews(viewList);
106527bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            if (namedViews != null) {
106627bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                viewList.removeAll(namedViews.values());
106727bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            }
10687ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            if (!viewList.isEmpty()) {
10697ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                viewList.add(nonExistentView);
10707ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                addTargets(exitTransition, viewList);
10717ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            }
1072c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1073ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        return viewList;
1074c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
1075c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1076c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private ArrayMap<String, View> remapSharedElements(TransitionState state, Fragment outFragment,
1077ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            boolean isBack) {
1078ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        ArrayMap<String, View> namedViews = new ArrayMap<String, View>();
1079c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (mSharedElementSourceNames != null) {
1080c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            outFragment.getView().findNamedViews(namedViews);
1081c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            if (isBack) {
1082c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                namedViews.retainAll(mSharedElementTargetNames);
1083c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            } else {
1084c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                namedViews = remapNames(mSharedElementSourceNames, mSharedElementTargetNames,
1085ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        namedViews);
1086d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
1087d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
1088d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1089c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (isBack) {
10906558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount            outFragment.mEnterTransitionCallback.onMapSharedElements(
1091c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    mSharedElementTargetNames, namedViews);
1092c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            setBackNameOverrides(state, namedViews, false);
1093c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        } else {
10946558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount            outFragment.mExitTransitionCallback.onMapSharedElements(
1095c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    mSharedElementTargetNames, namedViews);
1096c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            setNameOverrides(state, namedViews, false);
1097c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1098d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1099c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        return namedViews;
1100c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
1101d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1102c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    /**
1103c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * Prepares the enter transition by adding a non-existent view to the transition's target list
1104c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * and setting it epicenter callback. By adding a non-existent view to the target list,
1105c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * we can prevent any view from being targeted at the beginning of the transition.
1106c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * We will add to the views before the end state of the transition is captured so that the
1107c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * views will appear. At the start of the transition, we clear the list of targets so that
1108c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * we can restore the state of the transition and use it again.
1109ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     *
1110ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     * <p>The shared element transition maps its shared elements immediately prior to
1111ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     * capturing the final state of the Transition.</p>
1112c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     */
1113ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    private ArrayList<View> addTransitionTargets(final TransitionState state,
1114ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            final Transition enterTransition, final Transition sharedElementTransition,
1115ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            final Transition overallTransition, final View container,
1116ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            final Fragment inFragment, final Fragment outFragment,
11172deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            final ArrayList<View> hiddenFragmentViews, final boolean isBack,
11182deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            final ArrayList<View> sharedElementTargets) {
1119ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        if (enterTransition == null && sharedElementTransition == null &&
1120ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                overallTransition == null) {
1121ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            return null;
1122ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        }
1123ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        final ArrayList<View> enteringViews = new ArrayList<View>();
1124ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        container.getViewTreeObserver().addOnPreDrawListener(
1125ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                new ViewTreeObserver.OnPreDrawListener() {
1126ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    @Override
1127ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    public boolean onPreDraw() {
1128ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        container.getViewTreeObserver().removeOnPreDrawListener(this);
1129ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1130ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        // Don't include any newly-hidden fragments in the transition.
1131ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        excludeHiddenFragments(hiddenFragmentViews, inFragment.mContainerId,
1132ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                                overallTransition);
1133ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
113427bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                        ArrayMap<String, View> namedViews = null;
1135ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        if (sharedElementTransition != null) {
113627bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                            namedViews = mapSharedElementsIn(state, isBack, inFragment);
11372deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                            removeTargets(sharedElementTransition, sharedElementTargets);
11382deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                            sharedElementTargets.clear();
11397ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                            sharedElementTargets.add(state.nonExistentView);
11407ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                            sharedElementTargets.addAll(namedViews.values());
11412deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount
11422deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                            addTargets(sharedElementTransition, sharedElementTargets);
1143ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1144ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                            setEpicenterIn(namedViews, state);
1145ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1146ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                            callSharedElementEnd(state, inFragment, outFragment, isBack,
1147ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                                    namedViews);
1148ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        }
1149ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1150ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        if (enterTransition != null) {
1151c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                            View view = inFragment.getView();
1152c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                            if (view != null) {
1153c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                                view.captureTransitioningViews(enteringViews);
115427bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                                if (namedViews != null) {
115527bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                                    enteringViews.removeAll(namedViews.values());
115627bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                                }
11577ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                                enteringViews.add(state.nonExistentView);
11587ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                                // We added this earlier to prevent any views being targeted.
11597ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                                enterTransition.removeTarget(state.nonExistentView);
1160ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                                addTargets(enterTransition, enteringViews);
1161c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                            }
1162ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                            setSharedElementEpicenter(enterTransition, state);
1163c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                        }
1164ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        return true;
1165ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    }
1166ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                });
1167ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        return enteringViews;
1168ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    }
1169ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1170ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    private void callSharedElementEnd(TransitionState state, Fragment inFragment,
1171ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            Fragment outFragment, boolean isBack, ArrayMap<String, View> namedViews) {
1172ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        SharedElementCallback sharedElementCallback = isBack ?
1173ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                outFragment.mEnterTransitionCallback :
1174ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                inFragment.mEnterTransitionCallback;
1175ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        ArrayList<String> names = new ArrayList<String>(namedViews.keySet());
1176ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        ArrayList<View> views = new ArrayList<View>(namedViews.values());
1177ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        sharedElementCallback.onSharedElementEnd(names, views, null);
1178ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    }
1179ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1180ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    private void setEpicenterIn(ArrayMap<String, View> namedViews, TransitionState state) {
1181ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        if (mSharedElementTargetNames != null && !namedViews.isEmpty()) {
1182ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            // now we know the epicenter of the entering transition.
1183ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            View epicenter = namedViews
1184ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    .get(mSharedElementTargetNames.get(0));
1185ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            if (epicenter != null) {
1186ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                state.enteringEpicenterView = epicenter;
1187ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            }
1188c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1189d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
1190d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1191ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    private ArrayMap<String, View> mapSharedElementsIn(TransitionState state,
1192ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            boolean isBack, Fragment inFragment) {
1193ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        // Now map the shared elements in the incoming fragment
1194ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        ArrayMap<String, View> namedViews = mapEnteringSharedElements(state, inFragment, isBack);
1195ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1196ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        // remap shared elements and set the name mapping used
1197ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        // in the shared element transition.
1198ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        if (isBack) {
1199ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            inFragment.mExitTransitionCallback.onMapSharedElements(
1200ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    mSharedElementTargetNames, namedViews);
1201ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            setBackNameOverrides(state, namedViews, true);
1202ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        } else {
1203ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            inFragment.mEnterTransitionCallback.onMapSharedElements(
1204ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    mSharedElementTargetNames, namedViews);
1205ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            setNameOverrides(state, namedViews, true);
1206ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        }
1207ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        return namedViews;
1208ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    }
1209ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1210c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private static Transition mergeTransitions(Transition enterTransition,
1211c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            Transition exitTransition, Transition sharedElementTransition, Fragment inFragment,
1212c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            boolean isBack) {
1213c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        boolean overlap = true;
1214c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (enterTransition != null && exitTransition != null) {
1215c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            overlap = isBack ? inFragment.getAllowReturnTransitionOverlap() :
1216c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    inFragment.getAllowEnterTransitionOverlap();
1217c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1218c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
121927bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount        // Wrap the transitions. Explicit targets like in enter and exit will cause the
122027bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount        // views to be targeted regardless of excluded views. If that happens, then the
122127bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount        // excluded fragments views (hidden fragments) will still be in the transition.
122227bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount
1223c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        Transition transition;
1224c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (overlap) {
122527bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            // Regular transition -- do it all together
12262deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            TransitionSet transitionSet = new TransitionSet();
12272deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            if (enterTransition != null) {
12282deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                transitionSet.addTransition(enterTransition);
122927bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            }
12302deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            if (exitTransition != null) {
12312deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                transitionSet.addTransition(exitTransition);
12322deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            }
12332deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            if (sharedElementTransition != null) {
12342deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                transitionSet.addTransition(sharedElementTransition);
12352deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            }
12362deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            transition = transitionSet;
1237d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        } else {
123827bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            // First do exit, then enter, but allow shared element transition to happen
123927bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            // during both.
124027bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            Transition staggered = null;
124127bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            if (exitTransition != null && enterTransition != null) {
124227bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                staggered = new TransitionSet()
124327bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                        .addTransition(exitTransition)
124427bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                        .addTransition(enterTransition)
124527bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                        .setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
124627bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            } else if (exitTransition != null) {
124727bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                staggered = exitTransition;
124827bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            } else if (enterTransition != null) {
124927bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                staggered = enterTransition;
125027bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            }
125127bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            if (sharedElementTransition != null) {
125227bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                TransitionSet together = new TransitionSet();
125327bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                if (staggered != null) {
125427bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                    together.addTransition(staggered);
125527bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                }
125627bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                together.addTransition(sharedElementTransition);
125727bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                transition = together;
125827bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            } else {
125927bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                transition = staggered;
126027bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            }
1261c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1262c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        return transition;
1263c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
1264c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1265c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    /**
1266c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * Configures custom transitions for a specific fragment container.
1267c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *
1268c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param containerId The container ID of the fragments to configure the transition for.
1269ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     * @param state The Transition State keeping track of the executing transitions.
1270c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param firstOutFragments The list of first fragments to be removed, keyed on the
1271c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *                          container ID.
1272c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param lastInFragments The list of last fragments to be added, keyed on the
1273c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *                        container ID.
1274c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param isBack true if this is popping the back stack or false if this is a
1275c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *               forward operation.
1276c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     */
1277c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private void configureTransitions(int containerId, TransitionState state, boolean isBack,
1278ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            SparseArray<Fragment> firstOutFragments, SparseArray<Fragment> lastInFragments) {
1279c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        ViewGroup sceneRoot = (ViewGroup) mManager.mContainer.findViewById(containerId);
1280c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (sceneRoot != null) {
1281c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            Fragment inFragment = lastInFragments.get(containerId);
1282c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            Fragment outFragment = firstOutFragments.get(containerId);
1283c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1284c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            Transition enterTransition = getEnterTransition(inFragment, isBack);
1285c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            Transition sharedElementTransition = getSharedElementTransition(inFragment, outFragment,
1286c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    isBack);
1287c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            Transition exitTransition = getExitTransition(outFragment, isBack);
1288c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1289ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            if (enterTransition == null && sharedElementTransition == null &&
1290ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    exitTransition == null) {
1291ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                return; // no transitions!
1292ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            }
129327bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            if (enterTransition != null) {
129427bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                enterTransition.addTarget(state.nonExistentView);
1295c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            }
1296ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            ArrayMap<String, View> namedViews = null;
12972deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            ArrayList<View> sharedElementTargets = new ArrayList<View>();
1298ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            if (sharedElementTransition != null) {
1299ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                namedViews = remapSharedElements(state, outFragment, isBack);
13007ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                sharedElementTargets.add(state.nonExistentView);
13017ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                sharedElementTargets.addAll(namedViews.values());
13022deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                addTargets(sharedElementTransition, sharedElementTargets);
1303ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1304ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                // Notify the start of the transition.
1305ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                SharedElementCallback callback = isBack ?
1306ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        outFragment.mEnterTransitionCallback :
1307ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        inFragment.mEnterTransitionCallback;
1308ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                ArrayList<String> names = new ArrayList<String>(namedViews.keySet());
1309ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                ArrayList<View> views = new ArrayList<View>(namedViews.values());
1310ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                callback.onSharedElementStart(names, views, null);
1311ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            }
1312c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
131327bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            ArrayList<View> exitingViews = captureExitingViews(exitTransition, outFragment,
13147ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                    namedViews, state.nonExistentView);
131527bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            if (exitingViews == null || exitingViews.isEmpty()) {
131627bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                exitTransition = null;
131727bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            }
131827bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount
1319c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            // Set the epicenter of the exit transition
132027bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount            if (mSharedElementTargetNames != null && namedViews != null) {
1321c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                View epicenterView = namedViews.get(mSharedElementTargetNames.get(0));
1322c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                if (epicenterView != null) {
132327bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                    if (exitTransition != null) {
132427bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                        setEpicenter(exitTransition, epicenterView);
132527bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                    }
132627bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                    if (sharedElementTransition != null) {
132727bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                        setEpicenter(sharedElementTransition, epicenterView);
132827bc8aa583b437ec8ae3c13920aeabdb472125e0George Mount                    }
1329c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                }
1330c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            }
1331c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1332c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            Transition transition = mergeTransitions(enterTransition, exitTransition,
1333c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    sharedElementTransition, inFragment, isBack);
1334c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1335c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            if (transition != null) {
1336ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                ArrayList<View> hiddenFragments = new ArrayList<View>();
1337ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                ArrayList<View> enteringViews = addTransitionTargets(state, enterTransition,
1338ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        sharedElementTransition, transition, sceneRoot, inFragment, outFragment,
13392deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                        hiddenFragments, isBack, sharedElementTargets);
1340ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1341c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                transition.setNameOverrides(state.nameOverrides);
1342c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                // We want to exclude hidden views later, so we need a non-null list in the
1343c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                // transition now.
1344c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                transition.excludeTarget(state.nonExistentView, true);
1345c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                // Now exclude all currently hidden fragments.
1346ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                excludeHiddenFragments(hiddenFragments, containerId, transition);
1347c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                TransitionManager.beginDelayedTransition(sceneRoot, transition);
1348ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                // Remove the view targeting after the transition starts
1349ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                removeTargetedViewsFromTransitions(sceneRoot, state.nonExistentView,
1350ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        enterTransition, enteringViews, exitTransition, exitingViews,
13512deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                        sharedElementTransition, sharedElementTargets, transition, hiddenFragments);
1352d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
1353d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
1354d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
1355d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1356c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    /**
1357ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     * After the transition has started, remove all targets that we added to the transitions
1358ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     * so that the transitions are left in a clean state.
1359ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     */
1360ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    private void removeTargetedViewsFromTransitions(
1361ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            final ViewGroup sceneRoot, final View nonExistingView,
1362ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            final Transition enterTransition, final ArrayList<View> enteringViews,
1363ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            final Transition exitTransition, final ArrayList<View> exitingViews,
13642deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount            final Transition sharedElementTransition, final ArrayList<View> sharedElementTargets,
1365ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            final Transition overallTransition, final ArrayList<View> hiddenViews) {
13662deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount        if (overallTransition != null) {
1367ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            sceneRoot.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
1368ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                @Override
1369ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                public boolean onPreDraw() {
1370ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
1371ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    if (enterTransition != null) {
1372ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        enterTransition.removeTarget(nonExistingView);
1373ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        removeTargets(enterTransition, enteringViews);
1374ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    }
1375ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    if (exitTransition != null) {
1376ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        removeTargets(exitTransition, exitingViews);
1377ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    }
13782deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                    if (sharedElementTransition != null) {
13792deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                        removeTargets(sharedElementTransition, sharedElementTargets);
13802deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount                    }
1381ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    int numViews = hiddenViews.size();
1382ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    for (int i = 0; i < numViews; i++) {
1383ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        overallTransition.excludeTarget(hiddenViews.get(i), false);
1384ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    }
1385ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    overallTransition.excludeTarget(nonExistingView, false);
1386ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    return true;
1387ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                }
1388ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            });
1389ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        }
1390ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    }
1391ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
13927ce5d75dc920823d83e2e34fefc3875dc8868411George Mount    /**
13937ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     * This method removes the views from transitions that target ONLY those views.
13947ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     * The views list should match those added in addTargets and should contain
13957ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     * one view that is not in the view hierarchy (state.nonExistentView).
13967ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     */
13977ce5d75dc920823d83e2e34fefc3875dc8868411George Mount    public static void removeTargets(Transition transition, ArrayList<View> views) {
13987ce5d75dc920823d83e2e34fefc3875dc8868411George Mount        if (transition instanceof TransitionSet) {
13997ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            TransitionSet set = (TransitionSet) transition;
14007ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            int numTransitions = set.getTransitionCount();
14017ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            for (int i = 0; i < numTransitions; i++) {
14027ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                Transition child = set.getTransitionAt(i);
14037ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                removeTargets(child, views);
14047ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            }
14057ce5d75dc920823d83e2e34fefc3875dc8868411George Mount        } else if (!hasSimpleTarget(transition)) {
14067ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            List<View> targets = transition.getTargets();
14077ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            if (targets != null && targets.size() == views.size() &&
14087ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                    targets.containsAll(views)) {
14097ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                // We have an exact match. We must have added these earlier in addTargets
14107ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                for (int i = views.size() - 1; i >= 0; i--) {
14117ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                    transition.removeTarget(views.get(i));
14127ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                }
14137ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            }
1414ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        }
1415ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    }
1416ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
14177ce5d75dc920823d83e2e34fefc3875dc8868411George Mount    /**
14187ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     * This method adds views as targets to the transition, but only if the transition
14197ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     * doesn't already have a target. It is best for views to contain one View object
14207ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     * that does not exist in the view hierarchy (state.nonExistentView) so that
14217ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     * when they are removed later, a list match will suffice to remove the targets.
14227ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     * Otherwise, if you happened to have targeted the exact views for the transition,
14237ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     * the removeTargets call will remove them unexpectedly.
14247ce5d75dc920823d83e2e34fefc3875dc8868411George Mount     */
14257ce5d75dc920823d83e2e34fefc3875dc8868411George Mount    public static void addTargets(Transition transition, ArrayList<View> views) {
14267ce5d75dc920823d83e2e34fefc3875dc8868411George Mount        if (transition instanceof TransitionSet) {
14277ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            TransitionSet set = (TransitionSet) transition;
14287ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            int numTransitions = set.getTransitionCount();
14297ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            for (int i = 0; i < numTransitions; i++) {
14307ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                Transition child = set.getTransitionAt(i);
14317ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                addTargets(child, views);
14327ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            }
14337ce5d75dc920823d83e2e34fefc3875dc8868411George Mount        } else if (!hasSimpleTarget(transition)) {
14347ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            List<View> targets = transition.getTargets();
14357ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            if (isNullOrEmpty(targets)) {
14367ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                // We can just add the target views
14377ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                int numViews = views.size();
14387ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                for (int i = 0; i < numViews; i++) {
14397ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                    transition.addTarget(views.get(i));
14407ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                }
14417ce5d75dc920823d83e2e34fefc3875dc8868411George Mount            }
1442ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        }
1443ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    }
1444ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
14457ce5d75dc920823d83e2e34fefc3875dc8868411George Mount    private static boolean hasSimpleTarget(Transition transition) {
14467ce5d75dc920823d83e2e34fefc3875dc8868411George Mount        return !isNullOrEmpty(transition.getTargetIds()) ||
14477ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                !isNullOrEmpty(transition.getTargetNames()) ||
14487ce5d75dc920823d83e2e34fefc3875dc8868411George Mount                !isNullOrEmpty(transition.getTargetTypes());
14497ce5d75dc920823d83e2e34fefc3875dc8868411George Mount    }
14507ce5d75dc920823d83e2e34fefc3875dc8868411George Mount
14517ce5d75dc920823d83e2e34fefc3875dc8868411George Mount    private static boolean isNullOrEmpty(List list) {
14527ce5d75dc920823d83e2e34fefc3875dc8868411George Mount        return list == null || list.isEmpty();
14537ce5d75dc920823d83e2e34fefc3875dc8868411George Mount    }
14547ce5d75dc920823d83e2e34fefc3875dc8868411George Mount
1455ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    /**
1456c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * Remaps a name-to-View map, substituting different names for keys.
1457c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *
1458c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param inMap A list of keys found in the map, in the order in toGoInMap
1459c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param toGoInMap A list of keys to use for the new map, in the order of inMap
1460c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param namedViews The current mapping
1461ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     * @return a new Map after it has been mapped with the new names as keys.
1462c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     */
1463c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private static ArrayMap<String, View> remapNames(ArrayList<String> inMap,
1464ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            ArrayList<String> toGoInMap, ArrayMap<String, View> namedViews) {
1465ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        ArrayMap<String, View> remappedViews = new ArrayMap<String, View>();
1466c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (!namedViews.isEmpty()) {
1467c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            int numKeys = inMap.size();
1468c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            for (int i = 0; i < numKeys; i++) {
1469c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                View view = namedViews.get(inMap.get(i));
1470ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount
1471c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                if (view != null) {
1472ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    remappedViews.put(toGoInMap.get(i), view);
1473d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
1474d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
1475d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
1476ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        return remappedViews;
1477c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
1478c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1479c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    /**
1480ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     * Maps shared elements to views in the entering fragment.
1481c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *
1482c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param state The transition State as returned from {@link #beginTransition(
1483c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * android.util.SparseArray, android.util.SparseArray, boolean)}.
1484ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount     * @param inFragment The last fragment to be added.
1485c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     * @param isBack true if this is popping the back stack or false if this is a
1486c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     *               forward operation.
1487c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount     */
1488ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    private ArrayMap<String, View> mapEnteringSharedElements(TransitionState state,
1489ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            Fragment inFragment, boolean isBack) {
1490ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount        ArrayMap<String, View> namedViews = new ArrayMap<String, View>();
1491c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        View root = inFragment.getView();
1492c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (root != null) {
1493c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            if (mSharedElementSourceNames != null) {
1494c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                root.findNamedViews(namedViews);
1495c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                if (isBack) {
1496c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    namedViews = remapNames(mSharedElementSourceNames,
1497ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                            mSharedElementTargetNames, namedViews);
1498c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                } else {
1499c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    namedViews.retainAll(mSharedElementTargetNames);
1500c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                }
1501c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            }
1502c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1503c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        return namedViews;
1504c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
1505c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1506ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount    private void excludeHiddenFragments(final ArrayList<View> hiddenFragmentViews, int containerId,
1507c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            Transition transition) {
1508d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        if (mManager.mAdded != null) {
1509d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            for (int i = 0; i < mManager.mAdded.size(); i++) {
1510d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                Fragment fragment = mManager.mAdded.get(i);
1511c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                if (fragment.mView != null && fragment.mContainer != null &&
1512c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                        fragment.mContainerId == containerId) {
1513c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    if (fragment.mHidden) {
1514ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        if (!hiddenFragmentViews.contains(fragment.mView)) {
1515c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                            transition.excludeTarget(fragment.mView, true);
1516ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                            hiddenFragmentViews.add(fragment.mView);
1517c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                        }
1518c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    } else {
1519c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                        transition.excludeTarget(fragment.mView, false);
1520ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                        hiddenFragmentViews.remove(fragment.mView);
1521c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    }
1522d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
1523d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
1524d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
1525d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
1526d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1527d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    private static void setEpicenter(Transition transition, View view) {
1528d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        final Rect epicenter = new Rect();
1529d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        view.getBoundsOnScreen(epicenter);
1530d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1531d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        transition.setEpicenterCallback(new Transition.EpicenterCallback() {
1532d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            @Override
1533d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            public Rect onGetEpicenter(Transition transition) {
1534d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                return epicenter;
1535d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
1536d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        });
1537d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
1538d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1539d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    private void setSharedElementEpicenter(Transition transition, final TransitionState state) {
1540d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        transition.setEpicenterCallback(new Transition.EpicenterCallback() {
1541d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            private Rect mEpicenter;
1542d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1543d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            @Override
1544d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            public Rect onGetEpicenter(Transition transition) {
1545c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                if (mEpicenter == null && state.enteringEpicenterView != null) {
1546d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                    mEpicenter = new Rect();
1547c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    state.enteringEpicenterView.getBoundsOnScreen(mEpicenter);
1548d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
1549d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                return mEpicenter;
1550d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
1551d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        });
1552d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
1553d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1554c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    public TransitionState popFromBackStack(boolean doStateMove, TransitionState state,
1555c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            SparseArray<Fragment> firstOutFragments, SparseArray<Fragment> lastInFragments) {
1556f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        if (FragmentManagerImpl.DEBUG) {
1557f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            Log.v(TAG, "popFromBackStack: " + this);
1558f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
15598c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn            PrintWriter pw = new FastPrintWriter(logw, false, 1024);
1560f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn            dump("  ", null, pw, null);
15618c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn            pw.flush();
1562f43a33c5ea5adb8d100ab0c3da965bac33155cb8Dianne Hackborn        }
1563b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn
1564d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        if (state == null) {
1565c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            if (firstOutFragments.size() != 0 || lastInFragments.size() != 0) {
1566c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                state = beginTransition(firstOutFragments, lastInFragments, true);
1567c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            }
1568c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        } else if (!doStateMove) {
1569d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            setNameOverrides(state, mSharedElementTargetNames, mSharedElementSourceNames);
1570d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
1571d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1572b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn        bumpBackStackNesting(-1);
1573c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
15745ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        Op op = mTail;
15755ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        while (op != null) {
15765ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            switch (op.cmd) {
15775ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                case OP_ADD: {
15785ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    Fragment f = op.fragment;
1579bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase                    f.mNextAnim = op.popExitAnim;
15805ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    mManager.removeFragment(f,
1581b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn                            FragmentManagerImpl.reverseTransit(mTransition),
15825ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                            mTransitionStyle);
1583d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
1584d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
1585b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                case OP_REPLACE: {
1586b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                    Fragment f = op.fragment;
1587ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                    if (f != null) {
1588ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                        f.mNextAnim = op.popExitAnim;
1589ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                        mManager.removeFragment(f,
1590ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                FragmentManagerImpl.reverseTransit(mTransition),
1591ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                                mTransitionStyle);
1592ee76efb74b5886f98cdfebfbefe9b69224e016fbDianne Hackborn                    }
1593b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                    if (op.removed != null) {
1594d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                        for (int i = 0; i < op.removed.size(); i++) {
1595b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                            Fragment old = op.removed.get(i);
1596bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase                            old.mNextAnim = op.popEnterAnim;
1597b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                            mManager.addFragment(old, false);
1598b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                        }
1599b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn                    }
1600d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
1601d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
16025ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                case OP_REMOVE: {
16035ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    Fragment f = op.fragment;
1604bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase                    f.mNextAnim = op.popEnterAnim;
16055ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    mManager.addFragment(f, false);
1606d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
1607d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
16085ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                case OP_HIDE: {
16095ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    Fragment f = op.fragment;
1610bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase                    f.mNextAnim = op.popEnterAnim;
16115ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    mManager.showFragment(f,
1612b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn                            FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
1613d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
1614d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
16155ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                case OP_SHOW: {
16165ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    Fragment f = op.fragment;
1617bc377841db05bd5197ffadb58ba52c54b2a85f16Chet Haase                    f.mNextAnim = op.popExitAnim;
16185ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    mManager.hideFragment(f,
1619b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn                            FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
1620d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
1621d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
162247c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                case OP_DETACH: {
162347c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                    Fragment f = op.fragment;
1624d04ad541def2bca8fc2d810514ee15ab97893d35Dianne Hackborn                    f.mNextAnim = op.popEnterAnim;
162547c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                    mManager.attachFragment(f,
162647c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                            FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
1627d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
1628d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
162947c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                case OP_ATTACH: {
163047c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                    Fragment f = op.fragment;
1631d04ad541def2bca8fc2d810514ee15ab97893d35Dianne Hackborn                    f.mNextAnim = op.popExitAnim;
163247c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                    mManager.detachFragment(f,
163347c4156567ce5abf8a6fca7fefe6ae9a20fb5117Dianne Hackborn                            FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
1634d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                }
1635d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                break;
16365ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                default: {
16375ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                    throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
16385ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn                }
16395ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            }
1640c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
16415ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn            op = op.prev;
16425ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        }
1643c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
16445f36c96f6d3623a826466db68cc1586f078ac307Dianne Hackborn        if (doStateMove) {
16455f36c96f6d3623a826466db68cc1586f078ac307Dianne Hackborn            mManager.moveToState(mManager.mCurState,
16465f36c96f6d3623a826466db68cc1586f078ac307Dianne Hackborn                    FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle, true);
1647ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            state = null;
1648b31e84bc4513e46bac4be8f8d0513f78e360fb11Dianne Hackborn        }
1649dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
1650dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (mIndex >= 0) {
1651dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            mManager.freeBackStackIndex(mIndex);
1652dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            mIndex = -1;
1653dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
1654d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        return state;
1655d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
1656d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1657c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private static void setNameOverride(ArrayMap<String, String> overrides,
1658c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            String source, String target) {
1659c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        if (source != null && target != null && !source.equals(target)) {
1660c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            for (int index = 0; index < overrides.size(); index++) {
1661c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                if (source.equals(overrides.valueAt(index))) {
1662c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    overrides.setValueAt(index, target);
1663c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                    return;
1664c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                }
1665d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
1666c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            overrides.put(source, target);
1667d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
1668d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
1669d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1670d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    private static void setNameOverrides(TransitionState state, ArrayList<String> sourceNames,
1671d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            ArrayList<String> targetNames) {
1672d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        if (sourceNames != null) {
1673d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            for (int i = 0; i < sourceNames.size(); i++) {
1674d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                String source = sourceNames.get(i);
1675d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount                String target = targetNames.get(i);
1676c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                setNameOverride(state.nameOverrides, source, target);
1677c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            }
1678c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1679c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
1680c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1681c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private void setBackNameOverrides(TransitionState state, ArrayMap<String, View> namedViews,
1682c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            boolean isEnd) {
1683c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        int count = mSharedElementTargetNames.size();
1684c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        for (int i = 0; i < count; i++) {
1685c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            String source = mSharedElementSourceNames.get(i);
1686c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            String originalTarget = mSharedElementTargetNames.get(i);
1687ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            View view = namedViews.get(originalTarget);
1688ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount            if (view != null) {
1689ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                String target = view.getTransitionName();
1690ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                if (isEnd) {
1691ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    setNameOverride(state.nameOverrides, source, target);
1692ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                } else {
1693ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                    setNameOverride(state.nameOverrides, target, source);
1694ecfd007c8fe29504de517f3243613a7f00cef4fcGeorge Mount                }
1695c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            }
1696c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        }
1697c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    }
1698c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount
1699c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount    private void setNameOverrides(TransitionState state, ArrayMap<String, View> namedViews,
1700c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            boolean isEnd) {
1701c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        int count = namedViews.size();
1702c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        for (int i = 0; i < count; i++) {
1703c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            String source = namedViews.keyAt(i);
1704c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            String target = namedViews.valueAt(i).getTransitionName();
1705c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            if (isEnd) {
1706c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                setNameOverride(state.nameOverrides, source, target);
1707c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount            } else {
1708c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount                setNameOverride(state.nameOverrides, target, source);
1709d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount            }
1710d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount        }
17115ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
1712c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
17135ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public String getName() {
17145ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return mName;
17155ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
1716c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
17175ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public int getTransition() {
17185ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return mTransition;
17195ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
1720c6669ca63299219d815464129dac051ab2404286Dianne Hackborn
17215ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    public int getTransitionStyle() {
17225ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn        return mTransitionStyle;
17235ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn    }
17242b6230e0de4bac2829ac27b19e95ba75c3da82b4Adam Powell
17252b6230e0de4bac2829ac27b19e95ba75c3da82b4Adam Powell    public boolean isEmpty() {
17262b6230e0de4bac2829ac27b19e95ba75c3da82b4Adam Powell        return mNumOp == 0;
17272b6230e0de4bac2829ac27b19e95ba75c3da82b4Adam Powell    }
1728d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount
1729d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    public class TransitionState {
1730c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        public ArrayMap<String, String> nameOverrides = new ArrayMap<String, String>();
1731c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        public View enteringEpicenterView;
1732c03da0e7a9ef721709d51cf8a2d539a5bd8a320eGeorge Mount        public View nonExistentView;
1733d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount    }
17345ae74d6e89a30e79ea85c487b32223ef55314985Dianne Hackborn}
1735