blob: 6b16e8f61e14d15ccbab4b6dfab4dffa859090b8 [file] [log] [blame]
Dianne Hackborn5ae74d62010-05-19 19:14:57 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
Clara Bayarricd916f22016-06-13 13:14:51 +010019import android.os.Build;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070020import android.os.Parcel;
21import android.os.Parcelable;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070022import android.text.TextUtils;
Dianne Hackborn445646c2010-06-25 15:52:59 -070023import android.util.Log;
Dianne Hackbornf43a33c2012-09-27 00:48:11 -070024import android.util.LogWriter;
George Mountd4c3c912014-06-09 12:31:34 -070025import android.view.View;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070026
George Mounta7245b42016-02-10 17:03:32 -080027import com.android.internal.util.FastPrintWriter;
28
Dianne Hackborn30d71892010-12-11 10:37:55 -080029import java.io.FileDescriptor;
30import java.io.PrintWriter;
Clara Bayarricd916f22016-06-13 13:14:51 +010031import java.lang.reflect.Modifier;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070032import java.util.ArrayList;
33
34final class BackStackState implements Parcelable {
35 final int[] mOps;
36 final int mTransition;
37 final int mTransitionStyle;
38 final String mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -070039 final int mIndex;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070040 final int mBreadCrumbTitleRes;
41 final CharSequence mBreadCrumbTitleText;
42 final int mBreadCrumbShortTitleRes;
43 final CharSequence mBreadCrumbShortTitleText;
George Mountd4c3c912014-06-09 12:31:34 -070044 final ArrayList<String> mSharedElementSourceNames;
45 final ArrayList<String> mSharedElementTargetNames;
George Mounteca8e222016-07-07 13:13:05 -070046 final boolean mAllowOptimization;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070047
48 public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
George Mountf2045f82016-06-27 13:15:01 -070049 final int numOps = bse.mOps.size();
50 mOps = new int[numOps * 6];
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070051
Dianne Hackbornb7a2e472010-08-12 16:20:42 -070052 if (!bse.mAddToBackStack) {
53 throw new IllegalStateException("Not on back stack");
54 }
55
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070056 int pos = 0;
George Mountf2045f82016-06-27 13:15:01 -070057 for (int opNum = 0; opNum < numOps; opNum++) {
58 final BackStackRecord.Op op = bse.mOps.get(opNum);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070059 mOps[pos++] = op.cmd;
Dianne Hackbornee76efb2012-06-05 10:27:40 -070060 mOps[pos++] = op.fragment != null ? op.fragment.mIndex : -1;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070061 mOps[pos++] = op.enterAnim;
62 mOps[pos++] = op.exitAnim;
Chet Haasebc377842011-03-22 11:35:22 -070063 mOps[pos++] = op.popEnterAnim;
64 mOps[pos++] = op.popExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070065 }
66 mTransition = bse.mTransition;
67 mTransitionStyle = bse.mTransitionStyle;
68 mName = bse.mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -070069 mIndex = bse.mIndex;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070070 mBreadCrumbTitleRes = bse.mBreadCrumbTitleRes;
71 mBreadCrumbTitleText = bse.mBreadCrumbTitleText;
72 mBreadCrumbShortTitleRes = bse.mBreadCrumbShortTitleRes;
73 mBreadCrumbShortTitleText = bse.mBreadCrumbShortTitleText;
George Mountd4c3c912014-06-09 12:31:34 -070074 mSharedElementSourceNames = bse.mSharedElementSourceNames;
75 mSharedElementTargetNames = bse.mSharedElementTargetNames;
George Mounteca8e222016-07-07 13:13:05 -070076 mAllowOptimization = bse.mAllowOptimization;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070077 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070078
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070079 public BackStackState(Parcel in) {
80 mOps = in.createIntArray();
81 mTransition = in.readInt();
82 mTransitionStyle = in.readInt();
83 mName = in.readString();
Dianne Hackborndd913a52010-07-22 12:17:04 -070084 mIndex = in.readInt();
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070085 mBreadCrumbTitleRes = in.readInt();
86 mBreadCrumbTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
87 mBreadCrumbShortTitleRes = in.readInt();
88 mBreadCrumbShortTitleText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
George Mountd4c3c912014-06-09 12:31:34 -070089 mSharedElementSourceNames = in.createStringArrayList();
90 mSharedElementTargetNames = in.createStringArrayList();
George Mounteca8e222016-07-07 13:13:05 -070091 mAllowOptimization = in.readInt() != 0;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070092 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070093
94 public BackStackRecord instantiate(FragmentManagerImpl fm) {
95 BackStackRecord bse = new BackStackRecord(fm);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070096 int pos = 0;
Dianne Hackbornf43a33c2012-09-27 00:48:11 -070097 int num = 0;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -070098 while (pos < mOps.length) {
Dianne Hackbornc6669ca2010-09-16 01:33:24 -070099 BackStackRecord.Op op = new BackStackRecord.Op();
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700100 op.cmd = mOps[pos++];
George Mountd4c3c912014-06-09 12:31:34 -0700101 if (FragmentManagerImpl.DEBUG) {
102 Log.v(FragmentManagerImpl.TAG,
103 "Instantiate " + bse + " op #" + num + " base fragment #" + mOps[pos]);
104 }
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700105 int findex = mOps[pos++];
106 if (findex >= 0) {
107 Fragment f = fm.mActive.get(findex);
108 op.fragment = f;
109 } else {
110 op.fragment = null;
111 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700112 op.enterAnim = mOps[pos++];
113 op.exitAnim = mOps[pos++];
Chet Haasebc377842011-03-22 11:35:22 -0700114 op.popEnterAnim = mOps[pos++];
115 op.popExitAnim = mOps[pos++];
George Mount41fb9942016-03-30 13:59:23 -0700116 bse.mEnterAnim = op.enterAnim;
117 bse.mExitAnim = op.exitAnim;
118 bse.mPopEnterAnim = op.popEnterAnim;
119 bse.mPopExitAnim = op.popExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700120 bse.addOp(op);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700121 num++;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700122 }
123 bse.mTransition = mTransition;
124 bse.mTransitionStyle = mTransitionStyle;
125 bse.mName = mName;
Dianne Hackborndd913a52010-07-22 12:17:04 -0700126 bse.mIndex = mIndex;
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700127 bse.mAddToBackStack = true;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700128 bse.mBreadCrumbTitleRes = mBreadCrumbTitleRes;
129 bse.mBreadCrumbTitleText = mBreadCrumbTitleText;
130 bse.mBreadCrumbShortTitleRes = mBreadCrumbShortTitleRes;
131 bse.mBreadCrumbShortTitleText = mBreadCrumbShortTitleText;
George Mountd4c3c912014-06-09 12:31:34 -0700132 bse.mSharedElementSourceNames = mSharedElementSourceNames;
133 bse.mSharedElementTargetNames = mSharedElementTargetNames;
George Mounteca8e222016-07-07 13:13:05 -0700134 bse.mAllowOptimization = mAllowOptimization;
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700135 bse.bumpBackStackNesting(1);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700136 return bse;
137 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700138
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700139 public int describeContents() {
140 return 0;
141 }
142
143 public void writeToParcel(Parcel dest, int flags) {
144 dest.writeIntArray(mOps);
145 dest.writeInt(mTransition);
146 dest.writeInt(mTransitionStyle);
147 dest.writeString(mName);
Dianne Hackborndd913a52010-07-22 12:17:04 -0700148 dest.writeInt(mIndex);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700149 dest.writeInt(mBreadCrumbTitleRes);
150 TextUtils.writeToParcel(mBreadCrumbTitleText, dest, 0);
151 dest.writeInt(mBreadCrumbShortTitleRes);
152 TextUtils.writeToParcel(mBreadCrumbShortTitleText, dest, 0);
George Mountd4c3c912014-06-09 12:31:34 -0700153 dest.writeStringList(mSharedElementSourceNames);
154 dest.writeStringList(mSharedElementTargetNames);
George Mounteca8e222016-07-07 13:13:05 -0700155 dest.writeInt(mAllowOptimization ? 1 : 0);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700156 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700157
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700158 public static final Parcelable.Creator<BackStackState> CREATOR
159 = new Parcelable.Creator<BackStackState>() {
160 public BackStackState createFromParcel(Parcel in) {
161 return new BackStackState(in);
162 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700163
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700164 public BackStackState[] newArray(int size) {
165 return new BackStackState[size];
166 }
167 };
168}
169
170/**
171 * @hide Entry of an operation on the fragment back stack.
172 */
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700173final class BackStackRecord extends FragmentTransaction implements
George Mounteca8e222016-07-07 13:13:05 -0700174 FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700175 static final String TAG = FragmentManagerImpl.TAG;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700176
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700177 final FragmentManagerImpl mManager;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700178
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700179 static final int OP_NULL = 0;
180 static final int OP_ADD = 1;
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700181 static final int OP_REPLACE = 2;
182 static final int OP_REMOVE = 3;
183 static final int OP_HIDE = 4;
184 static final int OP_SHOW = 5;
Dianne Hackborn47c41562011-04-15 19:00:20 -0700185 static final int OP_DETACH = 6;
186 static final int OP_ATTACH = 7;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700187
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700188 static final class Op {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700189 int cmd;
190 Fragment fragment;
191 int enterAnim;
192 int exitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700193 int popEnterAnim;
194 int popExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700195 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700196
George Mountf2045f82016-06-27 13:15:01 -0700197 ArrayList<Op> mOps = new ArrayList<>();
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700198 int mEnterAnim;
199 int mExitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700200 int mPopEnterAnim;
201 int mPopExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700202 int mTransition;
203 int mTransitionStyle;
204 boolean mAddToBackStack;
Adam Powell0c24a552010-11-03 16:44:11 -0700205 boolean mAllowAddToBackStack = true;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700206 String mName;
207 boolean mCommitted;
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700208 int mIndex = -1;
George Mounteca8e222016-07-07 13:13:05 -0700209 boolean mAllowOptimization;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700210
211 int mBreadCrumbTitleRes;
212 CharSequence mBreadCrumbTitleText;
213 int mBreadCrumbShortTitleRes;
214 CharSequence mBreadCrumbShortTitleText;
215
George Mountd4c3c912014-06-09 12:31:34 -0700216 ArrayList<String> mSharedElementSourceNames;
217 ArrayList<String> mSharedElementTargetNames;
218
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700219 @Override
220 public String toString() {
221 StringBuilder sb = new StringBuilder(128);
222 sb.append("BackStackEntry{");
223 sb.append(Integer.toHexString(System.identityHashCode(this)));
224 if (mIndex >= 0) {
225 sb.append(" #");
226 sb.append(mIndex);
227 }
228 if (mName != null) {
229 sb.append(" ");
230 sb.append(mName);
231 }
232 sb.append("}");
233 return sb.toString();
234 }
235
Dianne Hackborn30d71892010-12-11 10:37:55 -0800236 public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700237 dump(prefix, writer, true);
238 }
239
240 void dump(String prefix, PrintWriter writer, boolean full) {
241 if (full) {
George Mountd4c3c912014-06-09 12:31:34 -0700242 writer.print(prefix);
243 writer.print("mName=");
244 writer.print(mName);
245 writer.print(" mIndex=");
246 writer.print(mIndex);
247 writer.print(" mCommitted=");
248 writer.println(mCommitted);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700249 if (mTransition != FragmentTransaction.TRANSIT_NONE) {
George Mountd4c3c912014-06-09 12:31:34 -0700250 writer.print(prefix);
251 writer.print("mTransition=#");
252 writer.print(Integer.toHexString(mTransition));
253 writer.print(" mTransitionStyle=#");
254 writer.println(Integer.toHexString(mTransitionStyle));
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700255 }
George Mountd4c3c912014-06-09 12:31:34 -0700256 if (mEnterAnim != 0 || mExitAnim != 0) {
257 writer.print(prefix);
258 writer.print("mEnterAnim=#");
259 writer.print(Integer.toHexString(mEnterAnim));
260 writer.print(" mExitAnim=#");
261 writer.println(Integer.toHexString(mExitAnim));
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700262 }
George Mountd4c3c912014-06-09 12:31:34 -0700263 if (mPopEnterAnim != 0 || mPopExitAnim != 0) {
264 writer.print(prefix);
265 writer.print("mPopEnterAnim=#");
266 writer.print(Integer.toHexString(mPopEnterAnim));
267 writer.print(" mPopExitAnim=#");
268 writer.println(Integer.toHexString(mPopExitAnim));
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700269 }
270 if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
George Mountd4c3c912014-06-09 12:31:34 -0700271 writer.print(prefix);
272 writer.print("mBreadCrumbTitleRes=#");
273 writer.print(Integer.toHexString(mBreadCrumbTitleRes));
274 writer.print(" mBreadCrumbTitleText=");
275 writer.println(mBreadCrumbTitleText);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700276 }
277 if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
George Mountd4c3c912014-06-09 12:31:34 -0700278 writer.print(prefix);
279 writer.print("mBreadCrumbShortTitleRes=#");
280 writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
281 writer.print(" mBreadCrumbShortTitleText=");
282 writer.println(mBreadCrumbShortTitleText);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700283 }
Dianne Hackborn30d71892010-12-11 10:37:55 -0800284 }
285
George Mountf2045f82016-06-27 13:15:01 -0700286 if (!mOps.isEmpty()) {
George Mountd4c3c912014-06-09 12:31:34 -0700287 writer.print(prefix);
288 writer.println("Operations:");
Dianne Hackborn30d71892010-12-11 10:37:55 -0800289 String innerPrefix = prefix + " ";
George Mountf2045f82016-06-27 13:15:01 -0700290 final int numOps = mOps.size();
291 for (int opNum = 0; opNum < numOps; opNum++) {
292 final Op op = mOps.get(opNum);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700293 String cmdStr;
294 switch (op.cmd) {
George Mountd4c3c912014-06-09 12:31:34 -0700295 case OP_NULL:
296 cmdStr = "NULL";
297 break;
298 case OP_ADD:
299 cmdStr = "ADD";
300 break;
301 case OP_REPLACE:
302 cmdStr = "REPLACE";
303 break;
304 case OP_REMOVE:
305 cmdStr = "REMOVE";
306 break;
307 case OP_HIDE:
308 cmdStr = "HIDE";
309 break;
310 case OP_SHOW:
311 cmdStr = "SHOW";
312 break;
313 case OP_DETACH:
314 cmdStr = "DETACH";
315 break;
316 case OP_ATTACH:
317 cmdStr = "ATTACH";
318 break;
319 default:
320 cmdStr = "cmd=" + op.cmd;
321 break;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800322 }
George Mountd4c3c912014-06-09 12:31:34 -0700323 writer.print(prefix);
324 writer.print(" Op #");
George Mountf2045f82016-06-27 13:15:01 -0700325 writer.print(opNum);
George Mountd4c3c912014-06-09 12:31:34 -0700326 writer.print(": ");
327 writer.print(cmdStr);
328 writer.print(" ");
329 writer.println(op.fragment);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700330 if (full) {
331 if (op.enterAnim != 0 || op.exitAnim != 0) {
George Mountd4c3c912014-06-09 12:31:34 -0700332 writer.print(innerPrefix);
333 writer.print("enterAnim=#");
334 writer.print(Integer.toHexString(op.enterAnim));
335 writer.print(" exitAnim=#");
336 writer.println(Integer.toHexString(op.exitAnim));
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700337 }
338 if (op.popEnterAnim != 0 || op.popExitAnim != 0) {
George Mountd4c3c912014-06-09 12:31:34 -0700339 writer.print(innerPrefix);
340 writer.print("popEnterAnim=#");
341 writer.print(Integer.toHexString(op.popEnterAnim));
342 writer.print(" popExitAnim=#");
343 writer.println(Integer.toHexString(op.popExitAnim));
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700344 }
Chet Haasebc377842011-03-22 11:35:22 -0700345 }
Dianne Hackborn30d71892010-12-11 10:37:55 -0800346 }
347 }
348 }
349
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700350 public BackStackRecord(FragmentManagerImpl manager) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700351 mManager = manager;
Clara Bayarri7eda6442016-11-10 20:45:38 +0000352 int targetSdkVersion = manager.mHost.getContext().getApplicationInfo().targetSdkVersion;
353 // TODO: make the check N_MR1 or O
354 mAllowOptimization = targetSdkVersion > Build.VERSION_CODES.N;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700355 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700356
357 public int getId() {
358 return mIndex;
359 }
360
Dianne Hackborn327fbd22011-01-17 14:38:50 -0800361 public int getBreadCrumbTitleRes() {
362 return mBreadCrumbTitleRes;
363 }
364
365 public int getBreadCrumbShortTitleRes() {
366 return mBreadCrumbShortTitleRes;
367 }
368
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700369 public CharSequence getBreadCrumbTitle() {
370 if (mBreadCrumbTitleRes != 0) {
Todd Kennedya5fc6f02015-04-14 18:22:54 -0700371 return mManager.mHost.getContext().getText(mBreadCrumbTitleRes);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700372 }
373 return mBreadCrumbTitleText;
374 }
375
376 public CharSequence getBreadCrumbShortTitle() {
377 if (mBreadCrumbShortTitleRes != 0) {
Todd Kennedya5fc6f02015-04-14 18:22:54 -0700378 return mManager.mHost.getContext().getText(mBreadCrumbShortTitleRes);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700379 }
380 return mBreadCrumbShortTitleText;
381 }
382
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700383 void addOp(Op op) {
George Mountf2045f82016-06-27 13:15:01 -0700384 mOps.add(op);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700385 op.enterAnim = mEnterAnim;
386 op.exitAnim = mExitAnim;
Chet Haasebc377842011-03-22 11:35:22 -0700387 op.popEnterAnim = mPopEnterAnim;
388 op.popExitAnim = mPopExitAnim;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700389 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700390
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700391 public FragmentTransaction add(Fragment fragment, String tag) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700392 doAddOp(0, fragment, tag, OP_ADD);
393 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700394 }
395
396 public FragmentTransaction add(int containerViewId, Fragment fragment) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700397 doAddOp(containerViewId, fragment, null, OP_ADD);
398 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700399 }
400
401 public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700402 doAddOp(containerViewId, fragment, tag, OP_ADD);
403 return this;
404 }
405
406 private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
Clara Bayarricd916f22016-06-13 13:14:51 +0100407 if (mManager.mHost.getContext() != null) {
408 final int targetSdkVersion =
409 mManager.mHost.getContext().getApplicationInfo().targetSdkVersion;
410 final Class fragmentClass = fragment.getClass();
411 final int modifiers = fragmentClass.getModifiers();
412 // TODO: make the check N_MR1 or O
413 if (targetSdkVersion > Build.VERSION_CODES.N && (fragmentClass.isAnonymousClass()
414 || !Modifier.isPublic(modifiers)
415 || (fragmentClass.isMemberClass() && !Modifier.isStatic(modifiers)))) {
Clara Bayarrieb7b7ec2016-06-23 11:08:55 +0100416 throw new IllegalStateException("Fragment " + fragmentClass.getCanonicalName()
417 + " must be a public static class to be properly recreated from"
418 + " instance state.");
Clara Bayarricd916f22016-06-13 13:14:51 +0100419 }
420 }
Dianne Hackborn3e449ce2010-09-11 20:52:31 -0700421 fragment.mFragmentManager = mManager;
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700422
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700423 if (tag != null) {
424 if (fragment.mTag != null && !tag.equals(fragment.mTag)) {
425 throw new IllegalStateException("Can't change tag of fragment "
426 + fragment + ": was " + fragment.mTag
427 + " now " + tag);
428 }
429 fragment.mTag = tag;
430 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700431
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700432 if (containerViewId != 0) {
Adam Powelle01f5952016-02-23 15:25:42 -0800433 if (containerViewId == View.NO_ID) {
434 throw new IllegalArgumentException("Can't add fragment "
435 + fragment + " with tag " + tag + " to container view with no id");
436 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700437 if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {
438 throw new IllegalStateException("Can't change container ID of fragment "
439 + fragment + ": was " + fragment.mFragmentId
440 + " now " + containerViewId);
441 }
442 fragment.mContainerId = fragment.mFragmentId = containerViewId;
443 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700444
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700445 Op op = new Op();
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700446 op.cmd = opcmd;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700447 op.fragment = fragment;
448 addOp(op);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700449 }
450
451 public FragmentTransaction replace(int containerViewId, Fragment fragment) {
452 return replace(containerViewId, fragment, null);
453 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700454
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700455 public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) {
456 if (containerViewId == 0) {
457 throw new IllegalArgumentException("Must use non-zero containerViewId");
458 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700459
Dianne Hackbornb31e84bc2010-06-08 18:04:35 -0700460 doAddOp(containerViewId, fragment, tag, OP_REPLACE);
461 return this;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700462 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700463
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700464 public FragmentTransaction remove(Fragment fragment) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700465 Op op = new Op();
466 op.cmd = OP_REMOVE;
467 op.fragment = fragment;
468 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700469
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700470 return this;
471 }
472
473 public FragmentTransaction hide(Fragment fragment) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700474 Op op = new Op();
475 op.cmd = OP_HIDE;
476 op.fragment = fragment;
477 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700478
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700479 return this;
480 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700481
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700482 public FragmentTransaction show(Fragment fragment) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700483 Op op = new Op();
484 op.cmd = OP_SHOW;
485 op.fragment = fragment;
486 addOp(op);
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700487
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700488 return this;
489 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700490
Dianne Hackborn47c41562011-04-15 19:00:20 -0700491 public FragmentTransaction detach(Fragment fragment) {
Dianne Hackborn47c41562011-04-15 19:00:20 -0700492 Op op = new Op();
493 op.cmd = OP_DETACH;
494 op.fragment = fragment;
495 addOp(op);
496
497 return this;
498 }
499
500 public FragmentTransaction attach(Fragment fragment) {
Dianne Hackborn47c41562011-04-15 19:00:20 -0700501 Op op = new Op();
502 op.cmd = OP_ATTACH;
503 op.fragment = fragment;
504 addOp(op);
505
506 return this;
507 }
508
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700509 public FragmentTransaction setCustomAnimations(int enter, int exit) {
Chet Haasebc377842011-03-22 11:35:22 -0700510 return setCustomAnimations(enter, exit, 0, 0);
511 }
512
513 public FragmentTransaction setCustomAnimations(int enter, int exit,
514 int popEnter, int popExit) {
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700515 mEnterAnim = enter;
516 mExitAnim = exit;
Chet Haasebc377842011-03-22 11:35:22 -0700517 mPopEnterAnim = popEnter;
518 mPopExitAnim = popExit;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700519 return this;
520 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700521
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700522 public FragmentTransaction setTransition(int transition) {
523 mTransition = transition;
524 return this;
525 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700526
George Mountd4c3c912014-06-09 12:31:34 -0700527 @Override
George Mount448bace2014-08-18 16:27:43 -0700528 public FragmentTransaction addSharedElement(View sharedElement, String name) {
529 String transitionName = sharedElement.getTransitionName();
530 if (transitionName == null) {
531 throw new IllegalArgumentException("Unique transitionNames are required for all" +
532 " sharedElements");
533 }
534 if (mSharedElementSourceNames == null) {
535 mSharedElementSourceNames = new ArrayList<String>();
536 mSharedElementTargetNames = new ArrayList<String>();
537 }
538 mSharedElementSourceNames.add(transitionName);
539 mSharedElementTargetNames.add(name);
540 return this;
541 }
542
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700543 public FragmentTransaction setTransitionStyle(int styleRes) {
544 mTransitionStyle = styleRes;
545 return this;
546 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700547
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700548 public FragmentTransaction addToBackStack(String name) {
Adam Powell0c24a552010-11-03 16:44:11 -0700549 if (!mAllowAddToBackStack) {
550 throw new IllegalStateException(
551 "This FragmentTransaction is not allowed to be added to the back stack.");
552 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700553 mAddToBackStack = true;
554 mName = name;
555 return this;
556 }
557
Adam Powell0c24a552010-11-03 16:44:11 -0700558 public boolean isAddToBackStackAllowed() {
559 return mAllowAddToBackStack;
560 }
561
562 public FragmentTransaction disallowAddToBackStack() {
563 if (mAddToBackStack) {
564 throw new IllegalStateException(
565 "This transaction is already being added to the back stack");
566 }
567 mAllowAddToBackStack = false;
568 return this;
569 }
570
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700571 public FragmentTransaction setBreadCrumbTitle(int res) {
572 mBreadCrumbTitleRes = res;
573 mBreadCrumbTitleText = null;
574 return this;
575 }
576
577 public FragmentTransaction setBreadCrumbTitle(CharSequence text) {
578 mBreadCrumbTitleRes = 0;
579 mBreadCrumbTitleText = text;
580 return this;
581 }
582
583 public FragmentTransaction setBreadCrumbShortTitle(int res) {
584 mBreadCrumbShortTitleRes = res;
585 mBreadCrumbShortTitleText = null;
586 return this;
587 }
588
589 public FragmentTransaction setBreadCrumbShortTitle(CharSequence text) {
590 mBreadCrumbShortTitleRes = 0;
591 mBreadCrumbShortTitleText = text;
592 return this;
593 }
594
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700595 void bumpBackStackNesting(int amt) {
596 if (!mAddToBackStack) {
597 return;
598 }
George Mountd4c3c912014-06-09 12:31:34 -0700599 if (FragmentManagerImpl.DEBUG) {
600 Log.v(TAG, "Bump nesting in " + this
601 + " by " + amt);
602 }
George Mountf2045f82016-06-27 13:15:01 -0700603 final int numOps = mOps.size();
604 for (int opNum = 0; opNum < numOps; opNum++) {
605 final Op op = mOps.get(opNum);
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700606 if (op.fragment != null) {
607 op.fragment.mBackStackNesting += amt;
George Mountd4c3c912014-06-09 12:31:34 -0700608 if (FragmentManagerImpl.DEBUG) {
609 Log.v(TAG, "Bump nesting of "
610 + op.fragment + " to " + op.fragment.mBackStackNesting);
611 }
Dianne Hackbornee76efb2012-06-05 10:27:40 -0700612 }
Dianne Hackbornb7a2e472010-08-12 16:20:42 -0700613 }
614 }
615
Dianne Hackborndd913a52010-07-22 12:17:04 -0700616 public int commit() {
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700617 return commitInternal(false);
618 }
619
620 public int commitAllowingStateLoss() {
621 return commitInternal(true);
622 }
George Mountd4c3c912014-06-09 12:31:34 -0700623
Adam Powell8585ed62016-02-04 15:38:20 -0800624 @Override
625 public void commitNow() {
626 disallowAddToBackStack();
627 mManager.execSingleAction(this, false);
628 }
629
630 @Override
631 public void commitNowAllowingStateLoss() {
632 disallowAddToBackStack();
633 mManager.execSingleAction(this, true);
634 }
635
George Mounteca8e222016-07-07 13:13:05 -0700636 @Override
637 public FragmentTransaction setAllowOptimization(boolean allowOptimization) {
638 mAllowOptimization = allowOptimization;
639 return this;
640 }
641
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700642 int commitInternal(boolean allowStateLoss) {
George Mountd4c3c912014-06-09 12:31:34 -0700643 if (mCommitted) {
644 throw new IllegalStateException("commit already called");
645 }
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700646 if (FragmentManagerImpl.DEBUG) {
647 Log.v(TAG, "Commit: " + this);
648 LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700649 PrintWriter pw = new FastPrintWriter(logw, false, 1024);
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700650 dump(" ", null, pw, null);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700651 pw.flush();
Dianne Hackbornf43a33c2012-09-27 00:48:11 -0700652 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700653 mCommitted = true;
Dianne Hackborndd913a52010-07-22 12:17:04 -0700654 if (mAddToBackStack) {
655 mIndex = mManager.allocBackStackIndex(this);
656 } else {
657 mIndex = -1;
658 }
Dianne Hackbornab36acb2010-11-05 14:12:11 -0700659 mManager.enqueueAction(this, allowStateLoss);
Dianne Hackborndd913a52010-07-22 12:17:04 -0700660 return mIndex;
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700661 }
George Mountd4c3c912014-06-09 12:31:34 -0700662
George Mounteca8e222016-07-07 13:13:05 -0700663 /**
George Mount86bfc662016-07-12 16:06:06 -0700664 * Implementation of {@link android.app.FragmentManagerImpl.OpGenerator}.
George Mounteca8e222016-07-07 13:13:05 -0700665 * This operation is added to the list of pending actions during {@link #commit()}, and
666 * will be executed on the UI thread to run this FragmentTransaction.
667 *
668 * @param records Modified to add this BackStackRecord
669 * @param isRecordPop Modified to add a false (this isn't a pop)
670 * @return true always because the records and isRecordPop will always be changed
671 */
672 @Override
673 public boolean generateOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop) {
George Mountd4c3c912014-06-09 12:31:34 -0700674 if (FragmentManagerImpl.DEBUG) {
675 Log.v(TAG, "Run: " + this);
676 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700677
George Mounteca8e222016-07-07 13:13:05 -0700678 records.add(this);
679 isRecordPop.add(false);
Dianne Hackborndd913a52010-07-22 12:17:04 -0700680 if (mAddToBackStack) {
George Mounteca8e222016-07-07 13:13:05 -0700681 mManager.addBackStackState(this);
Dianne Hackborndd913a52010-07-22 12:17:04 -0700682 }
George Mounteca8e222016-07-07 13:13:05 -0700683 return true;
684 }
Dianne Hackborndd913a52010-07-22 12:17:04 -0700685
George Mount86bfc662016-07-12 16:06:06 -0700686 boolean interactsWith(int containerId) {
687 final int numOps = mOps.size();
688 for (int opNum = 0; opNum < numOps; opNum++) {
689 final Op op = mOps.get(opNum);
690 if (op.fragment.mContainerId == containerId) {
691 return true;
692 }
693 }
694 return false;
695 }
696
697 boolean interactsWith(ArrayList<BackStackRecord> records, int startIndex, int endIndex) {
698 if (endIndex == startIndex) {
699 return false;
700 }
701 final int numOps = mOps.size();
702 int lastContainer = -1;
703 for (int opNum = 0; opNum < numOps; opNum++) {
704 final Op op = mOps.get(opNum);
705 final int container = op.fragment.mContainerId;
706 if (container != 0 && container != lastContainer) {
707 lastContainer = container;
708 for (int i = startIndex; i < endIndex; i++) {
709 BackStackRecord record = records.get(i);
710 final int numThoseOps = record.mOps.size();
711 for (int thoseOpIndex = 0; thoseOpIndex < numThoseOps; thoseOpIndex++) {
712 final Op thatOp = record.mOps.get(thoseOpIndex);
713 if (thatOp.fragment.mContainerId == container) {
714 return true;
715 }
716 }
717 }
718 }
719 }
720 return false;
721 }
722
George Mounteca8e222016-07-07 13:13:05 -0700723 /**
724 * Executes the operations contained within this transaction. The Fragment states will only
725 * be modified if optimizations are not allowed.
726 */
727 void executeOps() {
George Mountf2045f82016-06-27 13:15:01 -0700728 final int numOps = mOps.size();
729 for (int opNum = 0; opNum < numOps; opNum++) {
730 final Op op = mOps.get(opNum);
George Mounteca8e222016-07-07 13:13:05 -0700731 final Fragment f = op.fragment;
George Mount86bfc662016-07-12 16:06:06 -0700732 f.setNextTransition(mTransition, mTransitionStyle);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700733 switch (op.cmd) {
George Mountf2045f82016-06-27 13:15:01 -0700734 case OP_ADD:
George Mount86bfc662016-07-12 16:06:06 -0700735 f.setNextAnim(op.enterAnim);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700736 mManager.addFragment(f, false);
George Mountf2045f82016-06-27 13:15:01 -0700737 break;
738 case OP_REMOVE:
George Mount86bfc662016-07-12 16:06:06 -0700739 f.setNextAnim(op.exitAnim);
George Mounteca8e222016-07-07 13:13:05 -0700740 mManager.removeFragment(f);
George Mountf2045f82016-06-27 13:15:01 -0700741 break;
742 case OP_HIDE:
George Mount86bfc662016-07-12 16:06:06 -0700743 f.setNextAnim(op.exitAnim);
George Mounteca8e222016-07-07 13:13:05 -0700744 mManager.hideFragment(f);
George Mountf2045f82016-06-27 13:15:01 -0700745 break;
746 case OP_SHOW:
George Mount86bfc662016-07-12 16:06:06 -0700747 f.setNextAnim(op.enterAnim);
George Mounteca8e222016-07-07 13:13:05 -0700748 mManager.showFragment(f);
George Mountf2045f82016-06-27 13:15:01 -0700749 break;
750 case OP_DETACH:
George Mount86bfc662016-07-12 16:06:06 -0700751 f.setNextAnim(op.exitAnim);
George Mounteca8e222016-07-07 13:13:05 -0700752 mManager.detachFragment(f);
George Mountf2045f82016-06-27 13:15:01 -0700753 break;
754 case OP_ATTACH:
George Mount86bfc662016-07-12 16:06:06 -0700755 f.setNextAnim(op.enterAnim);
George Mounteca8e222016-07-07 13:13:05 -0700756 mManager.attachFragment(f);
George Mountf2045f82016-06-27 13:15:01 -0700757 break;
758 default:
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700759 throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700760 }
George Mounteca8e222016-07-07 13:13:05 -0700761 if (!mAllowOptimization && op.cmd != OP_ADD) {
762 mManager.moveFragmentToExpectedState(f);
763 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700764 }
George Mounteca8e222016-07-07 13:13:05 -0700765 if (!mAllowOptimization) {
766 // Added fragments are added at the end to comply with prior behavior.
767 mManager.moveToState(mManager.mCurState);
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700768 }
769 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700770
George Mounteca8e222016-07-07 13:13:05 -0700771 /**
772 * Reverses the execution of the operations within this transaction. The Fragment states will
773 * only be modified if optimizations are not allowed.
774 */
775 void executePopOps() {
776 for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
George Mountf2045f82016-06-27 13:15:01 -0700777 final Op op = mOps.get(opNum);
George Mounteca8e222016-07-07 13:13:05 -0700778 Fragment f = op.fragment;
George Mount86bfc662016-07-12 16:06:06 -0700779 f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
George Mounteca8e222016-07-07 13:13:05 -0700780 switch (op.cmd) {
781 case OP_ADD:
George Mount86bfc662016-07-12 16:06:06 -0700782 f.setNextAnim(op.popExitAnim);
George Mounteca8e222016-07-07 13:13:05 -0700783 mManager.removeFragment(f);
784 break;
785 case OP_REMOVE:
George Mount86bfc662016-07-12 16:06:06 -0700786 f.setNextAnim(op.popEnterAnim);
George Mounteca8e222016-07-07 13:13:05 -0700787 mManager.addFragment(f, false);
788 break;
789 case OP_HIDE:
George Mount86bfc662016-07-12 16:06:06 -0700790 f.setNextAnim(op.popEnterAnim);
George Mounteca8e222016-07-07 13:13:05 -0700791 mManager.showFragment(f);
792 break;
793 case OP_SHOW:
George Mount86bfc662016-07-12 16:06:06 -0700794 f.setNextAnim(op.popExitAnim);
George Mounteca8e222016-07-07 13:13:05 -0700795 mManager.hideFragment(f);
796 break;
797 case OP_DETACH:
George Mount86bfc662016-07-12 16:06:06 -0700798 f.setNextAnim(op.popEnterAnim);
George Mounteca8e222016-07-07 13:13:05 -0700799 mManager.attachFragment(f);
800 break;
801 case OP_ATTACH:
George Mount86bfc662016-07-12 16:06:06 -0700802 f.setNextAnim(op.popExitAnim);
George Mounteca8e222016-07-07 13:13:05 -0700803 mManager.detachFragment(f);
804 break;
805 default:
806 throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
807 }
808 if (!mAllowOptimization && op.cmd != OP_ADD) {
809 mManager.moveFragmentToExpectedState(f);
George Mountf2045f82016-06-27 13:15:01 -0700810 }
811 }
George Mounteca8e222016-07-07 13:13:05 -0700812 if (!mAllowOptimization) {
813 mManager.moveToState(mManager.mCurState);
George Mountf2045f82016-06-27 13:15:01 -0700814 }
George Mounteca8e222016-07-07 13:13:05 -0700815 }
George Mountf2045f82016-06-27 13:15:01 -0700816
George Mounteca8e222016-07-07 13:13:05 -0700817 /**
818 * Removes all OP_REPLACE ops and replaces them with the proper add and remove
819 * operations that are equivalent to the replace. This must be called prior to
820 * {@link #executeOps()} or any other call that operations on mOps.
821 *
822 * @param added Initialized to the fragments that are in the mManager.mAdded, this
823 * will be modified to contain the fragments that will be in mAdded
824 * after the execution ({@link #executeOps()}.
825 */
826 void expandReplaceOps(ArrayList<Fragment> added) {
George Mountf2045f82016-06-27 13:15:01 -0700827 for (int opNum = 0; opNum < mOps.size(); opNum++) {
828 final Op op = mOps.get(opNum);
829 switch (op.cmd) {
830 case OP_ADD:
831 case OP_ATTACH:
832 added.add(op.fragment);
George Mount86bfc662016-07-12 16:06:06 -0700833 break;
George Mountf2045f82016-06-27 13:15:01 -0700834 case OP_REMOVE:
835 case OP_DETACH:
836 added.remove(op.fragment);
837 break;
838 case OP_REPLACE: {
839 Fragment f = op.fragment;
840 int containerId = f.mContainerId;
841 boolean alreadyAdded = false;
842 for (int i = added.size() - 1; i >= 0; i--) {
843 Fragment old = added.get(i);
844 if (old.mContainerId == containerId) {
845 if (old == f) {
846 alreadyAdded = true;
847 } else {
848 Op removeOp = new Op();
849 removeOp.cmd = OP_REMOVE;
850 removeOp.fragment = old;
851 removeOp.enterAnim = op.enterAnim;
852 removeOp.popEnterAnim = op.popEnterAnim;
853 removeOp.exitAnim = op.exitAnim;
854 removeOp.popExitAnim = op.popExitAnim;
855 mOps.add(opNum, removeOp);
856 added.remove(old);
857 opNum++;
858 }
859 }
860 }
861 if (alreadyAdded) {
862 mOps.remove(opNum);
863 opNum--;
864 } else {
865 op.cmd = OP_ADD;
866 added.add(f);
867 }
868 }
869 break;
870 }
871 }
872 }
873
George Mount86bfc662016-07-12 16:06:06 -0700874 boolean isPostponed() {
875 for (int opNum = 0; opNum < mOps.size(); opNum++) {
George Mountf2045f82016-06-27 13:15:01 -0700876 final Op op = mOps.get(opNum);
George Mount86bfc662016-07-12 16:06:06 -0700877 if (isFragmentPostponed(op)) {
George Mountc855f7d2015-06-10 15:00:17 -0700878 return true;
879 }
880 }
881 return false;
882 }
883
George Mount86bfc662016-07-12 16:06:06 -0700884 void setOnStartPostponedListener(Fragment.OnStartEnterTransitionListener listener) {
885 for (int opNum = 0; opNum < mOps.size(); opNum++) {
886 final Op op = mOps.get(opNum);
887 if (isFragmentPostponed(op)) {
888 op.fragment.setOnStartEnterTransitionListener(listener);
George Mount61f83312015-09-09 16:10:29 -0700889 }
890 }
891 }
892
George Mount86bfc662016-07-12 16:06:06 -0700893 private static boolean isFragmentPostponed(Op op) {
894 final Fragment fragment = op.fragment;
895 return (fragment.mAdded && fragment.mView != null && !fragment.mDetached &&
896 !fragment.mHidden && fragment.isPostponed());
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700897 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700898
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700899 public String getName() {
900 return mName;
901 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700902
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700903 public int getTransition() {
904 return mTransition;
905 }
Dianne Hackbornc6669ca2010-09-16 01:33:24 -0700906
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700907 public int getTransitionStyle() {
908 return mTransitionStyle;
909 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700910
911 public boolean isEmpty() {
George Mountf2045f82016-06-27 13:15:01 -0700912 return mOps.isEmpty();
Adam Powell2b6230e2010-09-07 17:55:25 -0700913 }
Dianne Hackborn5ae74d62010-05-19 19:14:57 -0700914}