Don't destroy Fragments without calling initState()

The only place where keepActive was used was
when a Fragment was animating to the destroyed
state and then it was re-added before the
animation completes resulting in a Fragment that
had its Lifecycle destroyed and, due to keepActive,
did not have its Lifecycle/other state reset
via initState(). This can leave the Fragment in
an inconsistent state and breaks the invariant
around destroyed being a terminal state for a
Lifecycle object.

Instead, we can cancel the animation where it
is and proceed from that state (since that's a
known valid state). This also allows us to
remove the keepActive flag entirely, simplifying
the logic.

Test: all tests still pass
Change-Id: I3bd86e8c99936835c905a0241d90daf1941159bd
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentLayoutInflaterFactory.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentLayoutInflaterFactory.java
index 469e1ed..91842df 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentLayoutInflaterFactory.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentLayoutInflaterFactory.java
@@ -125,7 +125,7 @@
         // at the right phase of the lifecycle so that we will have mView populated
         // for compliant fragments below.
         if (mFragmentManager.mCurState < Fragment.CREATED && fragment.mFromLayout) {
-            mFragmentManager.moveToState(fragment, Fragment.CREATED, false);
+            mFragmentManager.moveToState(fragment, Fragment.CREATED);
         } else {
             mFragmentManager.moveToState(fragment);
         }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
index 2dce59b..8c06e17 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
@@ -1156,7 +1156,7 @@
                 return;
             }
             f.mDeferStart = false;
-            moveToState(f, mCurState, false);
+            moveToState(f, mCurState);
         }
     }
 
@@ -1165,7 +1165,7 @@
     }
 
     @SuppressWarnings("ReferenceEquality")
-    void moveToState(Fragment f, int newState, boolean keepActive) {
+    void moveToState(Fragment f, int newState) {
         // Fragments that are not currently added will sit in the onCreate() state.
         if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
             newState = Fragment.CREATED;
@@ -1201,11 +1201,9 @@
             if (f.mState < newState && (f.getAnimatingAway() != null || f.getAnimator() != null)) {
                 // The fragment is currently being animated...  but!  Now we
                 // want to move our state back up.  Give up on waiting for the
-                // animation, move to whatever the final state should be once
-                // the animation is done, and then we can proceed from there.
+                // animation and proceed from where we are.
                 f.setAnimatingAway(null);
                 f.setAnimator(null);
-                moveToState(f, f.getStateAfterAnimating(), true);
             }
             switch (f.mState) {
                 case Fragment.INITIALIZING:
@@ -1252,7 +1250,7 @@
                                         + " that does not belong to this FragmentManager!");
                             }
                             if (f.mTarget.mState < Fragment.CREATED) {
-                                moveToState(f.mTarget, Fragment.CREATED, true);
+                                moveToState(f.mTarget, Fragment.CREATED);
                             }
                             f.mTargetWho = f.mTarget.mWho;
                             f.mTarget = null;
@@ -1265,7 +1263,7 @@
                                         + " that does not belong to this FragmentManager!");
                             }
                             if (target.mState < Fragment.CREATED) {
-                                moveToState(target, Fragment.CREATED, true);
+                                moveToState(target, Fragment.CREATED);
                             }
                         }
 
@@ -1472,21 +1470,19 @@
 
                             f.performDetach();
                             dispatchOnFragmentDetached(f, false);
-                            if (!keepActive) {
-                                if (beingRemoved || mNonConfig.shouldDestroy(f)) {
-                                    makeInactive(f);
-                                } else {
-                                    f.mHost = null;
-                                    f.mParentFragment = null;
-                                    f.mFragmentManager = null;
-                                    if (f.mTargetWho != null) {
-                                        Fragment target = mActive.get(f.mTargetWho);
-                                        if (target != null && target.getRetainInstance()) {
-                                            // Only keep references to other retained Fragments
-                                            // to avoid developers accessing Fragments that
-                                            // are never coming back
-                                            f.mTarget = target;
-                                        }
+                            if (beingRemoved || mNonConfig.shouldDestroy(f)) {
+                                makeInactive(f);
+                            } else {
+                                f.mHost = null;
+                                f.mParentFragment = null;
+                                f.mFragmentManager = null;
+                                if (f.mTargetWho != null) {
+                                    Fragment target = mActive.get(f.mTargetWho);
+                                    if (target != null && target.getRetainInstance()) {
+                                        // Only keep references to other retained Fragments
+                                        // to avoid developers accessing Fragments that
+                                        // are never coming back
+                                        f.mTarget = target;
                                     }
                                 }
                             }
@@ -1536,7 +1532,7 @@
                             if (fragment.getAnimatingAway() != null) {
                                 fragment.setAnimatingAway(null);
                                 destroyFragmentView(fragment);
-                                moveToState(fragment, fragment.getStateAfterAnimating(), false);
+                                moveToState(fragment, fragment.getStateAfterAnimating());
                             }
                         }
                     });
@@ -1560,7 +1556,7 @@
                     fragment.setAnimator(null);
                     if (animator != null && container.indexOfChild(viewToAnimate) < 0) {
                         destroyFragmentView(fragment);
-                        moveToState(fragment, fragment.getStateAfterAnimating(), false);
+                        moveToState(fragment, fragment.getStateAfterAnimating());
                     }
                 }
             });
@@ -1583,7 +1579,7 @@
     }
 
     void moveToState(Fragment f) {
-        moveToState(f, mCurState, false);
+        moveToState(f, mCurState);
     }
 
     private void ensureInflatedFragmentView(Fragment f) {
@@ -1687,7 +1683,7 @@
                 nextState = Math.min(nextState, Fragment.INITIALIZING);
             }
         }
-        moveToState(f, nextState, false);
+        moveToState(f, nextState);
 
         if (f.mView != null) {
             // Move the view if it is out of order
@@ -2516,7 +2512,7 @@
         for (int i = 0; i < numAdded; i++) {
             Fragment fragment = mAdded.get(i);
             if (fragment.mState < state) {
-                moveToState(fragment, state, false);
+                moveToState(fragment, state);
                 if (fragment.mView != null && !fragment.mHidden && fragment.mIsNewlyAdded) {
                     added.add(fragment);
                 }
@@ -2555,7 +2551,7 @@
                     }
                     fragment.setAnimatingAway(null);
                     destroyFragmentView(fragment);
-                    moveToState(fragment, stateAfterAnimating, false);
+                    moveToState(fragment, stateAfterAnimating);
                 } else if (fragment.getAnimator() != null) {
                     fragment.getAnimator().end();
                 }
@@ -2882,9 +2878,9 @@
                 // We need to ensure that onDestroy and any other clean up is done
                 // so move the Fragment up to CREATED, then mark it as being removed, then
                 // destroy it.
-                moveToState(f, Fragment.CREATED, false);
+                moveToState(f, Fragment.CREATED);
                 f.mRemoving = true;
-                moveToState(f, Fragment.INITIALIZING, false);
+                moveToState(f, Fragment.INITIALIZING);
                 continue;
             }
             fs.mInstance = f;
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java
index 80fdf8e..ddd481d 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransition.java
@@ -1196,7 +1196,7 @@
             if (fragment.mState < Fragment.CREATED && manager.mCurState >= Fragment.CREATED
                     && !transaction.mReorderingAllowed) {
                 manager.makeActive(fragment);
-                manager.moveToState(fragment, Fragment.CREATED, false);
+                manager.moveToState(fragment, Fragment.CREATED);
             }
         }
         if (setFirstOut && (containerTransition == null || containerTransition.firstOut == null)) {