1cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/*
2cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Copyright (C) 2011 The Android Open Source Project
3cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
4cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * you may not use this file except in compliance with the License.
6cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * You may obtain a copy of the License at
7cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
8cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn *
10cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
11cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * See the License for the specific language governing permissions and
14cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * limitations under the License.
15cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */
16cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
17cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornpackage android.support.v4.app;
18cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
199f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mountimport android.graphics.Rect;
204500be62dea3895a98336122a2944cc4ab024bc5George Mountimport android.os.Build;
21cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Parcel;
22cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.os.Parcelable;
233a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackbornimport android.support.v4.util.LogWriter;
244500be62dea3895a98336122a2944cc4ab024bc5George Mountimport android.support.v4.util.Pair;
259f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mountimport android.support.v4.util.ArrayMap;
26cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.text.TextUtils;
27cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport android.util.Log;
289f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mountimport android.util.SparseArray;
294500be62dea3895a98336122a2944cc4ab024bc5George Mountimport android.view.View;
304500be62dea3895a98336122a2944cc4ab024bc5George Mountimport android.view.ViewGroup;
310f5ae57910484f1d873fdad90966b6244a633bd4George Mountimport android.view.ViewTreeObserver;
32cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
33cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.FileDescriptor;
34cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.io.PrintWriter;
35cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornimport java.util.ArrayList;
369f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mountimport java.util.Collection;
37cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
38cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornfinal class BackStackState implements Parcelable {
39cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    final int[] mOps;
40cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    final int mTransition;
41cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    final int mTransitionStyle;
42cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    final String mName;
43cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    final int mIndex;
44cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    final int mBreadCrumbTitleRes;
45cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    final CharSequence mBreadCrumbTitleText;
46cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    final int mBreadCrumbShortTitleRes;
47cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    final CharSequence mBreadCrumbShortTitleText;
484500be62dea3895a98336122a2944cc4ab024bc5George Mount    final ArrayList<String> mSharedElementSourceNames;
494500be62dea3895a98336122a2944cc4ab024bc5George Mount    final ArrayList<String> mSharedElementTargetNames;
50cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
51cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
52cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int numRemoved = 0;
53cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        BackStackRecord.Op op = bse.mHead;
54cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        while (op != null) {
55cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (op.removed != null) numRemoved += op.removed.size();
56cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            op = op.next;
57cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
58df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn        mOps = new int[bse.mNumOp*7 + numRemoved];
59cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
60cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (!bse.mAddToBackStack) {
61cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            throw new IllegalStateException("Not on back stack");
62cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
63cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
64cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op = bse.mHead;
65cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int pos = 0;
66cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        while (op != null) {
67cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mOps[pos++] = op.cmd;
685506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn            mOps[pos++] = op.fragment != null ? op.fragment.mIndex : -1;
69cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mOps[pos++] = op.enterAnim;
70cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mOps[pos++] = op.exitAnim;
71df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn            mOps[pos++] = op.popEnterAnim;
72df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn            mOps[pos++] = op.popExitAnim;
73cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (op.removed != null) {
74cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                final int N = op.removed.size();
75cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                mOps[pos++] = N;
76cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                for (int i=0; i<N; i++) {
77cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    mOps[pos++] = op.removed.get(i).mIndex;
78cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                }
79cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            } else {
80cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                mOps[pos++] = 0;
81cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
82cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            op = op.next;
83cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
84cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mTransition = bse.mTransition;
85cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mTransitionStyle = bse.mTransitionStyle;
86cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mName = bse.mName;
87cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mIndex = bse.mIndex;
88cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbTitleRes = bse.mBreadCrumbTitleRes;
89cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbTitleText = bse.mBreadCrumbTitleText;
90cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbShortTitleRes = bse.mBreadCrumbShortTitleRes;
91cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbShortTitleText = bse.mBreadCrumbShortTitleText;
924500be62dea3895a98336122a2944cc4ab024bc5George Mount        mSharedElementSourceNames = bse.mSharedElementSourceNames;
934500be62dea3895a98336122a2944cc4ab024bc5George Mount        mSharedElementTargetNames = bse.mSharedElementTargetNames;
94cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
95cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
96cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public BackStackState(Parcel in) {
97cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mOps = in.createIntArray();
98cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mTransition = in.readInt();
99cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mTransitionStyle = in.readInt();
100cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mName = in.readString();
101cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mIndex = in.readInt();
102cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbTitleRes = in.readInt();
103cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
104cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbShortTitleRes = in.readInt();
105cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbShortTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
1064500be62dea3895a98336122a2944cc4ab024bc5George Mount        mSharedElementSourceNames = in.createStringArrayList();
1074500be62dea3895a98336122a2944cc4ab024bc5George Mount        mSharedElementTargetNames = in.createStringArrayList();
108cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
109cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
110cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public BackStackRecord instantiate(FragmentManagerImpl fm) {
111cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        BackStackRecord bse = new BackStackRecord(fm);
112cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int pos = 0;
1133a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        int num = 0;
114cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        while (pos < mOps.length) {
115cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            BackStackRecord.Op op = new BackStackRecord.Op();
116cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            op.cmd = mOps[pos++];
117cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
1183a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    "Instantiate " + bse + " op #" + num + " base fragment #" + mOps[pos]);
1195506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn            int findex = mOps[pos++];
1205506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn            if (findex >= 0) {
1215506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                Fragment f = fm.mActive.get(findex);
1225506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                op.fragment = f;
1235506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn            } else {
1245506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                op.fragment = null;
1255506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn            }
126cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            op.enterAnim = mOps[pos++];
127cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            op.exitAnim = mOps[pos++];
128df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn            op.popEnterAnim = mOps[pos++];
129df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn            op.popExitAnim = mOps[pos++];
130cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            final int N = mOps[pos++];
131cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (N > 0) {
132cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                op.removed = new ArrayList<Fragment>(N);
133cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                for (int i=0; i<N; i++) {
134cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG,
1353a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                            "Instantiate " + bse + " set remove fragment #" + mOps[pos]);
136cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment r = fm.mActive.get(mOps[pos++]);
137cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    op.removed.add(r);
138cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                }
139cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
140cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            bse.addOp(op);
1413a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            num++;
142cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
143cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bse.mTransition = mTransition;
144cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bse.mTransitionStyle = mTransitionStyle;
145cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bse.mName = mName;
146cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bse.mIndex = mIndex;
147cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bse.mAddToBackStack = true;
148cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bse.mBreadCrumbTitleRes = mBreadCrumbTitleRes;
149cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bse.mBreadCrumbTitleText = mBreadCrumbTitleText;
150cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bse.mBreadCrumbShortTitleRes = mBreadCrumbShortTitleRes;
151cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bse.mBreadCrumbShortTitleText = mBreadCrumbShortTitleText;
1524500be62dea3895a98336122a2944cc4ab024bc5George Mount        bse.mSharedElementSourceNames = mSharedElementSourceNames;
1534500be62dea3895a98336122a2944cc4ab024bc5George Mount        bse.mSharedElementTargetNames = mSharedElementTargetNames;
154cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bse.bumpBackStackNesting(1);
155cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return bse;
156cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
157cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
158cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public int describeContents() {
159cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return 0;
160cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
161cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
162cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public void writeToParcel(Parcel dest, int flags) {
163cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        dest.writeIntArray(mOps);
164cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        dest.writeInt(mTransition);
165cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        dest.writeInt(mTransitionStyle);
166cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        dest.writeString(mName);
167cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        dest.writeInt(mIndex);
168cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        dest.writeInt(mBreadCrumbTitleRes);
169cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        TextUtils.writeToParcel(mBreadCrumbTitleText, dest, 0);
170cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        dest.writeInt(mBreadCrumbShortTitleRes);
171cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        TextUtils.writeToParcel(mBreadCrumbShortTitleText, dest, 0);
1724500be62dea3895a98336122a2944cc4ab024bc5George Mount        dest.writeStringList(mSharedElementSourceNames);
1734500be62dea3895a98336122a2944cc4ab024bc5George Mount        dest.writeStringList(mSharedElementTargetNames);
174cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
175cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
176cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public static final Parcelable.Creator<BackStackState> CREATOR
177cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            = new Parcelable.Creator<BackStackState>() {
178cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        public BackStackState createFromParcel(Parcel in) {
179cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return new BackStackState(in);
180cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
181cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
182cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        public BackStackState[] newArray(int size) {
183cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return new BackStackState[size];
184cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
185cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    };
186cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn}
187cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
188cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn/**
189cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn * @hide Entry of an operation on the fragment back stack.
190cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn */
191cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackbornfinal class BackStackRecord extends FragmentTransaction implements
192cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        FragmentManager.BackStackEntry, Runnable {
1933a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn    static final String TAG = FragmentManagerImpl.TAG;
194cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
195cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    final FragmentManagerImpl mManager;
196cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
197cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    static final int OP_NULL = 0;
198cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    static final int OP_ADD = 1;
199cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    static final int OP_REPLACE = 2;
200cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    static final int OP_REMOVE = 3;
201cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    static final int OP_HIDE = 4;
202cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    static final int OP_SHOW = 5;
203eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn    static final int OP_DETACH = 6;
204eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn    static final int OP_ATTACH = 7;
205cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
206cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    static final class Op {
207cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Op next;
208cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Op prev;
209cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int cmd;
210cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Fragment fragment;
211cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int enterAnim;
212cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        int exitAnim;
213df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn        int popEnterAnim;
214df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn        int popExitAnim;
215cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        ArrayList<Fragment> removed;
216cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
217cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
218cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    Op mHead;
219cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    Op mTail;
220cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    int mNumOp;
221cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    int mEnterAnim;
222cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    int mExitAnim;
223df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn    int mPopEnterAnim;
224df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn    int mPopExitAnim;
225cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    int mTransition;
226cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    int mTransitionStyle;
227cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    boolean mAddToBackStack;
228cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    boolean mAllowAddToBackStack = true;
229cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    String mName;
230cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    boolean mCommitted;
2313a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn    int mIndex = -1;
232cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
233cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    int mBreadCrumbTitleRes;
234cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    CharSequence mBreadCrumbTitleText;
235cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    int mBreadCrumbShortTitleRes;
236cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    CharSequence mBreadCrumbShortTitleText;
237cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
2384500be62dea3895a98336122a2944cc4ab024bc5George Mount    ArrayList<String> mSharedElementSourceNames;
2394500be62dea3895a98336122a2944cc4ab024bc5George Mount    ArrayList<String> mSharedElementTargetNames;
2404500be62dea3895a98336122a2944cc4ab024bc5George Mount
2413a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn    @Override
2423a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn    public String toString() {
2433a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        StringBuilder sb = new StringBuilder(128);
2443a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        sb.append("BackStackEntry{");
2453a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        sb.append(Integer.toHexString(System.identityHashCode(this)));
2463a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        if (mIndex >= 0) {
2473a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            sb.append(" #");
2483a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            sb.append(mIndex);
249df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn        }
2503a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        if (mName != null) {
2513a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            sb.append(" ");
2523a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            sb.append(mName);
253cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
2543a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        sb.append("}");
2553a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        return sb.toString();
2563a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn    }
2573a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn
2583a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
2593a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        dump(prefix, writer, true);
2603a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn    }
2613a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn
2623a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn    public void dump(String prefix, PrintWriter writer, boolean full) {
2633a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        if (full) {
2643a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            writer.print(prefix); writer.print("mName="); writer.print(mName);
2653a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    writer.print(" mIndex="); writer.print(mIndex);
2663a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    writer.print(" mCommitted="); writer.println(mCommitted);
2673a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            if (mTransition != FragmentTransaction.TRANSIT_NONE) {
2683a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                writer.print(prefix); writer.print("mTransition=#");
2693a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(Integer.toHexString(mTransition));
2703a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(" mTransitionStyle=#");
2713a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.println(Integer.toHexString(mTransitionStyle));
2723a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            }
2733a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            if (mEnterAnim != 0 || mExitAnim !=0) {
2743a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                writer.print(prefix); writer.print("mEnterAnim=#");
2753a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(Integer.toHexString(mEnterAnim));
2763a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(" mExitAnim=#");
2773a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.println(Integer.toHexString(mExitAnim));
2783a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            }
2793a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            if (mPopEnterAnim != 0 || mPopExitAnim !=0) {
2803a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                writer.print(prefix); writer.print("mPopEnterAnim=#");
2813a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(Integer.toHexString(mPopEnterAnim));
2823a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(" mPopExitAnim=#");
2833a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.println(Integer.toHexString(mPopExitAnim));
2843a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            }
2853a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
2863a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                writer.print(prefix); writer.print("mBreadCrumbTitleRes=#");
2873a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(Integer.toHexString(mBreadCrumbTitleRes));
2883a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(" mBreadCrumbTitleText=");
2893a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.println(mBreadCrumbTitleText);
2903a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            }
2913a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
2923a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#");
2933a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
2943a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(" mBreadCrumbShortTitleText=");
2953a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.println(mBreadCrumbShortTitleText);
2963a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            }
297cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
298cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
299cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mHead != null) {
300cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            writer.print(prefix); writer.println("Operations:");
301cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            String innerPrefix = prefix + "    ";
302cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            Op op = mHead;
303cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            int num = 0;
304cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            while (op != null) {
3053a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                String cmdStr;
3063a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                switch (op.cmd) {
3073a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    case OP_NULL: cmdStr="NULL"; break;
3083a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    case OP_ADD: cmdStr="ADD"; break;
3093a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    case OP_REPLACE: cmdStr="REPLACE"; break;
3103a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    case OP_REMOVE: cmdStr="REMOVE"; break;
3113a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    case OP_HIDE: cmdStr="HIDE"; break;
3123a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    case OP_SHOW: cmdStr="SHOW"; break;
3133a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    case OP_DETACH: cmdStr="DETACH"; break;
3143a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    case OP_ATTACH: cmdStr="ATTACH"; break;
3153a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    default: cmdStr="cmd=" + op.cmd; break;
316df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn                }
3173a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                writer.print(prefix); writer.print("  Op #"); writer.print(num);
3183a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(": "); writer.print(cmdStr);
3193a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(" "); writer.println(op.fragment);
3203a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                if (full) {
3213a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    if (op.enterAnim != 0 || op.exitAnim != 0) {
3223a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(prefix); writer.print("enterAnim=#");
3233a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                                writer.print(Integer.toHexString(op.enterAnim));
3243a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                                writer.print(" exitAnim=#");
3253a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                                writer.println(Integer.toHexString(op.exitAnim));
3263a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    }
3273a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    if (op.popEnterAnim != 0 || op.popExitAnim != 0) {
3283a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                        writer.print(prefix); writer.print("popEnterAnim=#");
3293a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                                writer.print(Integer.toHexString(op.popEnterAnim));
3303a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                                writer.print(" popExitAnim=#");
3313a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                                writer.println(Integer.toHexString(op.popExitAnim));
3323a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                    }
333cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                }
334cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                if (op.removed != null && op.removed.size() > 0) {
335cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    for (int i=0; i<op.removed.size(); i++) {
336cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        writer.print(innerPrefix);
337cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        if (op.removed.size() == 1) {
338cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                            writer.print("Removed: ");
339cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        } else {
3403a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                            if (i == 0) {
3413a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                                writer.println("Removed:");
3423a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                            }
3433a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                            writer.print(innerPrefix); writer.print("  #"); writer.print(i);
344cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                                    writer.print(": ");
345cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        }
346cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        writer.println(op.removed.get(i));
347cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    }
348cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                }
349cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                op = op.next;
3503a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn                num++;
351cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
352cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
353cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
354cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
355cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public BackStackRecord(FragmentManagerImpl manager) {
356cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mManager = manager;
357cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
358cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
359cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public int getId() {
360cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mIndex;
361cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
362cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
363cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public int getBreadCrumbTitleRes() {
364cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mBreadCrumbTitleRes;
365cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
366cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
367cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public int getBreadCrumbShortTitleRes() {
368cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mBreadCrumbShortTitleRes;
369cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
370cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
371cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public CharSequence getBreadCrumbTitle() {
372cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mBreadCrumbTitleRes != 0) {
373cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return mManager.mActivity.getText(mBreadCrumbTitleRes);
374cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
375cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mBreadCrumbTitleText;
376cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
377cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
378cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public CharSequence getBreadCrumbShortTitle() {
379cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mBreadCrumbShortTitleRes != 0) {
380cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return mManager.mActivity.getText(mBreadCrumbShortTitleRes);
381cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
382cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mBreadCrumbShortTitleText;
383cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
384cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
385cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    void addOp(Op op) {
386cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mHead == null) {
387cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mHead = mTail = op;
388cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
389cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            op.prev = mTail;
390cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mTail.next = op;
391cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mTail = op;
392cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
393cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op.enterAnim = mEnterAnim;
394cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op.exitAnim = mExitAnim;
395df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn        op.popEnterAnim = mPopEnterAnim;
396df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn        op.popExitAnim = mPopExitAnim;
397cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mNumOp++;
398cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
399cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
400cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction add(Fragment fragment, String tag) {
401cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        doAddOp(0, fragment, tag, OP_ADD);
402cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
403cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
404cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
405cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction add(int containerViewId, Fragment fragment) {
406cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        doAddOp(containerViewId, fragment, null, OP_ADD);
407cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
408cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
409cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
410cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
411cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        doAddOp(containerViewId, fragment, tag, OP_ADD);
412cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
413cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
414cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
415cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
416cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        fragment.mFragmentManager = mManager;
417cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
418cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (tag != null) {
419cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
420cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                throw new IllegalStateException("Can't change tag of fragment "
421cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        + fragment + ": was " + fragment.mTag
422cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        + " now " + tag);
423cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
424cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            fragment.mTag = tag;
425cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
426cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
427cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (containerViewId != 0) {
428cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
429cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                throw new IllegalStateException("Can't change container ID of fragment "
430cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        + fragment + ": was " + fragment.mFragmentId
431cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        + " now " + containerViewId);
432cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
433cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            fragment.mContainerId = fragment.mFragmentId = containerViewId;
434cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
435cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
436cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Op op = new Op();
437cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op.cmd = opcmd;
438cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op.fragment = fragment;
439cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        addOp(op);
440cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
441cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
442cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction replace(int containerViewId, Fragment fragment) {
443cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return replace(containerViewId, fragment, null);
444cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
445cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
446cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
447cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (containerViewId == 0) {
448cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            throw new IllegalArgumentException("Must use non-zero containerViewId");
449cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
450cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
451cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        doAddOp(containerViewId, fragment, tag, OP_REPLACE);
452cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
453cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
454cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
455cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction remove(Fragment fragment) {
456cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Op op = new Op();
457cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op.cmd = OP_REMOVE;
458cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op.fragment = fragment;
459cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        addOp(op);
460cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
461cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
462cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
463cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
464cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction hide(Fragment fragment) {
465cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Op op = new Op();
466cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op.cmd = OP_HIDE;
467cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op.fragment = fragment;
468cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        addOp(op);
469cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
470cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
471cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
472cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
473cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction show(Fragment fragment) {
474cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Op op = new Op();
475cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op.cmd = OP_SHOW;
476cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        op.fragment = fragment;
477cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        addOp(op);
478cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
479cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
480cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
481cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
482eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn    public FragmentTransaction detach(Fragment fragment) {
483eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn        Op op = new Op();
484eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn        op.cmd = OP_DETACH;
485eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn        op.fragment = fragment;
486eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn        addOp(op);
487eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn
488eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn        return this;
489eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn    }
490eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn
491eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn    public FragmentTransaction attach(Fragment fragment) {
492eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn        Op op = new Op();
493eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn        op.cmd = OP_ATTACH;
494eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn        op.fragment = fragment;
495eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn        addOp(op);
496eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn
497eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn        return this;
498eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn    }
499eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn
500cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction setCustomAnimations(int enter, int exit) {
501df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn        return setCustomAnimations(enter, exit, 0, 0);
502df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn    }
503df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn
504df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn    public FragmentTransaction setCustomAnimations(int enter, int exit,
505df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn            int popEnter, int popExit) {
506cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mEnterAnim = enter;
507cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mExitAnim = exit;
508df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn        mPopEnterAnim = popEnter;
509df6f1393f73a488ba2661b28d3d88a5ac19c4ea2Dianne Hackborn        mPopExitAnim = popExit;
510cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
511cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
512cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
513cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction setTransition(int transition) {
514cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mTransition = transition;
515cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
516cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
517cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
5184500be62dea3895a98336122a2944cc4ab024bc5George Mount    @Override
519128bb5c66d0b34c5a658c682deb3a0b9199b20c4George Mount    public FragmentTransaction addSharedElement(View sharedElement, String name) {
520a52784195525cdb1f2bb4d8dde1b8b314f480957Chet Haase        if (Build.VERSION.SDK_INT >= 21) {
5214500be62dea3895a98336122a2944cc4ab024bc5George Mount            String transitionName = FragmentTransitionCompat21.getTransitionName(sharedElement);
5224500be62dea3895a98336122a2944cc4ab024bc5George Mount            if (transitionName == null) {
5234500be62dea3895a98336122a2944cc4ab024bc5George Mount                throw new IllegalArgumentException("Unique transitionNames are required for all" +
5244500be62dea3895a98336122a2944cc4ab024bc5George Mount                        " sharedElements");
5254500be62dea3895a98336122a2944cc4ab024bc5George Mount            }
526128bb5c66d0b34c5a658c682deb3a0b9199b20c4George Mount            if (mSharedElementSourceNames == null) {
527128bb5c66d0b34c5a658c682deb3a0b9199b20c4George Mount                mSharedElementSourceNames = new ArrayList<String>();
528128bb5c66d0b34c5a658c682deb3a0b9199b20c4George Mount                mSharedElementTargetNames = new ArrayList<String>();
529128bb5c66d0b34c5a658c682deb3a0b9199b20c4George Mount            }
5304500be62dea3895a98336122a2944cc4ab024bc5George Mount
531128bb5c66d0b34c5a658c682deb3a0b9199b20c4George Mount            mSharedElementSourceNames.add(transitionName);
5324500be62dea3895a98336122a2944cc4ab024bc5George Mount            mSharedElementTargetNames.add(name);
5334500be62dea3895a98336122a2944cc4ab024bc5George Mount        }
5344500be62dea3895a98336122a2944cc4ab024bc5George Mount        return this;
5354500be62dea3895a98336122a2944cc4ab024bc5George Mount    }
5364500be62dea3895a98336122a2944cc4ab024bc5George Mount
537cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction setTransitionStyle(int styleRes) {
538cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mTransitionStyle = styleRes;
539cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
540cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
541cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
542cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction addToBackStack(String name) {
543cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (!mAllowAddToBackStack) {
544cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            throw new IllegalStateException(
545cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    "This FragmentTransaction is not allowed to be added to the back stack.");
546cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
547cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mAddToBackStack = true;
548cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mName = name;
549cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
550cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
551cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
552cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public boolean isAddToBackStackAllowed() {
553cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mAllowAddToBackStack;
554cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
555cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
556cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction disallowAddToBackStack() {
557cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mAddToBackStack) {
558cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            throw new IllegalStateException(
559cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    "This transaction is already being added to the back stack");
560cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
561cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mAllowAddToBackStack = false;
562cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
563cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
564cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
565cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction setBreadCrumbTitle(int res) {
566cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbTitleRes = res;
567cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbTitleText = null;
568cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
569cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
570cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
571cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction setBreadCrumbTitle(CharSequence text) {
572cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbTitleRes = 0;
573cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbTitleText = text;
574cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
575cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
576cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
577cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction setBreadCrumbShortTitle(int res) {
578cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbShortTitleRes = res;
579cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbShortTitleText = null;
580cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
581cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
582cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
583cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public FragmentTransaction setBreadCrumbShortTitle(CharSequence text) {
584cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbShortTitleRes = 0;
585cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mBreadCrumbShortTitleText = text;
586cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return this;
587cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
588cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
589cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    void bumpBackStackNesting(int amt) {
590cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (!mAddToBackStack) {
591cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            return;
592cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
593cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting in " + this
594cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                + " by " + amt);
595cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Op op = mHead;
596cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        while (op != null) {
5975506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn            if (op.fragment != null) {
5985506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                op.fragment.mBackStackNesting += amt;
5995506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
6005506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                        + op.fragment + " to " + op.fragment.mBackStackNesting);
6015506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn            }
602cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (op.removed != null) {
603cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                for (int i=op.removed.size()-1; i>=0; i--) {
604cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment r = op.removed.get(i);
605cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    r.mBackStackNesting += amt;
606cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
607cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                            + r + " to " + r.mBackStackNesting);
608cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                }
609cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
610cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            op = op.next;
611cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
612cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
613cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
614cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public int commit() {
615cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return commitInternal(false);
616cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
617cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
618cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public int commitAllowingStateLoss() {
619cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return commitInternal(true);
620cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
621cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
622cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    int commitInternal(boolean allowStateLoss) {
623cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mCommitted) throw new IllegalStateException("commit already called");
6243a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        if (FragmentManagerImpl.DEBUG) {
6253a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            Log.v(TAG, "Commit: " + this);
6263a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            LogWriter logw = new LogWriter(TAG);
6273a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            PrintWriter pw = new PrintWriter(logw);
6283a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            dump("  ", null, pw, null);
6293a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        }
630cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mCommitted = true;
631cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mAddToBackStack) {
632cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mIndex = mManager.allocBackStackIndex(this);
633cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        } else {
634cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mIndex = -1;
635cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
636cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        mManager.enqueueAction(this, allowStateLoss);
637cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mIndex;
638cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
639cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
640cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public void run() {
641cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Run: " + this);
642cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
643cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mAddToBackStack) {
644cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            if (mIndex < 0) {
645cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                throw new IllegalStateException("addToBackStack() called after commit()");
646cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
647cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
648cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
649cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bumpBackStackNesting(1);
650cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
6519f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        TransitionState state = null;
6529f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        SparseArray<Fragment> firstOutFragments = null;
6539f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        SparseArray<Fragment> lastInFragments = null;
654a52784195525cdb1f2bb4d8dde1b8b314f480957Chet Haase        if (Build.VERSION.SDK_INT >= 21) {
6559f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            firstOutFragments = new SparseArray<Fragment>();
6569f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            lastInFragments = new SparseArray<Fragment>();
6579f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
6589f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            calculateFragments(firstOutFragments, lastInFragments);
6599f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
6600f5ae57910484f1d873fdad90966b6244a633bd4George Mount            state = beginTransition(firstOutFragments, lastInFragments, false);
6619f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
6624500be62dea3895a98336122a2944cc4ab024bc5George Mount
6634500be62dea3895a98336122a2944cc4ab024bc5George Mount        int transitionStyle = state != null ? 0 : mTransitionStyle;
6644500be62dea3895a98336122a2944cc4ab024bc5George Mount        int transition = state != null ? 0 : mTransition;
665cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Op op = mHead;
666cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        while (op != null) {
6674500be62dea3895a98336122a2944cc4ab024bc5George Mount            int enterAnim = state != null ? 0 : op.enterAnim;
6684500be62dea3895a98336122a2944cc4ab024bc5George Mount            int exitAnim = state != null ? 0 : op.exitAnim;
669cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            switch (op.cmd) {
670cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                case OP_ADD: {
671cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment f = op.fragment;
6724500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = enterAnim;
673cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    mManager.addFragment(f, false);
674cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                } break;
675cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                case OP_REPLACE: {
676cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment f = op.fragment;
677cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    if (mManager.mAdded != null) {
678cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        for (int i=0; i<mManager.mAdded.size(); i++) {
679cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                            Fragment old = mManager.mAdded.get(i);
680cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                            if (FragmentManagerImpl.DEBUG) Log.v(TAG,
681cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                                    "OP_REPLACE: adding=" + f + " old=" + old);
6825506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                            if (f == null || old.mContainerId == f.mContainerId) {
6835506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                if (old == f) {
6845506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                    op.fragment = f = null;
6855506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                } else {
6865506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                    if (op.removed == null) {
6875506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                        op.removed = new ArrayList<Fragment>();
6885506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                    }
6895506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                    op.removed.add(old);
6904500be62dea3895a98336122a2944cc4ab024bc5George Mount                                    old.mNextAnim = exitAnim;
6915506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                    if (mAddToBackStack) {
6925506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                        old.mBackStackNesting += 1;
6935506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                        if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "
6945506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                                + old + " to " + old.mBackStackNesting);
6955506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                                    }
6964500be62dea3895a98336122a2944cc4ab024bc5George Mount                                    mManager.removeFragment(old, transition, transitionStyle);
697cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                                }
698cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                            }
699cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        }
700cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    }
7015506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                    if (f != null) {
7024500be62dea3895a98336122a2944cc4ab024bc5George Mount                        f.mNextAnim = enterAnim;
7035506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                        mManager.addFragment(f, false);
7045506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                    }
705cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                } break;
706cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                case OP_REMOVE: {
707cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment f = op.fragment;
7084500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = exitAnim;
7094500be62dea3895a98336122a2944cc4ab024bc5George Mount                    mManager.removeFragment(f, transition, transitionStyle);
710cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                } break;
711cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                case OP_HIDE: {
712cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment f = op.fragment;
7134500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = exitAnim;
7144500be62dea3895a98336122a2944cc4ab024bc5George Mount                    mManager.hideFragment(f, transition, transitionStyle);
715cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                } break;
716cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                case OP_SHOW: {
717cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment f = op.fragment;
7184500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = enterAnim;
7194500be62dea3895a98336122a2944cc4ab024bc5George Mount                    mManager.showFragment(f, transition, transitionStyle);
720cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                } break;
721eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                case OP_DETACH: {
722eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                    Fragment f = op.fragment;
7234500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = exitAnim;
7244500be62dea3895a98336122a2944cc4ab024bc5George Mount                    mManager.detachFragment(f, transition, transitionStyle);
725eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                } break;
726eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                case OP_ATTACH: {
727eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                    Fragment f = op.fragment;
7284500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = enterAnim;
7294500be62dea3895a98336122a2944cc4ab024bc5George Mount                    mManager.attachFragment(f, transition, transitionStyle);
730eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                } break;
731cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                default: {
732cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
733cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                }
734cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
735cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
736cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            op = op.next;
737cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
738cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
7394500be62dea3895a98336122a2944cc4ab024bc5George Mount        mManager.moveToState(mManager.mCurState, transition, transitionStyle, true);
740cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
741cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mAddToBackStack) {
742cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mManager.addBackStackState(this);
743cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
744cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
745cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
7469f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private static void setFirstOut(SparseArray<Fragment> fragments, Fragment fragment) {
7479f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (fragment != null) {
7489f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            int containerId = fragment.mContainerId;
7499f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            if (containerId != 0 && !fragment.isHidden() && fragment.isAdded() &&
7509f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    fragment.getView() != null && fragments.get(containerId) == null) {
7519f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                fragments.put(containerId, fragment);
7524500be62dea3895a98336122a2944cc4ab024bc5George Mount            }
7539f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
7549f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
7559f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
7569f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private void setLastIn(SparseArray<Fragment> fragments, Fragment fragment) {
7579f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (fragment != null) {
7589f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            int containerId = fragment.mContainerId;
7599f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            if (containerId != 0) {
7609f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                fragments.put(containerId, fragment);
7619f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
7629f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
7639f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
7649f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
7659f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    /**
7669f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * Finds the first removed fragment and last added fragments when going forward.
7679f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * If none of the fragments have transitions, then both lists will be empty.
7689f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *
7699f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param firstOutFragments The list of first fragments to be removed, keyed on the
7709f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *                          container ID. This list will be modified by the method.
7719f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param lastInFragments The list of last fragments to be added, keyed on the
7729f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *                        container ID. This list will be modified by the method.
7739f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     */
7749f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private void calculateFragments(SparseArray<Fragment> firstOutFragments,
7759f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            SparseArray<Fragment> lastInFragments) {
7767516316ffdf6fbf7b248c615404831191daa66a4George Mount        if (!mManager.mContainer.hasView()) {
7777516316ffdf6fbf7b248c615404831191daa66a4George Mount            return; // nothing to see, so no transitions
7787516316ffdf6fbf7b248c615404831191daa66a4George Mount        }
7799f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        Op op = mHead;
7809f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        while (op != null) {
7819f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            switch (op.cmd) {
7829f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_ADD:
7839f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setLastIn(lastInFragments, op.fragment);
7849f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
7859f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_REPLACE: {
7869f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    Fragment f = op.fragment;
7879f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    if (mManager.mAdded != null) {
7889f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                        for (int i = 0; i < mManager.mAdded.size(); i++) {
7899f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                            Fragment old = mManager.mAdded.get(i);
7909f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                            if (f == null || old.mContainerId == f.mContainerId) {
7919f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                                if (old == f) {
7929f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                                    f = null;
7939f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                                } else {
7949f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                                    setFirstOut(firstOutFragments, old);
7959f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                                }
7969f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                            }
7974500be62dea3895a98336122a2944cc4ab024bc5George Mount                        }
7984500be62dea3895a98336122a2944cc4ab024bc5George Mount                    }
7999f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setLastIn(lastInFragments, f);
8009f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8014500be62dea3895a98336122a2944cc4ab024bc5George Mount                }
8029f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_REMOVE:
8039f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
8049f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8059f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_HIDE:
8069f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
8079f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8089f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_SHOW:
8099f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setLastIn(lastInFragments, op.fragment);
8109f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8119f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_DETACH:
8129f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
8139f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8149f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_ATTACH:
8159f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setLastIn(lastInFragments, op.fragment);
8169f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8174500be62dea3895a98336122a2944cc4ab024bc5George Mount            }
8189f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
8199f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            op = op.next;
8209f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
8214500be62dea3895a98336122a2944cc4ab024bc5George Mount    }
8224500be62dea3895a98336122a2944cc4ab024bc5George Mount
8239f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    /**
8249f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * Finds the first removed fragment and last added fragments when popping the back stack.
8259f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * If none of the fragments have transitions, then both lists will be empty.
8269f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *
8279f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param firstOutFragments The list of first fragments to be removed, keyed on the
8289f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *                          container ID. This list will be modified by the method.
8299f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param lastInFragments The list of last fragments to be added, keyed on the
8309f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *                        container ID. This list will be modified by the method.
8319f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     */
8329f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    public void calculateBackFragments(SparseArray<Fragment> firstOutFragments,
8339f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            SparseArray<Fragment> lastInFragments) {
8347516316ffdf6fbf7b248c615404831191daa66a4George Mount        if (!mManager.mContainer.hasView()) {
8357516316ffdf6fbf7b248c615404831191daa66a4George Mount            return; // nothing to see, so no transitions
8367516316ffdf6fbf7b248c615404831191daa66a4George Mount        }
8379f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        Op op = mHead;
8389f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        while (op != null) {
8399f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            switch (op.cmd) {
8409f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_ADD:
8419f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
8429f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8439f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_REPLACE:
8449f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    if (op.removed != null) {
8459f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                        for (int i = op.removed.size() - 1; i >= 0; i--) {
8469f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                            setLastIn(lastInFragments, op.removed.get(i));
8474500be62dea3895a98336122a2944cc4ab024bc5George Mount                        }
8484500be62dea3895a98336122a2944cc4ab024bc5George Mount                    }
8499f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
8509f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8519f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_REMOVE:
8529f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setLastIn(lastInFragments, op.fragment);
8539f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8549f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_HIDE:
8559f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setLastIn(lastInFragments, op.fragment);
8569f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8579f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_SHOW:
8589f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
8599f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8609f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_DETACH:
8619f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setLastIn(lastInFragments, op.fragment);
8629f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8639f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                case OP_ATTACH:
8649f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    setFirstOut(firstOutFragments, op.fragment);
8659f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    break;
8669f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
8679f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
8689f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            op = op.next;
8699f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
8704500be62dea3895a98336122a2944cc4ab024bc5George Mount    }
8714500be62dea3895a98336122a2944cc4ab024bc5George Mount
8729f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    public TransitionState popFromBackStack(boolean doStateMove, TransitionState state,
8739f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            SparseArray<Fragment> firstOutFragments, SparseArray<Fragment> lastInFragments) {
8743a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        if (FragmentManagerImpl.DEBUG) {
8753a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            Log.v(TAG, "popFromBackStack: " + this);
8763a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            LogWriter logw = new LogWriter(TAG);
8773a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            PrintWriter pw = new PrintWriter(logw);
8783a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn            dump("  ", null, pw, null);
8793a7571011a8f2c2e2685c4e3e7a6fa46673ee7eaDianne Hackborn        }
880cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
8814500be62dea3895a98336122a2944cc4ab024bc5George Mount        if (state == null) {
8829f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            if (firstOutFragments.size() != 0 || lastInFragments.size() != 0) {
8839f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                state = beginTransition(firstOutFragments, lastInFragments, true);
8849f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
8859f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        } else if (!doStateMove) {
8869f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            setNameOverrides(state, mSharedElementTargetNames, mSharedElementSourceNames);
8874500be62dea3895a98336122a2944cc4ab024bc5George Mount        }
8884500be62dea3895a98336122a2944cc4ab024bc5George Mount
889cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        bumpBackStackNesting(-1);
890cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
8914500be62dea3895a98336122a2944cc4ab024bc5George Mount        int transitionStyle = state != null ? 0 : mTransitionStyle;
8924500be62dea3895a98336122a2944cc4ab024bc5George Mount        int transition = state != null ? 0 : mTransition;
893cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        Op op = mTail;
894cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        while (op != null) {
8954500be62dea3895a98336122a2944cc4ab024bc5George Mount            int popEnterAnim = state != null ? 0 : op.popEnterAnim;
8964500be62dea3895a98336122a2944cc4ab024bc5George Mount            int popExitAnim= state != null ? 0 : op.popExitAnim;
897cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            switch (op.cmd) {
898cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                case OP_ADD: {
899cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment f = op.fragment;
9004500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = popExitAnim;
901cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    mManager.removeFragment(f,
9024500be62dea3895a98336122a2944cc4ab024bc5George Mount                            FragmentManagerImpl.reverseTransit(transition), transitionStyle);
903cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                } break;
904cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                case OP_REPLACE: {
905cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment f = op.fragment;
9065506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                    if (f != null) {
9074500be62dea3895a98336122a2944cc4ab024bc5George Mount                        f.mNextAnim = popExitAnim;
9085506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                        mManager.removeFragment(f,
9094500be62dea3895a98336122a2944cc4ab024bc5George Mount                                FragmentManagerImpl.reverseTransit(transition), transitionStyle);
9105506618c80a292ac275d8b0c1046b446c7f58836Dianne Hackborn                    }
911cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    if (op.removed != null) {
912cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        for (int i=0; i<op.removed.size(); i++) {
913cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                            Fragment old = op.removed.get(i);
9144500be62dea3895a98336122a2944cc4ab024bc5George Mount                            old.mNextAnim = popEnterAnim;
915cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                            mManager.addFragment(old, false);
916cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                        }
917cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    }
918cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                } break;
919cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                case OP_REMOVE: {
920cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment f = op.fragment;
9214500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = popEnterAnim;
922cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    mManager.addFragment(f, false);
923cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                } break;
924cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                case OP_HIDE: {
925cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment f = op.fragment;
9264500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = popEnterAnim;
927cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    mManager.showFragment(f,
9284500be62dea3895a98336122a2944cc4ab024bc5George Mount                            FragmentManagerImpl.reverseTransit(transition), transitionStyle);
929cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                } break;
930cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                case OP_SHOW: {
931cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    Fragment f = op.fragment;
9324500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = popExitAnim;
933cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    mManager.hideFragment(f,
9344500be62dea3895a98336122a2944cc4ab024bc5George Mount                            FragmentManagerImpl.reverseTransit(transition), transitionStyle);
935cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                } break;
936eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                case OP_DETACH: {
937eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                    Fragment f = op.fragment;
9384500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = popEnterAnim;
939eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                    mManager.attachFragment(f,
9404500be62dea3895a98336122a2944cc4ab024bc5George Mount                            FragmentManagerImpl.reverseTransit(transition), transitionStyle);
941eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                } break;
942eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                case OP_ATTACH: {
943eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                    Fragment f = op.fragment;
9444500be62dea3895a98336122a2944cc4ab024bc5George Mount                    f.mNextAnim = popEnterAnim;
945eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                    mManager.detachFragment(f,
9464500be62dea3895a98336122a2944cc4ab024bc5George Mount                            FragmentManagerImpl.reverseTransit(transition), transitionStyle);
947eedc67283a5a49dce86c625e54596dfdea9465a7Dianne Hackborn                } break;
948cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                default: {
949cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                    throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
950cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn                }
951cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            }
952cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
953cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            op = op.prev;
954cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
955cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
956cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (doStateMove) {
957cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mManager.moveToState(mManager.mCurState,
9584500be62dea3895a98336122a2944cc4ab024bc5George Mount                    FragmentManagerImpl.reverseTransit(transition), transitionStyle, true);
9590f5ae57910484f1d873fdad90966b6244a633bd4George Mount            state = null;
960cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
961cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
962cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        if (mIndex >= 0) {
963cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mManager.freeBackStackIndex(mIndex);
964cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn            mIndex = -1;
965cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        }
9664500be62dea3895a98336122a2944cc4ab024bc5George Mount        return state;
967cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
968cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
969cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public String getName() {
970cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mName;
971cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
972cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
973cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public int getTransition() {
974cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mTransition;
975cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
976cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
977cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public int getTransitionStyle() {
978cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mTransitionStyle;
979cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
980cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn
981cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    public boolean isEmpty() {
982cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn        return mNumOp == 0;
983cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn    }
9849f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
9859f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    /**
9869f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * When custom fragment transitions are used, this sets up the state for each transition
9879f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * and begins the transition. A different transition is started for each fragment container
9889f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * and consists of up to 3 different transitions: the exit transition, a shared element
9899f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * transition and an enter transition.
9909f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *
9919f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * <p>The exit transition operates against the leaf nodes of the first fragment
9929f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * with a view that was removed. If no such fragment was removed, then no exit
9939f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * transition is executed. The exit transition comes from the outgoing fragment.</p>
9949f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *
9959f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * <p>The enter transition operates against the last fragment that was added. If
9969f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * that fragment does not have a view or no fragment was added, then no enter
9979f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * transition is executed. The enter transition comes from the incoming fragment.</p>
9989f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *
9999f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * <p>The shared element transition operates against all views and comes either
10009f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * from the outgoing fragment or the incoming fragment, depending on whether this
10019f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * is going forward or popping the back stack. When going forward, the incoming
10029f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * fragment's enter shared element transition is used, but when going back, the
10039f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * outgoing fragment's return shared element transition is used. Shared element
10049f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * transitions only operate if there is both an incoming and outgoing fragment.</p>
10059f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *
10069f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param firstOutFragments The list of first fragments to be removed, keyed on the
10079f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *                          container ID.
10089f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param lastInFragments The list of last fragments to be added, keyed on the
10099f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *                        container ID.
10109f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param isBack true if this is popping the back stack or false if this is a
10119f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *               forward operation.
10129f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @return The TransitionState used to complete the operation of the transition
10130f5ae57910484f1d873fdad90966b6244a633bd4George Mount     * in {@link #setNameOverrides(BackStackRecord.TransitionState, java.util.ArrayList,
10140f5ae57910484f1d873fdad90966b6244a633bd4George Mount     * java.util.ArrayList)}.
10159f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     */
10169f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private TransitionState beginTransition(SparseArray<Fragment> firstOutFragments,
10179f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            SparseArray<Fragment> lastInFragments, boolean isBack) {
10189f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        TransitionState state = new TransitionState();
10199f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
10209f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        // Adding a non-existent target view makes sure that the transitions don't target
10219f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        // any views by default. They'll only target the views we tell add. If we don't
10229f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        // add any, then no views will be targeted.
10239f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        state.nonExistentView = new View(mManager.mActivity);
10249f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
10258dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        boolean anyTransitionStarted = false;
10269f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        // Go over all leaving fragments.
10279f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        for (int i = 0; i < firstOutFragments.size(); i++) {
10289f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            int containerId = firstOutFragments.keyAt(i);
10298dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            if (configureTransitions(containerId, state, isBack, firstOutFragments,
10308dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    lastInFragments)) {
10318dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                anyTransitionStarted = true;
10328dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            }
10339f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
10349f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
10359f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        // Now go over all entering fragments that didn't have a leaving fragment.
10369f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        for (int i = 0; i < lastInFragments.size(); i++) {
10379f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            int containerId = lastInFragments.keyAt(i);
10388dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            if (firstOutFragments.get(containerId) == null &&
10399f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                configureTransitions(containerId, state, isBack, firstOutFragments,
10408dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                        lastInFragments)) {
10418dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                anyTransitionStarted = true;
10429f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
10439f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
10449f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
10458dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        if (!anyTransitionStarted) {
10468dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            state = null;
10478dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        }
10488dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount
10499f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        return state;
10509f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
10519f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
10529f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private static Object getEnterTransition(Fragment inFragment, boolean isBack) {
10539f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (inFragment == null) {
10549f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            return null;
10559f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
10560f5ae57910484f1d873fdad90966b6244a633bd4George Mount        return FragmentTransitionCompat21.cloneTransition(isBack ?
10570f5ae57910484f1d873fdad90966b6244a633bd4George Mount                inFragment.getReenterTransition() : inFragment.getEnterTransition());
10589f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
10599f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
10609f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private static Object getExitTransition(Fragment outFragment, boolean isBack) {
10619f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (outFragment == null) {
10629f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            return null;
10639f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
10640f5ae57910484f1d873fdad90966b6244a633bd4George Mount        return FragmentTransitionCompat21.cloneTransition(isBack ?
10650f5ae57910484f1d873fdad90966b6244a633bd4George Mount                outFragment.getReturnTransition() : outFragment.getExitTransition());
10669f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
10679f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
10689f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private static Object getSharedElementTransition(Fragment inFragment, Fragment outFragment,
10699f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            boolean isBack) {
10709f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (inFragment == null || outFragment == null) {
10719f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            return null;
10729f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
10730f5ae57910484f1d873fdad90966b6244a633bd4George Mount        return FragmentTransitionCompat21.cloneTransition(isBack ?
10740f5ae57910484f1d873fdad90966b6244a633bd4George Mount                outFragment.getSharedElementReturnTransition() :
10750f5ae57910484f1d873fdad90966b6244a633bd4George Mount                inFragment.getSharedElementEnterTransition());
10769f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
10779f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
10780f5ae57910484f1d873fdad90966b6244a633bd4George Mount    private static Object captureExitingViews(Object exitTransition, Fragment outFragment,
1079c766ad5a6e0c115f08b933ede22375c7070a3391George Mount            ArrayList<View> exitingViews, ArrayMap<String, View> namedViews, View nonExistentView) {
10809f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (exitTransition != null) {
10819f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            exitTransition = FragmentTransitionCompat21.captureExitingViews(exitTransition,
1082c766ad5a6e0c115f08b933ede22375c7070a3391George Mount                    outFragment.getView(), exitingViews, namedViews, nonExistentView);
10839f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
10849f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        return exitTransition;
10859f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
10869f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
10879f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private ArrayMap<String, View> remapSharedElements(TransitionState state, Fragment outFragment,
10880f5ae57910484f1d873fdad90966b6244a633bd4George Mount            boolean isBack) {
10890f5ae57910484f1d873fdad90966b6244a633bd4George Mount        ArrayMap<String, View> namedViews = new ArrayMap<String, View>();
10909f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (mSharedElementSourceNames != null) {
10919f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            FragmentTransitionCompat21.findNamedViews(namedViews, outFragment.getView());
10929f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            if (isBack) {
10939f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                namedViews.retainAll(mSharedElementTargetNames);
10949f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            } else {
10959f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                namedViews = remapNames(mSharedElementSourceNames, mSharedElementTargetNames,
10960f5ae57910484f1d873fdad90966b6244a633bd4George Mount                        namedViews);
10979f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
10989f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
10999f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
11009f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (isBack) {
11019306f07b1d66f4974a81f781d29739b30124fff0George Mount            if (outFragment.mEnterTransitionCallback != null) {
11029306f07b1d66f4974a81f781d29739b30124fff0George Mount                outFragment.mEnterTransitionCallback.onMapSharedElements(
11039f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                        mSharedElementTargetNames, namedViews);
11049f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
11059f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            setBackNameOverrides(state, namedViews, false);
11069f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        } else {
11079306f07b1d66f4974a81f781d29739b30124fff0George Mount            if (outFragment.mExitTransitionCallback != null) {
11089306f07b1d66f4974a81f781d29739b30124fff0George Mount                outFragment.mExitTransitionCallback.onMapSharedElements(
11099f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                        mSharedElementTargetNames, namedViews);
11109f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
11119f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            setNameOverrides(state, namedViews, false);
11129f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
11139f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
11149f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        return namedViews;
11159f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
11169f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
11179f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    /**
11189f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * Configures custom transitions for a specific fragment container.
11199f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *
11209f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param containerId The container ID of the fragments to configure the transition for.
11210f5ae57910484f1d873fdad90966b6244a633bd4George Mount     * @param state The Transition State keeping track of the executing transitions.
11229f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param firstOutFragments The list of first fragments to be removed, keyed on the
11239f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *                          container ID.
11249f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param lastInFragments The list of last fragments to be added, keyed on the
11259f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *                        container ID.
11269f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param isBack true if this is popping the back stack or false if this is a
11279f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *               forward operation.
11289f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     */
11298dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount    private boolean configureTransitions(int containerId, TransitionState state, boolean isBack,
11300f5ae57910484f1d873fdad90966b6244a633bd4George Mount            SparseArray<Fragment> firstOutFragments, SparseArray<Fragment> lastInFragments) {
11319f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        ViewGroup sceneRoot = (ViewGroup) mManager.mContainer.findViewById(containerId);
11328dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        if (sceneRoot == null) {
11338dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            return false;
11348dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        }
11358dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        final Fragment inFragment = lastInFragments.get(containerId);
11368dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        Fragment outFragment = firstOutFragments.get(containerId);
11378dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount
11388dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        Object enterTransition = getEnterTransition(inFragment, isBack);
11398dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        Object sharedElementTransition = getSharedElementTransition(inFragment, outFragment,
11408dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                isBack);
11418dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        Object exitTransition = getExitTransition(outFragment, isBack);
11428dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        if (enterTransition == null && sharedElementTransition == null &&
11438dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                exitTransition == null) {
11448dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            return false; // no transitions!
11458dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        }
11468dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        ArrayMap<String, View> namedViews = null;
114762260534040eba52462875a435df2c1f50ab846eGeorge Mount        ArrayList<View> sharedElementTargets = new ArrayList<View>();
11488dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        if (sharedElementTransition != null) {
11498dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            namedViews = remapSharedElements(state, outFragment, isBack);
1150c766ad5a6e0c115f08b933ede22375c7070a3391George Mount            sharedElementTargets.add(state.nonExistentView);
1151c766ad5a6e0c115f08b933ede22375c7070a3391George Mount            sharedElementTargets.addAll(namedViews.values());
11528dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount
11538dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            // Notify the start of the transition.
11548dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            SharedElementCallback callback = isBack ?
11558dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    outFragment.mEnterTransitionCallback :
11568dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    inFragment.mEnterTransitionCallback;
11578dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            if (callback != null) {
11588dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                ArrayList<String> names = new ArrayList<String>(namedViews.keySet());
11598dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                ArrayList<View> views = new ArrayList<View>(namedViews.values());
11608dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                callback.onSharedElementStart(names, views, null);
11619f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
11628dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        }
11639f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
11648dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        ArrayList<View> exitingViews = new ArrayList<View>();
11658dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        exitTransition = captureExitingViews(exitTransition, outFragment, exitingViews,
1166c766ad5a6e0c115f08b933ede22375c7070a3391George Mount                namedViews, state.nonExistentView);
11675a8f14de0bb4304f9a3aebdcb35ee0dd607f27f7George Mount
11688dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        // Set the epicenter of the exit transition
11698dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        if (mSharedElementTargetNames != null && namedViews != null) {
11708dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            View epicenterView = namedViews.get(mSharedElementTargetNames.get(0));
11718dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            if (epicenterView != null) {
11728dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                if (exitTransition != null) {
11738dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    FragmentTransitionCompat21.setEpicenter(exitTransition, epicenterView);
11748dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                }
11758dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                if (sharedElementTransition != null) {
11768dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    FragmentTransitionCompat21.setEpicenter(sharedElementTransition,
11778dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                            epicenterView);
11789f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                }
11799f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
11808dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        }
11819f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
11828dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        FragmentTransitionCompat21.ViewRetriever viewRetriever =
11838dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                new FragmentTransitionCompat21.ViewRetriever() {
11848dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    @Override
11858dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    public View getView() {
11868dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                        return inFragment.getView();
11878dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    }
11888dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                };
11899f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
11908dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        if (sharedElementTransition != null) {
11918dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            prepareSharedElementTransition(state, sceneRoot, sharedElementTransition,
119262260534040eba52462875a435df2c1f50ab846eGeorge Mount                    inFragment, outFragment, isBack, sharedElementTargets);
11938dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        }
11940f5ae57910484f1d873fdad90966b6244a633bd4George Mount
11958dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        ArrayList<View> enteringViews = new ArrayList<View>();
11968dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        ArrayMap<String, View> renamedViews = new ArrayMap<String, View>();
11979f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
11988dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        boolean allowOverlap = isBack ? inFragment.getAllowReturnTransitionOverlap() :
11998dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                inFragment.getAllowEnterTransitionOverlap();
12008dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        Object transition = FragmentTransitionCompat21.mergeTransitions(enterTransition,
12018dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                exitTransition, sharedElementTransition, allowOverlap);
12029f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
12038dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        if (transition != null) {
12048dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            FragmentTransitionCompat21.addTransitionTargets(enterTransition,
12058dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    sharedElementTransition, sceneRoot, viewRetriever, state.nonExistentView,
12068dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    state.enteringEpicenterView, state.nameOverrides, enteringViews,
120762260534040eba52462875a435df2c1f50ab846eGeorge Mount                    renamedViews, sharedElementTargets);
12088dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            excludeHiddenFragmentsAfterEnter(sceneRoot, state, containerId, transition);
12090f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12108dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            // We want to exclude hidden views later, so we need a non-null list in the
12118dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            // transition now.
12128dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            FragmentTransitionCompat21.excludeTarget(transition, state.nonExistentView, true);
12138dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            // Now exclude all currently hidden fragments.
12148dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            excludeHiddenFragments(state, containerId, transition);
12150f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12168dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            FragmentTransitionCompat21.beginDelayedTransition(sceneRoot, transition);
12170f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12188dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount            FragmentTransitionCompat21.cleanupTransitions(sceneRoot, state.nonExistentView,
12198dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    enterTransition, enteringViews, exitTransition, exitingViews,
122062260534040eba52462875a435df2c1f50ab846eGeorge Mount                    sharedElementTransition, sharedElementTargets,
12218dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount                    transition, state.hiddenFragmentViews, renamedViews);
12220f5ae57910484f1d873fdad90966b6244a633bd4George Mount        }
12238dfd79ec7028cfdfa1ba69ed7cbf27aac41dc78aGeorge Mount        return transition != null;
12240f5ae57910484f1d873fdad90966b6244a633bd4George Mount    }
12250f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12260f5ae57910484f1d873fdad90966b6244a633bd4George Mount    private void prepareSharedElementTransition(final TransitionState state, final View sceneRoot,
12270f5ae57910484f1d873fdad90966b6244a633bd4George Mount            final Object sharedElementTransition, final Fragment inFragment,
122862260534040eba52462875a435df2c1f50ab846eGeorge Mount            final Fragment outFragment, final boolean isBack,
122962260534040eba52462875a435df2c1f50ab846eGeorge Mount            final ArrayList<View> sharedElementTargets) {
12300f5ae57910484f1d873fdad90966b6244a633bd4George Mount        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
12310f5ae57910484f1d873fdad90966b6244a633bd4George Mount                new ViewTreeObserver.OnPreDrawListener() {
12320f5ae57910484f1d873fdad90966b6244a633bd4George Mount            @Override
12330f5ae57910484f1d873fdad90966b6244a633bd4George Mount            public boolean onPreDraw() {
12340f5ae57910484f1d873fdad90966b6244a633bd4George Mount                sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
12350f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12360f5ae57910484f1d873fdad90966b6244a633bd4George Mount                if (sharedElementTransition != null) {
123762260534040eba52462875a435df2c1f50ab846eGeorge Mount                    FragmentTransitionCompat21.removeTargets(sharedElementTransition,
123862260534040eba52462875a435df2c1f50ab846eGeorge Mount                            sharedElementTargets);
123962260534040eba52462875a435df2c1f50ab846eGeorge Mount                    sharedElementTargets.clear();
124062260534040eba52462875a435df2c1f50ab846eGeorge Mount
12410f5ae57910484f1d873fdad90966b6244a633bd4George Mount                    ArrayMap<String, View> namedViews = mapSharedElementsIn(
12420f5ae57910484f1d873fdad90966b6244a633bd4George Mount                            state, isBack, inFragment);
1243c766ad5a6e0c115f08b933ede22375c7070a3391George Mount                    sharedElementTargets.add(state.nonExistentView);
1244c766ad5a6e0c115f08b933ede22375c7070a3391George Mount                    sharedElementTargets.addAll(namedViews.values());
124562260534040eba52462875a435df2c1f50ab846eGeorge Mount                    FragmentTransitionCompat21.addTargets(sharedElementTransition,
124662260534040eba52462875a435df2c1f50ab846eGeorge Mount                            sharedElementTargets);
12470f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12480f5ae57910484f1d873fdad90966b6244a633bd4George Mount                    setEpicenterIn(namedViews, state);
12490f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12500f5ae57910484f1d873fdad90966b6244a633bd4George Mount                    callSharedElementEnd(state, inFragment, outFragment, isBack,
12510f5ae57910484f1d873fdad90966b6244a633bd4George Mount                            namedViews);
12520f5ae57910484f1d873fdad90966b6244a633bd4George Mount                }
12530f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12540f5ae57910484f1d873fdad90966b6244a633bd4George Mount                return true;
12559f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
12560f5ae57910484f1d873fdad90966b6244a633bd4George Mount        });
12570f5ae57910484f1d873fdad90966b6244a633bd4George Mount    }
12580f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12590f5ae57910484f1d873fdad90966b6244a633bd4George Mount    private void callSharedElementEnd(TransitionState state, Fragment inFragment,
12600f5ae57910484f1d873fdad90966b6244a633bd4George Mount            Fragment outFragment, boolean isBack, ArrayMap<String, View> namedViews) {
12610f5ae57910484f1d873fdad90966b6244a633bd4George Mount        SharedElementCallback sharedElementCallback = isBack ?
12620f5ae57910484f1d873fdad90966b6244a633bd4George Mount                outFragment.mEnterTransitionCallback :
12630f5ae57910484f1d873fdad90966b6244a633bd4George Mount                inFragment.mEnterTransitionCallback;
12640f5ae57910484f1d873fdad90966b6244a633bd4George Mount        if (sharedElementCallback != null) {
12650f5ae57910484f1d873fdad90966b6244a633bd4George Mount            ArrayList<String> names = new ArrayList<String>(namedViews.keySet());
12660f5ae57910484f1d873fdad90966b6244a633bd4George Mount            ArrayList<View> views = new ArrayList<View>(namedViews.values());
12670f5ae57910484f1d873fdad90966b6244a633bd4George Mount            sharedElementCallback.onSharedElementEnd(names, views, null);
12689f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
12699f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
12709f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
12710f5ae57910484f1d873fdad90966b6244a633bd4George Mount    private void setEpicenterIn(ArrayMap<String, View> namedViews, TransitionState state) {
12720f5ae57910484f1d873fdad90966b6244a633bd4George Mount        if (mSharedElementTargetNames != null && !namedViews.isEmpty()) {
12730f5ae57910484f1d873fdad90966b6244a633bd4George Mount            // now we know the epicenter of the entering transition.
12740f5ae57910484f1d873fdad90966b6244a633bd4George Mount            View epicenter = namedViews
12750f5ae57910484f1d873fdad90966b6244a633bd4George Mount                    .get(mSharedElementTargetNames.get(0));
12760f5ae57910484f1d873fdad90966b6244a633bd4George Mount            if (epicenter != null) {
12770f5ae57910484f1d873fdad90966b6244a633bd4George Mount                state.enteringEpicenterView.epicenter = epicenter;
12780f5ae57910484f1d873fdad90966b6244a633bd4George Mount            }
12790f5ae57910484f1d873fdad90966b6244a633bd4George Mount        }
12800f5ae57910484f1d873fdad90966b6244a633bd4George Mount    }
12810f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12820f5ae57910484f1d873fdad90966b6244a633bd4George Mount    private ArrayMap<String, View> mapSharedElementsIn(TransitionState state,
12830f5ae57910484f1d873fdad90966b6244a633bd4George Mount            boolean isBack, Fragment inFragment) {
12840f5ae57910484f1d873fdad90966b6244a633bd4George Mount        // Now map the shared elements in the incoming fragment
12850f5ae57910484f1d873fdad90966b6244a633bd4George Mount        ArrayMap<String, View> namedViews = mapEnteringSharedElements(state, inFragment, isBack);
12860f5ae57910484f1d873fdad90966b6244a633bd4George Mount
12870f5ae57910484f1d873fdad90966b6244a633bd4George Mount        // remap shared elements and set the name mapping used
12880f5ae57910484f1d873fdad90966b6244a633bd4George Mount        // in the shared element transition.
12890f5ae57910484f1d873fdad90966b6244a633bd4George Mount        if (isBack) {
12900f5ae57910484f1d873fdad90966b6244a633bd4George Mount            if (inFragment.mExitTransitionCallback != null) {
12910f5ae57910484f1d873fdad90966b6244a633bd4George Mount                inFragment.mExitTransitionCallback.onMapSharedElements(
12920f5ae57910484f1d873fdad90966b6244a633bd4George Mount                        mSharedElementTargetNames, namedViews);
12930f5ae57910484f1d873fdad90966b6244a633bd4George Mount            }
12940f5ae57910484f1d873fdad90966b6244a633bd4George Mount            setBackNameOverrides(state, namedViews, true);
12950f5ae57910484f1d873fdad90966b6244a633bd4George Mount        } else {
12960f5ae57910484f1d873fdad90966b6244a633bd4George Mount            if (inFragment.mEnterTransitionCallback != null) {
12970f5ae57910484f1d873fdad90966b6244a633bd4George Mount                inFragment.mEnterTransitionCallback.onMapSharedElements(
12980f5ae57910484f1d873fdad90966b6244a633bd4George Mount                        mSharedElementTargetNames, namedViews);
12990f5ae57910484f1d873fdad90966b6244a633bd4George Mount            }
13000f5ae57910484f1d873fdad90966b6244a633bd4George Mount            setNameOverrides(state, namedViews, true);
13010f5ae57910484f1d873fdad90966b6244a633bd4George Mount        }
13020f5ae57910484f1d873fdad90966b6244a633bd4George Mount        return namedViews;
13030f5ae57910484f1d873fdad90966b6244a633bd4George Mount    }
13040f5ae57910484f1d873fdad90966b6244a633bd4George Mount
13059f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    /**
13069f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * Remaps a name-to-View map, substituting different names for keys.
13079f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *
13089f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param inMap A list of keys found in the map, in the order in toGoInMap
13099f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param toGoInMap A list of keys to use for the new map, in the order of inMap
13109f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param namedViews The current mapping
13110f5ae57910484f1d873fdad90966b6244a633bd4George Mount     * @return A copy of namedViews with the keys coming from toGoInMap.
13129f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     */
13139f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private static ArrayMap<String, View> remapNames(ArrayList<String> inMap,
13140f5ae57910484f1d873fdad90966b6244a633bd4George Mount            ArrayList<String> toGoInMap, ArrayMap<String, View> namedViews) {
13150f5ae57910484f1d873fdad90966b6244a633bd4George Mount        if (namedViews.isEmpty()) {
13160f5ae57910484f1d873fdad90966b6244a633bd4George Mount            return namedViews;
13170f5ae57910484f1d873fdad90966b6244a633bd4George Mount        }
13180f5ae57910484f1d873fdad90966b6244a633bd4George Mount        ArrayMap<String, View> remappedViews = new ArrayMap<String, View>();
13190f5ae57910484f1d873fdad90966b6244a633bd4George Mount        int numKeys = inMap.size();
13200f5ae57910484f1d873fdad90966b6244a633bd4George Mount        for (int i = 0; i < numKeys; i++) {
13210f5ae57910484f1d873fdad90966b6244a633bd4George Mount            View view = namedViews.get(inMap.get(i));
13220f5ae57910484f1d873fdad90966b6244a633bd4George Mount            if (view != null) {
13230f5ae57910484f1d873fdad90966b6244a633bd4George Mount                remappedViews.put(toGoInMap.get(i), view);
13249f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
13259f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
13260f5ae57910484f1d873fdad90966b6244a633bd4George Mount        return remappedViews;
13279f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
13289f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
13299f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    /**
13300f5ae57910484f1d873fdad90966b6244a633bd4George Mount     * Maps shared elements to views in the entering fragment.
13319f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *
13329f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param state The transition State as returned from {@link #beginTransition(
13339f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * android.util.SparseArray, android.util.SparseArray, boolean)}.
13340f5ae57910484f1d873fdad90966b6244a633bd4George Mount     * @param inFragment The last fragment to be added.
13359f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     * @param isBack true if this is popping the back stack or false if this is a
13369f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     *               forward operation.
13379f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount     */
13380f5ae57910484f1d873fdad90966b6244a633bd4George Mount    private ArrayMap<String, View> mapEnteringSharedElements(TransitionState state,
13390f5ae57910484f1d873fdad90966b6244a633bd4George Mount            Fragment inFragment, boolean isBack) {
13400f5ae57910484f1d873fdad90966b6244a633bd4George Mount        ArrayMap<String, View> namedViews = new ArrayMap<String, View>();
13419f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        View root = inFragment.getView();
13429f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (root != null) {
13439f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            if (mSharedElementSourceNames != null) {
13449f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                FragmentTransitionCompat21.findNamedViews(namedViews, root);
13459f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                if (isBack) {
13469f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    namedViews = remapNames(mSharedElementSourceNames,
13470f5ae57910484f1d873fdad90966b6244a633bd4George Mount                            mSharedElementTargetNames, namedViews);
13489f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                } else {
13499f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    namedViews.retainAll(mSharedElementTargetNames);
13509f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                }
13519f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
13529f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
13539f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        return namedViews;
13549f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
13559f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
13560f5ae57910484f1d873fdad90966b6244a633bd4George Mount    private void excludeHiddenFragmentsAfterEnter(final View sceneRoot, final TransitionState state,
13570f5ae57910484f1d873fdad90966b6244a633bd4George Mount            final int containerId, final Object transition) {
13580f5ae57910484f1d873fdad90966b6244a633bd4George Mount        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
13590f5ae57910484f1d873fdad90966b6244a633bd4George Mount                new ViewTreeObserver.OnPreDrawListener() {
13600f5ae57910484f1d873fdad90966b6244a633bd4George Mount            public boolean onPreDraw() {
13610f5ae57910484f1d873fdad90966b6244a633bd4George Mount                sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
13620f5ae57910484f1d873fdad90966b6244a633bd4George Mount                excludeHiddenFragments(state, containerId, transition);
13630f5ae57910484f1d873fdad90966b6244a633bd4George Mount                return true;
13640f5ae57910484f1d873fdad90966b6244a633bd4George Mount            }
13650f5ae57910484f1d873fdad90966b6244a633bd4George Mount        });
13660f5ae57910484f1d873fdad90966b6244a633bd4George Mount    }
13670f5ae57910484f1d873fdad90966b6244a633bd4George Mount
13689f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private void excludeHiddenFragments(TransitionState state, int containerId, Object transition) {
13699f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (mManager.mAdded != null) {
13709f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            for (int i = 0; i < mManager.mAdded.size(); i++) {
13719f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                Fragment fragment = mManager.mAdded.get(i);
13729f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                if (fragment.mView != null && fragment.mContainer != null &&
13739f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                        fragment.mContainerId == containerId) {
13749f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    if (fragment.mHidden) {
13759f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                        if (!state.hiddenFragmentViews.contains(fragment.mView)) {
13769f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                            FragmentTransitionCompat21.excludeTarget(transition, fragment.mView,
13779f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                                    true);
13789f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                            state.hiddenFragmentViews.add(fragment.mView);
13799f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                        }
13809f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    } else {
13819f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                        FragmentTransitionCompat21.excludeTarget(transition, fragment.mView,
13829f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                                false);
13839f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                        state.hiddenFragmentViews.remove(fragment.mView);
13849f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    }
13859f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                }
13869f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
13879f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
13889f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
13899f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
13909f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private static void setNameOverride(ArrayMap<String, String> overrides,
13919f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            String source, String target) {
13929f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (source != null && target != null && !source.equals(target)) {
13939f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            for (int index = 0; index < overrides.size(); index++) {
13949f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                if (source.equals(overrides.valueAt(index))) {
13959f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    overrides.setValueAt(index, target);
13969f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                    return;
13979f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                }
13989f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
13999f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            overrides.put(source, target);
14009f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
14019f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
14029f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
14039f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private static void setNameOverrides(TransitionState state, ArrayList<String> sourceNames,
14049f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            ArrayList<String> targetNames) {
14059f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        if (sourceNames != null) {
14069f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            for (int i = 0; i < sourceNames.size(); i++) {
14079f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                String source = sourceNames.get(i);
14089f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                String target = targetNames.get(i);
14099f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                setNameOverride(state.nameOverrides, source, target);
14109f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
14119f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
14129f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
14139f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
14149f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private void setBackNameOverrides(TransitionState state, ArrayMap<String, View> namedViews,
14159f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            boolean isEnd) {
14165a8f14de0bb4304f9a3aebdcb35ee0dd607f27f7George Mount        int count = mSharedElementTargetNames == null ? 0 : mSharedElementTargetNames.size();
14179f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        for (int i = 0; i < count; i++) {
14189f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            String source = mSharedElementSourceNames.get(i);
14199f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            String originalTarget = mSharedElementTargetNames.get(i);
14209f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            View view = namedViews.get(originalTarget);
14210f5ae57910484f1d873fdad90966b6244a633bd4George Mount            if (view != null) {
14220f5ae57910484f1d873fdad90966b6244a633bd4George Mount                String target = FragmentTransitionCompat21.getTransitionName(view);
14230f5ae57910484f1d873fdad90966b6244a633bd4George Mount                if (isEnd) {
14240f5ae57910484f1d873fdad90966b6244a633bd4George Mount                    setNameOverride(state.nameOverrides, source, target);
14250f5ae57910484f1d873fdad90966b6244a633bd4George Mount                } else {
14260f5ae57910484f1d873fdad90966b6244a633bd4George Mount                    setNameOverride(state.nameOverrides, target, source);
14270f5ae57910484f1d873fdad90966b6244a633bd4George Mount                }
14289f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
14299f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
14309f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
14319f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
14329f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    private void setNameOverrides(TransitionState state, ArrayMap<String, View> namedViews,
14339f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            boolean isEnd) {
14349f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        int count = namedViews.size();
14359f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        for (int i = 0; i < count; i++) {
14369f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            String source = namedViews.keyAt(i);
14379f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            String target = FragmentTransitionCompat21.getTransitionName(namedViews.valueAt(i));
14389f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            if (isEnd) {
14399f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                setNameOverride(state.nameOverrides, source, target);
14409f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            } else {
14419f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                setNameOverride(state.nameOverrides, target, source);
14429f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount            }
14439f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        }
14449f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
14459f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
14469f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    public class TransitionState {
14479f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        public ArrayMap<String, String> nameOverrides = new ArrayMap<String, String>();
14489f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        public ArrayList<View> hiddenFragmentViews = new ArrayList<View>();
14499f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount
14509f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        public FragmentTransitionCompat21.EpicenterView enteringEpicenterView =
14519f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount                new FragmentTransitionCompat21.EpicenterView();
14529f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount        public View nonExistentView;
14539f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount    }
1454cba2e2c881e8e16ea5025b564c94320174d65f01Dianne Hackborn}
1455