[go: nahoru, domu]

Merge "Add check to only invalidate options menu when contributing menu items" into androidx-main
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerInflatedFragmentTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerInflatedFragmentTest.kt
index 81cf605..0366a45 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerInflatedFragmentTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerInflatedFragmentTest.kt
@@ -212,7 +212,13 @@
     }
 }
 
-class SimpleContainerActivity : FragmentActivity(R.layout.simple_container)
+class SimpleContainerActivity : FragmentActivity(R.layout.simple_container) {
+    var invalidateCount = 0
+    override fun invalidateMenu() {
+        invalidateCount++
+        super.invalidateMenu()
+    }
+}
 
 class ContainerViewActivity : FragmentActivity(R.layout.inflated_fragment_container_view) {
     var foundFragment = false
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/OptionsMenuFragmentTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/OptionsMenuFragmentTest.kt
index 27a4ec9..eb41633 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/OptionsMenuFragmentTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/OptionsMenuFragmentTest.kt
@@ -37,6 +37,7 @@
 import androidx.test.filters.SmallTest
 import androidx.testutils.withActivity
 import androidx.testutils.withUse
+import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
@@ -62,9 +63,13 @@
 
     @Test
     fun fragmentWithOptionsMenu() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val fragment = MenuFragment()
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
         fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment)
             .commit()
@@ -72,16 +77,29 @@
 
         assertWithMessage("Fragment should have an options menu")
             .that(fragment.hasOptionsMenu()).isTrue()
