Fix saveWhileAnimatingAway() local test failures

FragmentAnimatorTest saveWhileAnimatingAway() test can fail locally
because of animations ending before asserts can be reached.

We should not wait 2 cycles after executing pending transactions on the
FragmentManager. Executing pending transactions forces the animation to
begin and by waiting 2 cycles, it is given a chance to end. Instead,
after we executing pending transactions, we should ensure animations
have been started, then do our asserts. This ensures that even if the
animations were to run with a duration of 0, we still would do our
asserts before the fragment gets marked as inactive. So we should no
longer have to rely on timing for this test to be successful.

Test: all tests pass
FIXES: 138798649
Change-Id: I43f44c535f02ca8af19dce5c787542a7a22f6284
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
index 5d7c1ac..ea6aeef 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
@@ -433,26 +433,26 @@
 
         val fm1 = fc1.supportFragmentManager
 
-        val fragment1 = StrictViewFragment(R.layout.scene1)
+        val fragment1 = AnimationListenerFragment(R.layout.scene1)
         fm1.beginTransaction()
             .add(R.id.fragmentContainer, fragment1, "1")
             .commit()
         activityRule.waitForExecution()
 
-        val fragment2 = StrictViewFragment()
+        val fragment2 = AnimationListenerFragment()
 
         fm1.beginTransaction()
             .setCustomAnimations(0, 0, 0, R.anim.long_fade_out)
             .replace(R.id.fragmentContainer, fragment2, "2")
             .addToBackStack(null)
             .commit()
-        instrumentation.runOnMainSync { fm1.executePendingTransactions() }
-        activityRule.waitForExecution()
+        activityRule.executePendingTransactions(fm1)
 
         fm1.popBackStack()
-
-        instrumentation.runOnMainSync { fm1.executePendingTransactions() }
-        activityRule.waitForExecution()
+        activityRule.executePendingTransactions(fm1)
+        // ensure the animation was started
+        assertThat(fragment2.startAnimationLatch.await(1000, TimeUnit.MILLISECONDS))
+            .isTrue()
         // Now fragment2 should be animating away
         assertThat(fragment2.isAdded).isFalse()
         // still exists because it is animating
@@ -718,7 +718,9 @@
         }
     }
 
-    class AnimationListenerFragment : StrictViewFragment() {
+    class AnimationListenerFragment(
+        @LayoutRes contentLayoutId: Int = R.layout.strict_view_fragment
+    ) : StrictViewFragment(contentLayoutId) {
         lateinit var createdView: View
         var forceRunOnHwLayer: Boolean = false
         var repeat: Boolean = false
@@ -728,6 +730,7 @@
         var exitStartCount = 0
         var exitRepeatCount = 0
         var exitEndCount = 0
+        val startAnimationLatch = CountDownLatch(1)
         val enterLatch = CountDownLatch(1)
         val exitLatch = CountDownLatch(1)
 
@@ -770,6 +773,7 @@
                         } else {
                             exitStartCount++
                         }
+                        startAnimationLatch.countDown()
                     }
 
                     override fun onAnimationEnd(animation: Animation) {
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt
index c74f1f3..1478ed2 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimatorTest.kt
@@ -22,6 +22,7 @@
 import android.os.Build
 import android.view.View
 import androidx.annotation.AnimatorRes
+import androidx.annotation.LayoutRes
 import androidx.annotation.RequiresApi
 import androidx.core.view.ViewCompat
 import androidx.fragment.app.test.FragmentTestActivity
@@ -452,14 +453,14 @@
 
         val fm1 = fc1.supportFragmentManager
 
-        val fragment1 = StrictViewFragment(R.layout.scene1)
+        val fragment1 = AnimatorFragment(R.layout.scene1)
         fm1.beginTransaction()
             .add(R.id.fragmentContainer, fragment1, "1")
             .setReorderingAllowed(true)
             .commit()
         activityRule.waitForExecution()
 
-        val fragment2 = StrictViewFragment()
+        val fragment2 = AnimatorFragment()
 
         fm1.beginTransaction()
             .setCustomAnimations(0, 0, 0, R.animator.slow_fade_out)
@@ -468,12 +469,12 @@
             .setReorderingAllowed(true)
             .commit()
         activityRule.executePendingTransactions(fm1)
-        activityRule.waitForExecution()
 
         fm1.popBackStack()
 
         activityRule.executePendingTransactions(fm1)
-        activityRule.waitForExecution()
+        // ensure the animation was started
+        assertThat(fragment2.wasStarted).isTrue()
         // Now fragment2 should be animating away
         assertThat(fragment2.isAdded).isFalse()
         assertThat(fm1.findFragmentByTag("2"))
@@ -548,7 +549,8 @@
         assertThat(fragment.numAnimators).isEqualTo(expectedAnimators)
     }
 
-    class AnimatorFragment : StrictViewFragment() {
+    class AnimatorFragment(@LayoutRes contentLayoutId: Int = R.layout.strict_view_fragment) :
+        StrictViewFragment(contentLayoutId) {
         var numAnimators: Int = 0
         lateinit var baseAnimator: Animator
         var baseEnter: Boolean = false