Merge "Fix saving target fragment when Fragment not yet created." into oc-dev
diff --git a/tests/fragment/src/android/fragment/cts/FragmentLifecycleTest.java b/tests/fragment/src/android/fragment/cts/FragmentLifecycleTest.java
index fbd6d01..a0d38e1 100644
--- a/tests/fragment/src/android/fragment/cts/FragmentLifecycleTest.java
+++ b/tests/fragment/src/android/fragment/cts/FragmentLifecycleTest.java
@@ -808,6 +808,45 @@
         });
     }
 
+    /**
+     * When a fragment has been optimized out, it state should still be saved during
+     * save and restore instance state.
+     */
+    @Test
+    public void saveRemovedFragment() throws Throwable {
+        mActivityRule.runOnUiThread(() -> {
+            FragmentController fc = FragmentTestUtil.createController(mActivityRule);
+            FragmentTestUtil.resume(mActivityRule, fc, null);
+            FragmentManager fm = fc.getFragmentManager();
+
+            SaveStateFragment fragment1 = SaveStateFragment.create(1);
+            fm.beginTransaction()
+                    .add(android.R.id.content, fragment1, "1")
+                    .addToBackStack(null)
+                    .commit();
+            SaveStateFragment fragment2 = SaveStateFragment.create(2);
+            fm.beginTransaction()
+                    .replace(android.R.id.content, fragment2, "2")
+                    .addToBackStack(null)
+                    .commit();
+            fm.executePendingTransactions();
+
+            Pair<Parcelable, FragmentManagerNonConfig> savedState =
+                    FragmentTestUtil.destroy(mActivityRule, fc);
+
+            fc = FragmentTestUtil.createController(mActivityRule);
+            FragmentTestUtil.resume(mActivityRule, fc, savedState);
+            fm = fc.getFragmentManager();
+            fragment2 = (SaveStateFragment) fm.findFragmentByTag("2");
+            assertNotNull(fragment2);
+            assertEquals(2, fragment2.getValue());
+            fm.popBackStackImmediate();
+            fragment1 = (SaveStateFragment) fm.findFragmentByTag("1");
+            assertNotNull(fragment1);
+            assertEquals(1, fragment1.getValue());
+        });
+    }
+
     private void executePendingTransactions(final FragmentManager fm) throws Throwable {
         mActivityRule.runOnUiThread(new Runnable() {
             @Override
@@ -974,4 +1013,33 @@
             return (w != null && w.peekDecorView() != null);
         }
     }
+
+    public static class SaveStateFragment extends Fragment {
+        private static final String VALUE_KEY = "SaveStateFragment.mValue";
+        private int mValue;
+
+        public static SaveStateFragment create(int value) {
+            SaveStateFragment saveStateFragment = new SaveStateFragment();
+            saveStateFragment.mValue = value;
+            return saveStateFragment;
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+            outState.putInt(VALUE_KEY, mValue);
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            if (savedInstanceState != null) {
+                mValue = savedInstanceState.getInt(VALUE_KEY, mValue);
+            }
+        }
+
+        public int getValue() {
+            return mValue;
+        }
+    }
 }
diff --git a/tests/fragment/src/android/fragment/cts/FragmentOptimizationTest.java b/tests/fragment/src/android/fragment/cts/FragmentOptimizationTest.java
index 253bbcb..f91eb65 100644
--- a/tests/fragment/src/android/fragment/cts/FragmentOptimizationTest.java
+++ b/tests/fragment/src/android/fragment/cts/FragmentOptimizationTest.java
@@ -163,7 +163,7 @@
         assertEquals(1, fragment1.onHideCount);
         assertEquals(0, fragment1.onShowCount);
         assertEquals(0, fragment1.onDetachCount);
-        assertEquals(0, fragment1.onAttachCount);
+        assertEquals(1, fragment1.onAttachCount);
 
         FragmentTestUtil.popBackStackImmediate(mActivityRule, id[0],
                 FragmentManager.POP_BACK_STACK_INCLUSIVE);
@@ -171,8 +171,8 @@
         assertEquals(0, fragment1.onCreateViewCount);
         assertEquals(1, fragment1.onHideCount);
         assertEquals(1, fragment1.onShowCount);
-        assertEquals(0, fragment1.onDetachCount);
-        assertEquals(0, fragment1.onAttachCount);
+        assertEquals(1, fragment1.onDetachCount);
+        assertEquals(1, fragment1.onAttachCount);
     }
 
     // Ensure that removing and adding the same view results in no operation