Merge "Fix getting wrong instance when restoring non-config" into nyc-support-25.4-dev
diff --git a/fragment/java/android/support/v4/app/FragmentManager.java b/fragment/java/android/support/v4/app/FragmentManager.java
index 48e6698..e071de2 100644
--- a/fragment/java/android/support/v4/app/FragmentManager.java
+++ b/fragment/java/android/support/v4/app/FragmentManager.java
@@ -2806,7 +2806,15 @@
for (int i = 0; i < count; i++) {
Fragment f = nonConfigFragments.get(i);
if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f);
- FragmentState fs = fms.mActive[f.mIndex];
+ int index = 0; // index into fms.mActive
+ while (index < fms.mActive.length && fms.mActive[index].mIndex != f.mIndex) {
+ index++;
+ }
+ if (index == fms.mActive.length) {
+ throwException(new IllegalStateException("Could not find active fragment "
+ + "with index " + f.mIndex));
+ }
+ FragmentState fs = fms.mActive[index];
fs.mInstance = f;
f.mSavedViewState = null;
f.mBackStackNesting = 0;
diff --git a/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java b/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
index c9d7351..c6db19b 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
@@ -684,6 +684,52 @@
assertTrue(activity.onDestroyLatch.await(1000, TimeUnit.MILLISECONDS));
}
+ /**
+ * When a fragment is saved in non-config, it should be restored to the same index.
+ */
+ @Test
+ @UiThreadTest
+ public void restoreNonConfig() throws Throwable {
+ FragmentController fc = FragmentTestUtil.createController(mActivityRule);
+ FragmentTestUtil.resume(mActivityRule, fc, null);
+ FragmentManager fm = fc.getSupportFragmentManager();
+
+ Fragment fragment1 = new StrictFragment();
+ fm.beginTransaction()
+ .add(fragment1, "1")
+ .addToBackStack(null)
+ .commit();
+ fm.executePendingTransactions();
+ Fragment fragment2 = new StrictFragment();
+ fragment2.setRetainInstance(true);
+ fragment2.setTargetFragment(fragment1, 0);
+ Fragment fragment3 = new StrictFragment();
+ fm.beginTransaction()
+ .remove(fragment1)
+ .add(fragment2, "2")
+ .add(fragment3, "3")
+ .addToBackStack(null)
+ .commit();
+ fm.executePendingTransactions();
+
+ Pair<Parcelable, FragmentManagerNonConfig> savedState =
+ FragmentTestUtil.destroy(mActivityRule, fc);
+
+ fc = FragmentTestUtil.createController(mActivityRule);
+ FragmentTestUtil.resume(mActivityRule, fc, savedState);
+ boolean foundFragment2 = false;
+ for (Fragment fragment : fc.getSupportFragmentManager().getFragments()) {
+ if (fragment == fragment2) {
+ foundFragment2 = true;
+ assertNotNull(fragment.getTargetFragment());
+ assertEquals("1", fragment.getTargetFragment().getTag());
+ } else {
+ assertNotEquals("2", fragment.getTag());
+ }
+ }
+ assertTrue(foundFragment2);
+ }
+
private void assertAnimationsMatch(FragmentManager fm, int enter, int exit, int popEnter,
int popExit) {
FragmentManagerImpl fmImpl = (FragmentManagerImpl) fm;
diff --git a/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java b/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
index ff48420..9ee0c48 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
@@ -145,9 +145,10 @@
}
}
- public static FragmentController createController(ActivityTestRule<FragmentTestActivity> rule) {
+ public static FragmentController createController(
+ ActivityTestRule<? extends FragmentActivity> rule) {
final FragmentController[] controller = new FragmentController[1];
- final FragmentTestActivity activity = rule.getActivity();
+ final FragmentActivity activity = rule.getActivity();
runOnUiThreadRethrow(rule, new Runnable() {
@Override
public void run() {
diff --git a/fragment/tests/java/android/support/v4/app/HostCallbacks.java b/fragment/tests/java/android/support/v4/app/HostCallbacks.java
index 9a0ef1c..15698a6 100644
--- a/fragment/tests/java/android/support/v4/app/HostCallbacks.java
+++ b/fragment/tests/java/android/support/v4/app/HostCallbacks.java
@@ -16,20 +16,19 @@
package android.support.v4.app;
import android.os.Handler;
-import android.support.v4.app.test.FragmentTestActivity;
import android.view.LayoutInflater;
import android.view.View;
-class HostCallbacks extends FragmentHostCallback<FragmentTestActivity> {
- private final FragmentTestActivity mActivity;
+class HostCallbacks extends FragmentHostCallback<FragmentActivity> {
+ private final FragmentActivity mActivity;
- HostCallbacks(FragmentTestActivity activity, Handler handler, int windowAnimations) {
+ HostCallbacks(FragmentActivity activity, Handler handler, int windowAnimations) {
super(activity, handler, windowAnimations);
mActivity = activity;
}
@Override
- public FragmentTestActivity onGetHost() {
+ public FragmentActivity onGetHost() {
return mActivity;
}