Protect use of onFindViewById for Fragment Transitions.
am: 1780bc94be

Change-Id: I8d6c2de7ffb7a12631c5bb8ba880e5a9f1939426
diff --git a/fragment/java/android/support/v4/app/FragmentTransition.java b/fragment/java/android/support/v4/app/FragmentTransition.java
index 71ac889..5e0d9e3 100644
--- a/fragment/java/android/support/v4/app/FragmentTransition.java
+++ b/fragment/java/android/support/v4/app/FragmentTransition.java
@@ -186,7 +186,10 @@
     private static void configureTransitionsOptimized(FragmentManagerImpl fragmentManager,
             int containerId, FragmentContainerTransition fragments,
             View nonExistentView, ArrayMap<String, String> nameOverrides) {
-        ViewGroup sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+        ViewGroup sceneRoot = null;
+        if (fragmentManager.mContainer.onHasView()) {
+            sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+        }
         if (sceneRoot == null) {
             return;
         }
@@ -276,7 +279,10 @@
     private static void configureTransitionsUnoptimized(FragmentManagerImpl fragmentManager,
             int containerId, FragmentContainerTransition fragments,
             View nonExistentView, ArrayMap<String, String> nameOverrides) {
-        ViewGroup sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+        ViewGroup sceneRoot = null;
+        if (fragmentManager.mContainer.onHasView()) {
+            sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+        }
         if (sceneRoot == null) {
             return;
         }
diff --git a/fragment/tests/java/android/support/v4/app/FragmentViewTests.java b/fragment/tests/java/android/support/v4/app/FragmentViewTests.java
index 296c3f8..521eb84 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentViewTests.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentViewTests.java
@@ -32,6 +32,7 @@
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v4.app.test.FragmentTestActivity;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -942,6 +943,7 @@
     // Ensure that non-optimized transactions are executed individually rather than together.
     // This forces references from one fragment to another that should be executed earlier
     // to work.
+    @Test
     public void nonOptimizeTogether() throws Throwable {
         FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
         ViewGroup container = (ViewGroup)
@@ -973,6 +975,33 @@
         assertNotNull(findViewById(R.id.textA));
     }
 
+    // Ensure that there is no problem if the child fragment manager is used before
+    // the View has been added.
+    @Test
+    public void childFragmentManager() throws Throwable {
+        FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
+        ViewGroup container = (ViewGroup)
+                mActivityRule.getActivity().findViewById(R.id.fragmentContainer);
+        final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
+
+        final StrictViewFragment fragment1 = new ParentFragment();
+        fragment1.setLayoutId(R.layout.double_container);
+
+        fm.beginTransaction()
+                .add(R.id.fragmentContainer, fragment1)
+                .addToBackStack(null)
+                .commit();
+
+        FragmentTestUtil.executePendingTransactions(mActivityRule);
+
+        FragmentTestUtil.assertChildren(container, fragment1);
+        ViewGroup innerContainer = (ViewGroup)
+                fragment1.getView().findViewById(R.id.fragmentContainer1);
+
+        Fragment fragment2 = fragment1.getChildFragmentManager().findFragmentByTag("inner");
+        FragmentTestUtil.assertChildren(innerContainer, fragment2);
+    }
+
     private View findViewById(int viewId) {
         return mActivityRule.getActivity().findViewById(viewId);
     }
@@ -996,4 +1025,25 @@
             super.onViewCreated(view, savedInstanceState);
         }
     }
+
+    public static class ParentFragment extends StrictViewFragment {
+        public ParentFragment() {
+            setLayoutId(R.layout.double_container);
+        }
+
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                                 Bundle savedInstanceState) {
+            View view = super.onCreateView(inflater, container, savedInstanceState);
+            final StrictViewFragment fragment2 = new StrictViewFragment();
+            fragment2.setLayoutId(R.layout.fragment_a);
+
+            getChildFragmentManager().beginTransaction()
+                    .add(R.id.fragmentContainer1, fragment2, "inner")
+                    .addToBackStack(null)
+                    .commit();
+            getChildFragmentManager().executePendingTransactions();
+            return view;
+        }
+    }
 }