+        assertWithMessage("Adding fragment with options menu should invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(2)
         assertWithMessage("Child fragments should not have an options menu")
             .that(fragment.mChildFragmentManager.checkForMenus()).isFalse()
+
+        fm.beginTransaction()
+            .remove(fragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage("Removing fragment with options menu should invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(3)
     }
 
     @LargeTest
     @Test
     fun setMenuVisibilityShowHide() {
        withUse(ActivityScenario.launch(SimpleContainerActivity::class.java)) {
-            val fm = withActivity { supportFragmentManager }
+           withActivity {
+               /** Internal call to [SimpleContainerActivity.invalidateMenu] from [SimpleContainerActivity.addMenuProvider] upon activity creation */
+               assertThat(invalidateCount).isEqualTo(1)
+           }
 
+            val fm = withActivity { supportFragmentManager }
             val fragment = MenuFragment()
 
             withActivity {
@@ -93,10 +111,17 @@
             assertWithMessage("Fragment should have an options menu")
                 .that(fragment.hasOptionsMenu()).isTrue()
 
+           withActivity {
+               assertWithMessage("Adding fragment with options menu should invalidate menu")
+                   .that(invalidateCount).isEqualTo(2)
+           }
+
             withActivity {
                 fm.beginTransaction()
                     .hide(fragment)
                     .commitNow()
+                assertWithMessage("Hiding fragment with options menu should invalidate menu")
+                    .that(invalidateCount).isEqualTo(3)
             }
 
             fragment.>
@@ -105,19 +130,34 @@
                 fm.beginTransaction()
                     .show(fragment)
                     .commitNow()
+                assertWithMessage("Showing fragment with options menu should invalidate menu")
+                    .that(invalidateCount).isEqualTo(4)
             }
 
             assertWithMessage("onCreateOptionsMenu was not called")
                 .that(fragment.onCreateOptionsMenuCountDownLatch.await(1000, TimeUnit.MILLISECONDS))
                 .isTrue()
+
+           withActivity {
+               fm.beginTransaction()
+                   .remove(fragment)
+                   .commitNow()
+               executePendingTransactions()
+               assertWithMessage("Removing fragment with options menu should invalidate menu")
+                   .that(invalidateCount).isEqualTo(5)
+           }
         }
     }
 
     @Test
     fun fragmentWithNoOptionsMenu() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val fragment = StrictViewFragment()
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
         fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment)
             .commit()
@@ -125,15 +165,29 @@
 
         assertWithMessage("Fragment should not have an options menu")
             .that(fragment.hasOptionsMenu()).isFalse()
+        assertWithMessage("Adding fragment without options menu should not invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(1)
         assertWithMessage("Child fragments should not have an options menu")
             .that(fragment.mChildFragmentManager.checkForMenus()).isFalse()
+
+        fm.beginTransaction()
+            .remove(fragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertThat(activity.invalidateCount).isEqualTo(1)
+        assertWithMessage("Removing fragment without options menu should not invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(1)
     }
 
     @Test
     fun childFragmentWithOptionsMenu() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val parent = ParentOptionsMenuFragment()
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
         fm.beginTransaction()
             .add(R.id.fragmentContainer, parent, "parent")
             .commit()
@@ -143,13 +197,37 @@
             .that(parent.hasOptionsMenu()).isFalse()
         assertWithMessage("Child fragment should have an options menu")
             .that(parent.mChildFragmentManager.checkForMenus()).isTrue()
+        assertWithMessage(
+            "Adding child fragment with options menu and parent fragment " +
+                "without should invalidate menu only once"
+        ).that(activity.invalidateCount).isEqualTo(2)
+
+        parent.mChildFragmentManager.beginTransaction()
+            .remove(parent.childFragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing child fragment with options menu should invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
+
+        fm.beginTransaction()
+            .remove(parent)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing parent fragment without options menu should not invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
     }
 
     @Test
     fun childFragmentWithOptionsMenuParentMenuVisibilityFalse() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val parent = ParentOptionsMenuFragment()
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
 
         parent.setMenuVisibility(false)
         fm.beginTransaction()
@@ -161,19 +239,43 @@
             .that(parent.hasOptionsMenu()).isFalse()
         assertWithMessage("Child fragment should have an options menu")
             .that(parent.childFragmentManager.checkForMenus()).isTrue()
+        assertWithMessage(
+            "Adding child fragment with options menu and parent fragment " +
+                "without should invalidate menu only once"
+        ).that(activity.invalidateCount).isEqualTo(2)
 
         activityRule.runOnUiThread {
             assertWithMessage("child fragment onCreateOptions menu was not called")
                 .that(parent.childFragment.onCreateOptionsMenuCountDownLatch.count)
                 .isEqualTo(1)
         }
+
+        parent.mChildFragmentManager.beginTransaction()
+            .remove(parent.childFragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing child fragment with options menu should invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
+
+        fm.beginTransaction()
+            .remove(parent)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing parent fragment without options menu should not invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
     }
 
     @Test
     fun childFragmentWithPrepareOptionsMenuParentMenuVisibilityFalse() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val parent = ParentOptionsMenuFragment()
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
 
         parent.setMenuVisibility(false)
         fm.beginTransaction()
@@ -185,19 +287,43 @@
             .that(parent.hasOptionsMenu()).isFalse()
         assertWithMessage("Child fragment should have an options menu")
             .that(parent.childFragmentManager.checkForMenus()).isTrue()
+        assertWithMessage(
+            "Adding child fragment with options menu and parent fragment " +
+                "without should invalidate menu only once"
+        ).that(activity.invalidateCount).isEqualTo(2)
 
         activityRule.runOnUiThread {
             assertWithMessage("child fragment onCreateOptions menu was not called")
                 .that(parent.childFragment.onPrepareOptionsMenuCountDownLatch.count)
                 .isEqualTo(1)
         }
+
+        parent.mChildFragmentManager.beginTransaction()
+            .remove(parent.childFragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing child fragment with options menu should invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
+
+        fm.beginTransaction()
+            .remove(parent)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing parent fragment without options menu should not invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
     }
 
     @Test
     fun parentAndChildFragmentWithOptionsMenu() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val parent = ParentOptionsMenuFragment(true)
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
         fm.beginTransaction()
             .add(R.id.fragmentContainer, parent, "parent")
             .commit()
@@ -207,47 +333,108 @@
             .that(parent.hasOptionsMenu()).isTrue()
         assertWithMessage("Child fragment should have an options menu")
             .that(parent.mChildFragmentManager.checkForMenus()).isTrue()
+        assertWithMessage(
+            "Adding parent and child fragment both with options menu should invalidate menu twice"
+        ).that(activity.invalidateCount).isEqualTo(3)
+
+        parent.mChildFragmentManager.beginTransaction()
+            .remove(parent.childFragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing child fragment with options menu should invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(4)
+
+        fm.beginTransaction()
+            .remove(parent)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing parent fragment with options menu should invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(5)
     }
 
     @Test
     fun grandchildFragmentWithOptionsMenu() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
-        val parent = StrictViewFragment(R.layout.double_container)
-        val fm = activityRule.activity.supportFragmentManager
+        val grandParent = StrictViewFragment(R.layout.double_container)
+        val fm = activity.supportFragmentManager
         fm.beginTransaction()
-            .add(R.id.fragmentContainer, parent, "parent")
+            .add(R.id.fragmentContainer, grandParent, "grandParent")
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Adding grandparent fragment without options menu should not invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(1)
+
+        val parent = ParentOptionsMenuFragment()
+        grandParent.childFragmentManager.beginTransaction()
+            .add(R.id.fragmentContainer1, parent)
             .commit()
         activityRule.executePendingTransactions()
 
-        parent.childFragmentManager.beginTransaction()
-            .add(R.id.fragmentContainer1, ParentOptionsMenuFragment())
-            .commit()
-        activityRule.executePendingTransactions()
-
-        assertWithMessage("Fragment should not have an options menu")
-            .that(parent.hasOptionsMenu()).isFalse()
+        assertWithMessage("Parent fragment should not have an options menu")
+            .that(grandParent.hasOptionsMenu()).isFalse()
         assertWithMessage("Grandchild fragment should have an options menu")
-            .that(parent.mChildFragmentManager.checkForMenus()).isTrue()
+            .that(grandParent.mChildFragmentManager.checkForMenus()).isTrue()
+        assertWithMessage(
+            "Adding grandchild fragment with options menu and " +
+            "parent fragment without should invalidate menu only once"
+        ).that(activity.invalidateCount).isEqualTo(2)
+
+        parent.mChildFragmentManager.beginTransaction()
+            .remove(parent.childFragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing grandchild fragment with options menu should invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
+
+        grandParent.mChildFragmentManager.beginTransaction()
+            .remove(parent)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing parent fragment without options menu should not invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
+
+        fm.beginTransaction()
+            .remove(grandParent)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing grandparent fragment without options menu should not invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
     }
 
     // Ensure that we check further than just the first child fragment
     @Test
     fun secondChildFragmentWithOptionsMenu() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val parent = StrictViewFragment(R.layout.double_container)
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
         fm.beginTransaction()
             .add(R.id.fragmentContainer, parent, "parent")
             .commit()
         activityRule.executePendingTransactions()
 
+        val childWithoutMenu = Fragment()
         parent.childFragmentManager.beginTransaction()
-            .add(R.id.fragmentContainer1, Fragment())
+            .add(R.id.fragmentContainer1, childWithoutMenu)
             .commit()
         activityRule.executePendingTransactions()
 
+        val childWithMenu = MenuFragment()
         parent.childFragmentManager.beginTransaction()
-            .add(R.id.fragmentContainer2, MenuFragment())
+            .add(R.id.fragmentContainer2, childWithMenu)
             .commit()
         activityRule.executePendingTransactions()
 
@@ -255,76 +442,156 @@
             .that(parent.hasOptionsMenu()).isFalse()
         assertWithMessage("Second child fragment should have an options menu")
             .that(parent.mChildFragmentManager.checkForMenus()).isTrue()
+        assertWithMessage(
+            "Adding second child fragment with options menu and the parent and " +
+                "first child fragments without should invalidate menu only once"
+        ).that(activity.invalidateCount).isEqualTo(2)
+
+        parent.mChildFragmentManager.beginTransaction()
+            .remove(childWithoutMenu)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing first child fragment without options menu should not invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(2)
+
+        parent.mChildFragmentManager.beginTransaction()
+            .remove(childWithMenu)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing second child fragment with options menu should invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
+
+        fm.beginTransaction()
+            .remove(parent)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage(
+            "Removing parent fragment without options menu should not invalidate menu"
+        ).that(activity.invalidateCount).isEqualTo(3)
     }
 
     @Test
     fun onPrepareOptionsMenu() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val fragment = MenuFragment()
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
         fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment)
             .commit()
         activityRule.executePendingTransactions()
+        assertWithMessage("Adding fragment with options menu should invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(2)
 
-        openActionBarOverflowOrOptionsMenu(activityRule.activity.applicationContext)
+        openActionBarOverflowOrOptionsMenu(activity.applicationContext)
         onView(ViewMatchers.withText("Item1")).perform(ViewActions.click())
         assertWithMessage("onPrepareOptionsMenu was not called")
             .that(fragment.onPrepareOptionsMenuCountDownLatch.await(1000, TimeUnit.MILLISECONDS))
             .isTrue()
+
+        fm.beginTransaction()
+            .remove(fragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage("Removing fragment with options menu should invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(3)
     }
 
     @Test
     fun inflatesMenu() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val fragment = MenuFragment()
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
         fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment)
             .commit()
         activityRule.executePendingTransactions()
+        assertWithMessage("Adding fragment with options menu should invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(2)
 
-        openActionBarOverflowOrOptionsMenu(activityRule.activity.applicationContext)
+        openActionBarOverflowOrOptionsMenu(activity.applicationContext)
         onView(ViewMatchers.withText("Item1"))
             .check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
         onView(ViewMatchers.withText("Item2"))
             .check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
+
+        fm.beginTransaction()
+            .remove(fragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage("Removing fragment with options menu should invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(3)
     }
 
     @Test
     fun menuItemSelected() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val fragment = MenuFragment()
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
         fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment)
             .commit()
         activityRule.executePendingTransactions()
+        assertWithMessage("Adding fragment with options menu should invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(2)
 
-        openActionBarOverflowOrOptionsMenu(activityRule.activity.applicationContext)
+        openActionBarOverflowOrOptionsMenu(activity.applicationContext)
         onView(ViewMatchers.withText("Item1")).perform(ViewActions.click())
 
-        openActionBarOverflowOrOptionsMenu(activityRule.activity.applicationContext)
+        openActionBarOverflowOrOptionsMenu(activity.applicationContext)
         onView(ViewMatchers.withText("Item2")).perform(ViewActions.click())
+
+        fm.beginTransaction()
+            .remove(fragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage("Removing fragment with options menu should invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(3)
     }
 
     @Test
     fun onOptionsMenuClosed() {
+        val activity = activityRule.getActivity()
+        /** Internal call to [FragmentTestActivity.invalidateMenu] from [FragmentTestActivity.addMenuProvider] upon activity creation */
+        assertThat(activity.invalidateCount).isEqualTo(1)
+
         activityRule.setContentView(R.layout.simple_container)
         val fragment = MenuFragment()
-        val fm = activityRule.activity.supportFragmentManager
+        val fm = activity.supportFragmentManager
         fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment)
             .commit()
         activityRule.executePendingTransactions()
+        assertWithMessage("Adding fragment with options menu should invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(2)
 
-        openActionBarOverflowOrOptionsMenu(activityRule.activity.applicationContext)
+        openActionBarOverflowOrOptionsMenu(activity.applicationContext)
         activityRule.runOnUiThread {
-            activityRule.activity.closeOptionsMenu()
+            activity.closeOptionsMenu()
         }
         assertWithMessage("onOptionsMenuClosed was not called")
             .that(fragment.onOptionsMenuClosedCountDownLatch.await(1000, TimeUnit.MILLISECONDS))
             .isTrue()
+
+        fm.beginTransaction()
+            .remove(fragment)
+            .commit()
+        activityRule.executePendingTransactions()
+        assertWithMessage("Removing fragment with options menu should invalidate menu")
+            .that(activity.invalidateCount).isEqualTo(3)
     }
 
     @Suppress("DEPRECATION")
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/FragmentTestActivity.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/FragmentTestActivity.kt
index 6e80faa..ccc564c 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/FragmentTestActivity.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/FragmentTestActivity.kt
@@ -31,6 +31,7 @@
 class FragmentTestActivity : FragmentActivity(R.layout.activity_content) {
 
     val finishCountDownLatch = CountDownLatch(1)
+    var invalidateCount = 0
 
     override fun finish() {
         super.finish()
@@ -44,6 +45,11 @@
             .commitNow()
     }
 
+    override fun invalidateMenu() {
+        invalidateCount++
+        super.invalidateMenu()
+    }
+
     class ParentFragment : Fragment() {
         var wasAttachedInTime: Boolean = false
 
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
index c373049..be8ae42 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
@@ -390,7 +390,7 @@
     @SuppressWarnings("DeprecatedIsStillUsed")
     @Deprecated
     public void supportInvalidateOptionsMenu() {
-        invalidateOptionsMenu();
+        invalidateMenu();
     }
 
     /**
@@ -753,7 +753,7 @@
 
         @Override
         public void invalidateMenu() {
-            FragmentActivity.this.invalidateOptionsMenu();
+            FragmentActivity.this.invalidateMenu();
         }
     }
 
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 c84669f..01d5094 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
@@ -3007,7 +3007,7 @@
             onPictureInPictureModeChangedProvider.removeOnPictureInPictureModeChangedListener(
                     mOnPictureInPictureModeChangedListener);
         }
-        if (mHost instanceof MenuHost) {
+        if (mHost instanceof MenuHost && mParent == null) {
             ((MenuHost) mHost).removeMenuProvider(mMenuProvider);
         }
         mHost = null;