summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author George Mount <mount@google.com> 2016-08-01 21:44:50 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2016-08-01 21:44:52 +0000
commit921891518a7665cd4d286a356b3e26419e84d148 (patch)
tree6eefb3d4b25549fd9812abc89d27e43a889350d5
parent1b4ab52e248a4a6e9d53f0878024c81aeb561b20 (diff)
parentf2045f8f0c5c6aba96b6a4ed570cfcbe3e7e1d64 (diff)
Merge "Convert BackStackRecord Operations to ArrayList."
-rw-r--r--core/java/android/app/BackStackRecord.java355
1 files changed, 122 insertions, 233 deletions
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 199e9aa0f615..f4f8d6936247 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -54,39 +54,22 @@ final class BackStackState implements Parcelable {
final ArrayList<String> mSharedElementTargetNames;
public BackStackState(FragmentManagerImpl fm, BackStackRecord bse) {
- int numRemoved = 0;
- BackStackRecord.Op op = bse.mHead;
- while (op != null) {
- if (op.removed != null) {
- numRemoved += op.removed.size();
- }
- op = op.next;
- }
- mOps = new int[bse.mNumOp * 7 + numRemoved];
+ final int numOps = bse.mOps.size();
+ mOps = new int[numOps * 6];
if (!bse.mAddToBackStack) {
throw new IllegalStateException("Not on back stack");
}
- op = bse.mHead;
int pos = 0;
- while (op != null) {
+ for (int opNum = 0; opNum < numOps; opNum++) {
+ final BackStackRecord.Op op = bse.mOps.get(opNum);
mOps[pos++] = op.cmd;
mOps[pos++] = op.fragment != null ? op.fragment.mIndex : -1;
mOps[pos++] = op.enterAnim;
mOps[pos++] = op.exitAnim;
mOps[pos++] = op.popEnterAnim;
mOps[pos++] = op.popExitAnim;
- if (op.removed != null) {
- final int N = op.removed.size();
- mOps[pos++] = N;
- for (int i = 0; i < N; i++) {
- mOps[pos++] = op.removed.get(i).mIndex;
- }
- } else {
- mOps[pos++] = 0;
- }
- op = op.next;
}
mTransition = bse.mTransition;
mTransitionStyle = bse.mTransitionStyle;
@@ -136,18 +119,6 @@ final class BackStackState implements Parcelable {
op.exitAnim = mOps[pos++];
op.popEnterAnim = mOps[pos++];
op.popExitAnim = mOps[pos++];
- final int N = mOps[pos++];
- if (N > 0) {
- op.removed = new ArrayList<Fragment>(N);
- for (int i = 0; i < N; i++) {
- if (FragmentManagerImpl.DEBUG) {
- Log.v(FragmentManagerImpl.TAG,
- "Instantiate " + bse + " set remove fragment #" + mOps[pos]);
- }
- Fragment r = fm.mActive.get(mOps[pos++]);
- op.removed.add(r);
- }
- }
bse.mEnterAnim = op.enterAnim;
bse.mExitAnim = op.exitAnim;
bse.mPopEnterAnim = op.popEnterAnim;
@@ -219,20 +190,15 @@ final class BackStackRecord extends FragmentTransaction implements
static final int OP_ATTACH = 7;
static final class Op {
- Op next;
- Op prev;
int cmd;
Fragment fragment;
int enterAnim;
int exitAnim;
int popEnterAnim;
int popExitAnim;
- ArrayList<Fragment> removed;
}
- Op mHead;
- Op mTail;
- int mNumOp;
+ ArrayList<Op> mOps = new ArrayList<>();
int mEnterAnim;
int mExitAnim;
int mPopEnterAnim;
@@ -320,13 +286,13 @@ final class BackStackRecord extends FragmentTransaction implements
}
}
- if (mHead != null) {
+ if (!mOps.isEmpty()) {
writer.print(prefix);
writer.println("Operations:");
String innerPrefix = prefix + " ";
- Op op = mHead;
- int num = 0;
- while (op != null) {
+ final int numOps = mOps.size();
+ for (int opNum = 0; opNum < numOps; opNum++) {
+ final Op op = mOps.get(opNum);
String cmdStr;
switch (op.cmd) {
case OP_NULL:
@@ -359,7 +325,7 @@ final class BackStackRecord extends FragmentTransaction implements
}
writer.print(prefix);
writer.print(" Op #");
- writer.print(num);
+ writer.print(opNum);
writer.print(": ");
writer.print(cmdStr);
writer.print(" ");
@@ -380,25 +346,6 @@ final class BackStackRecord extends FragmentTransaction implements
writer.println(Integer.toHexString(op.popExitAnim));
}
}
- if (op.removed != null && op.removed.size() > 0) {
- for (int i = 0; i < op.removed.size(); i++) {
- writer.print(innerPrefix);
- if (op.removed.size() == 1) {
- writer.print("Removed: ");
- } else {
- if (i == 0) {
- writer.println("Removed:");
- }
- writer.print(innerPrefix);
- writer.print(" #");
- writer.print(i);
- writer.print(": ");
- }
- writer.println(op.removed.get(i));
- }
- }
- op = op.next;
- num++;
}
}
}
@@ -434,18 +381,11 @@ final class BackStackRecord extends FragmentTransaction implements
}
void addOp(Op op) {
- if (mHead == null) {
- mHead = mTail = op;
- } else {
- op.prev = mTail;
- mTail.next = op;
- mTail = op;
- }
+ mOps.add(op);
op.enterAnim = mEnterAnim;
op.exitAnim = mExitAnim;
op.popEnterAnim = mPopEnterAnim;
op.popExitAnim = mPopExitAnim;
- mNumOp++;
}
public FragmentTransaction add(Fragment fragment, String tag) {
@@ -660,8 +600,9 @@ final class BackStackRecord extends FragmentTransaction implements
Log.v(TAG, "Bump nesting in " + this
+ " by " + amt);
}
- Op op = mHead;
- while (op != null) {
+ final int numOps = mOps.size();
+ for (int opNum = 0; opNum < numOps; opNum++) {
+ final Op op = mOps.get(opNum);
if (op.fragment != null) {
op.fragment.mBackStackNesting += amt;
if (FragmentManagerImpl.DEBUG) {
@@ -669,17 +610,6 @@ final class BackStackRecord extends FragmentTransaction implements
+ op.fragment + " to " + op.fragment.mBackStackNesting);
}
}
- if (op.removed != null) {
- for (int i = op.removed.size() - 1; i >= 0; i--) {
- Fragment r = op.removed.get(i);
- r.mBackStackNesting += amt;
- if (FragmentManagerImpl.DEBUG) {
- Log.v(TAG, "Bump nesting of "
- + r + " to " + r.mBackStackNesting);
- }
- }
- }
- op = op.next;
}
}
@@ -735,6 +665,7 @@ final class BackStackRecord extends FragmentTransaction implements
}
}
+ expandReplaceOps();
bumpBackStackNesting(1);
if (mManager.mCurState >= Fragment.CREATED) {
@@ -744,88 +675,38 @@ final class BackStackRecord extends FragmentTransaction implements
beginTransition(firstOutFragments, lastInFragments, false);
}
- Op op = mHead;
- while (op != null) {
+ final int numOps = mOps.size();
+ for (int opNum = 0; opNum < numOps; opNum++) {
+ final Op op = mOps.get(opNum);
+ Fragment f = op.fragment;
switch (op.cmd) {
- case OP_ADD: {
- Fragment f = op.fragment;
+ case OP_ADD:
f.mNextAnim = op.enterAnim;
mManager.addFragment(f, false);
- }
- break;
- case OP_REPLACE: {
- Fragment f = op.fragment;
- int containerId = f.mContainerId;
- if (mManager.mAdded != null) {
- for (int i = mManager.mAdded.size() - 1; i >= 0; i--) {
- Fragment old = mManager.mAdded.get(i);
- if (FragmentManagerImpl.DEBUG) {
- Log.v(TAG,
- "OP_REPLACE: adding=" + f + " old=" + old);
- }
- if (old.mContainerId == containerId) {
- if (old == f) {
- op.fragment = f = null;
- } else {
- if (op.removed == null) {
- op.removed = new ArrayList<Fragment>();
- }
- op.removed.add(old);
- old.mNextAnim = op.exitAnim;
- if (mAddToBackStack) {
- old.mBackStackNesting += 1;
- if (FragmentManagerImpl.DEBUG) {
- Log.v(TAG, "Bump nesting of "
- + old + " to " + old.mBackStackNesting);
- }
- }
- mManager.removeFragment(old, mTransition, mTransitionStyle);
- }
- }
- }
- }
- if (f != null) {
- f.mNextAnim = op.enterAnim;
- mManager.addFragment(f, false);
- }
- }
- break;
- case OP_REMOVE: {
- Fragment f = op.fragment;
+ break;
+ case OP_REMOVE:
f.mNextAnim = op.exitAnim;
mManager.removeFragment(f, mTransition, mTransitionStyle);
- }
- break;
- case OP_HIDE: {
- Fragment f = op.fragment;
+ break;
+ case OP_HIDE:
f.mNextAnim = op.exitAnim;
mManager.hideFragment(f, mTransition, mTransitionStyle);
- }
- break;
- case OP_SHOW: {
- Fragment f = op.fragment;
+ break;
+ case OP_SHOW:
f.mNextAnim = op.enterAnim;
mManager.showFragment(f, mTransition, mTransitionStyle);
- }
- break;
- case OP_DETACH: {
- Fragment f = op.fragment;
+ break;
+ case OP_DETACH:
f.mNextAnim = op.exitAnim;
mManager.detachFragment(f, mTransition, mTransitionStyle);
- }
- break;
- case OP_ATTACH: {
- Fragment f = op.fragment;
+ break;
+ case OP_ATTACH:
f.mNextAnim = op.enterAnim;
mManager.attachFragment(f, mTransition, mTransitionStyle);
- }
- break;
- default: {
+ break;
+ default:
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
- }
}
-
- op = op.next;
}
mManager.moveToState(mManager.mCurState, mTransition,
@@ -836,6 +717,72 @@ final class BackStackRecord extends FragmentTransaction implements
}
}
+ private void expandReplaceOps() {
+ final int numOps = mOps.size();
+
+ boolean hasReplace = false;
+ // Before we do anything, check to see if any replace operations exist:
+ for (int opNum = 0; opNum < numOps; opNum++) {
+ final Op op = mOps.get(opNum);
+ if (op.cmd == OP_REPLACE) {
+ hasReplace = true;
+ break;
+ }
+ }
+
+ if (!hasReplace) {
+ return; // nothing to expand
+ }
+
+ ArrayList<Fragment> added = (mManager.mAdded == null) ? new ArrayList<Fragment>() :
+ new ArrayList<>(mManager.mAdded);
+ for (int opNum = 0; opNum < mOps.size(); opNum++) {
+ final Op op = mOps.get(opNum);
+ switch (op.cmd) {
+ case OP_ADD:
+ case OP_ATTACH:
+ added.add(op.fragment);
+ break;
+ case OP_REMOVE:
+ case OP_DETACH:
+ added.remove(op.fragment);
+ break;
+ case OP_REPLACE: {
+ Fragment f = op.fragment;
+ int containerId = f.mContainerId;
+ boolean alreadyAdded = false;
+ for (int i = added.size() - 1; i >= 0; i--) {
+ Fragment old = added.get(i);
+ if (old.mContainerId == containerId) {
+ if (old == f) {
+ alreadyAdded = true;
+ } else {
+ Op removeOp = new Op();
+ removeOp.cmd = OP_REMOVE;
+ removeOp.fragment = old;
+ removeOp.enterAnim = op.enterAnim;
+ removeOp.popEnterAnim = op.popEnterAnim;
+ removeOp.exitAnim = op.exitAnim;
+ removeOp.popExitAnim = op.popExitAnim;
+ mOps.add(opNum, removeOp);
+ added.remove(old);
+ opNum++;
+ }
+ }
+ }
+ if (alreadyAdded) {
+ mOps.remove(opNum);
+ opNum--;
+ } else {
+ op.cmd = OP_ADD;
+ added.add(f);
+ }
+ }
+ break;
+ }
+ }
+ }
+
private static void setFirstOut(SparseArray<Fragment> firstOutFragments,
SparseArray<Fragment> lastInFragments, Fragment fragment) {
if (fragment != null) {
@@ -891,30 +838,13 @@ final class BackStackRecord extends FragmentTransaction implements
if (!mManager.mContainer.onHasView()) {
return; // nothing to see, so no transitions
}
- Op op = mHead;
- while (op != null) {
+ final int numOps = mOps.size();
+ for (int opNum = 0; opNum < numOps; opNum++) {
+ final Op op = mOps.get(opNum);
switch (op.cmd) {
case OP_ADD:
setLastIn(firstOutFragments, lastInFragments, op.fragment);
break;
- case OP_REPLACE: {
- Fragment f = op.fragment;
- if (mManager.mAdded != null) {
- for (int i = 0; i < mManager.mAdded.size(); i++) {
- Fragment old = mManager.mAdded.get(i);
- if (f == null || old.mContainerId == f.mContainerId) {
- if (old == f) {
- f = null;
- lastInFragments.remove(old.mContainerId);
- } else {
- setFirstOut(firstOutFragments, lastInFragments, old);
- }
- }
- }
- }
- setLastIn(firstOutFragments, lastInFragments, op.fragment);
- break;
- }
case OP_REMOVE:
setFirstOut(firstOutFragments, lastInFragments, op.fragment);
break;
@@ -931,8 +861,6 @@ final class BackStackRecord extends FragmentTransaction implements
setLastIn(firstOutFragments, lastInFragments, op.fragment);
break;
}
-
- op = op.next;
}
}
@@ -950,20 +878,13 @@ final class BackStackRecord extends FragmentTransaction implements
if (!mManager.mContainer.onHasView()) {
return; // nothing to see, so no transitions
}
- Op op = mTail;
- while (op != null) {
+ final int numOps = mOps.size();
+ for (int opNum = numOps - 1; opNum >= 0; opNum--) {
+ final Op op = mOps.get(opNum);
switch (op.cmd) {
case OP_ADD:
setFirstOut(firstOutFragments, lastInFragments, op.fragment);
break;
- case OP_REPLACE:
- if (op.removed != null) {
- for (int i = op.removed.size() - 1; i >= 0; i--) {
- setLastIn(firstOutFragments, lastInFragments, op.removed.get(i));
- }
- }
- setFirstOut(firstOutFragments, lastInFragments, op.fragment);
- break;
case OP_REMOVE:
setLastIn(firstOutFragments, lastInFragments, op.fragment);
break;
@@ -980,8 +901,6 @@ final class BackStackRecord extends FragmentTransaction implements
setFirstOut(firstOutFragments, lastInFragments, op.fragment);
break;
}
-
- op = op.prev;
}
}
@@ -1691,74 +1610,44 @@ final class BackStackRecord extends FragmentTransaction implements
bumpBackStackNesting(-1);
- Op op = mTail;
- while (op != null) {
+ final int numOps = mOps.size();
+ for (int opNum = numOps - 1; opNum >= 0; opNum--) {
+ final Op op = mOps.get(opNum);
+ Fragment f = op.fragment;
switch (op.cmd) {
- case OP_ADD: {
- Fragment f = op.fragment;
+ case OP_ADD:
f.mNextAnim = op.popExitAnim;
mManager.removeFragment(f,
FragmentManagerImpl.reverseTransit(mTransition),
mTransitionStyle);
- }
- break;
- case OP_REPLACE: {
- Fragment f = op.fragment;
- if (f != null) {
- f.mNextAnim = op.popExitAnim;
- mManager.removeFragment(f,
- FragmentManagerImpl.reverseTransit(mTransition),
- mTransitionStyle);
- }
- if (op.removed != null) {
- for (int i = 0; i < op.removed.size(); i++) {
- Fragment old = op.removed.get(i);
- old.mNextAnim = op.popEnterAnim;
- mManager.addFragment(old, false);
- }
- }
- }
- break;
- case OP_REMOVE: {
- Fragment f = op.fragment;
+ break;
+ case OP_REMOVE:
f.mNextAnim = op.popEnterAnim;
mManager.addFragment(f, false);
- }
- break;
- case OP_HIDE: {
- Fragment f = op.fragment;
+ break;
+ case OP_HIDE:
f.mNextAnim = op.popEnterAnim;
mManager.showFragment(f,
FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
- }
- break;
- case OP_SHOW: {
- Fragment f = op.fragment;
+ break;
+ case OP_SHOW:
f.mNextAnim = op.popExitAnim;
mManager.hideFragment(f,
FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
- }
- break;
- case OP_DETACH: {
- Fragment f = op.fragment;
+ break;
+ case OP_DETACH:
f.mNextAnim = op.popEnterAnim;
mManager.attachFragment(f,
FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
- }
- break;
- case OP_ATTACH: {
- Fragment f = op.fragment;
+ break;
+ case OP_ATTACH:
f.mNextAnim = op.popExitAnim;
mManager.detachFragment(f,
FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle);
- }
- break;
- default: {
+ break;
+ default:
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
- }
}
-
- op = op.prev;
}
if (doStateMove) {
@@ -1845,7 +1734,7 @@ final class BackStackRecord extends FragmentTransaction implements
}
public boolean isEmpty() {
- return mNumOp == 0;
+ return mOps.isEmpty();
}
public class TransitionState {