Clean up open dialogs on quick settings triggering

Bug: 131717514
Test: manual + robolectric
Change-Id: I672f1d6f4f2ec554a363383778ccb7380fca8170
Merged-In: I672f1d6f4f2ec554a363383778ccb7380fca8170
diff --git a/src/com/android/car/settings/common/CarSettingActivity.java b/src/com/android/car/settings/common/CarSettingActivity.java
index a01a8c2..94b1606 100644
--- a/src/com/android/car/settings/common/CarSettingActivity.java
+++ b/src/com/android/car/settings/common/CarSettingActivity.java
@@ -21,11 +21,14 @@
 import android.text.TextUtils;
 
 import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 
 import com.android.car.settings.R;
 
+import java.util.List;
+
 /**
  * Root activity used for most of the Settings app. This activity provides additional functionality
  * which handles intents.
@@ -75,9 +78,8 @@
     public void launchFragment(Fragment fragment) {
         // Called before super to clear the back stack if necessary before launching the fragment
         // in question.
-        if (fragment.getClass().getName().equals(
-                getString(R.string.config_settings_hierarchy_root_fragment))
-                && getSupportFragmentManager().getBackStackEntryCount() > 1) {
+        if (isRootFragmentRequiringCleanup(fragment)) {
+            cleanUpOrphanedDialogs();
             clearBackStack();
         }
 
@@ -125,4 +127,22 @@
         String pkgName = intent.getStringExtra(Intent.EXTRA_CALLING_PACKAGE);
         return TextUtils.equals(pkgName, getPackageName());
     }
+
+    private boolean isRootFragmentRequiringCleanup(Fragment fragment) {
+        boolean isRoot = fragment.getClass().getName().equals(
+                getString(R.string.config_settings_hierarchy_root_fragment));
+        boolean requiresCleanup = getSupportFragmentManager().getBackStackEntryCount() > 1;
+        return isRoot && requiresCleanup;
+    }
+
+    private void cleanUpOrphanedDialogs() {
+        List<Fragment> fragments = getSupportFragmentManager().getFragments();
+        if (fragments != null) {
+            for (Fragment fragment : fragments) {
+                if (fragment instanceof DialogFragment) {
+                    ((DialogFragment) fragment).dismiss();
+                }
+            }
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/car/settings/common/CarSettingActivityTest.java b/tests/robotests/src/com/android/car/settings/common/CarSettingActivityTest.java
index 4be2167..47a1327 100644
--- a/tests/robotests/src/com/android/car/settings/common/CarSettingActivityTest.java
+++ b/tests/robotests/src/com/android/car/settings/common/CarSettingActivityTest.java
@@ -20,6 +20,8 @@
 
 import static org.mockito.Mockito.when;
 
+import android.app.AlertDialog;
+import android.app.Dialog;
 import android.car.Car;
 import android.car.drivingstate.CarUxRestrictions;
 import android.car.drivingstate.CarUxRestrictionsManager;
@@ -28,6 +30,9 @@
 import android.os.Bundle;
 import android.provider.Settings;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
 import androidx.fragment.app.Fragment;
 
 import com.android.car.settings.CarSettingsRobolectricTestRunner;
@@ -49,8 +54,6 @@
 @RunWith(CarSettingsRobolectricTestRunner.class)
 public class CarSettingActivityTest {
 
-    private static final String TEST_TAG = "test_tag";
-
     private Context mContext;
     private ActivityController<CarSettingActivity> mActivityController;
     private CarSettingActivity mActivity;
@@ -70,7 +73,7 @@
         mContext = RuntimeEnvironment.application;
         mActivityController = ActivityController.of(new CarSettingActivity());
         mActivity = mActivityController.get();
-        mActivityController.create();
+        mActivityController.setup();
     }
 
     @Test
@@ -133,7 +136,7 @@
     @Test
     public void onResume_newIntent_launchesNewFragment() {
         Robolectric.getForegroundThreadScheduler().unPause();
-        mActivityController.start().postCreate(null).resume();
+
         TestFragment testFragment = new TestFragment();
         mActivity.launchFragment(testFragment);
         assertThat(mActivity.getCurrentFragment()).isEqualTo(testFragment);
@@ -146,7 +149,6 @@
 
     @Test
     public void onResume_savedInstanceState_doesNotLaunchFragmentFromOldIntent() {
-        mActivityController.start().postCreate(null).resume();
         Intent intent = new Intent(Settings.ACTION_DATE_SETTINGS);
         mActivity.onNewIntent(intent);
         assertThat(mActivity.getCurrentFragment()).isNotInstanceOf(TestFragment.class);
@@ -204,7 +206,47 @@
                 .isEqualTo(1);
     }
 
+    @Test
+    public void launchFragment_rootFragment_dismissesDialogs() {
+        Robolectric.getForegroundThreadScheduler().unPause();
+
+        // Add fragment 1
+        TestFragment testFragment1 = new TestFragment();
+        mActivity.launchFragment(testFragment1);
+
+        // Show dialog 1
+        String tag1 = "tag1";
+        TestDialogFragment testDialogFragment1 = new TestDialogFragment();
+        testDialogFragment1.show(mActivity.getSupportFragmentManager(), tag1);
+
+        // Show dialog 2
+        String tag2 = "tag2";
+        TestDialogFragment testDialogFragment2 = new TestDialogFragment();
+        testDialogFragment2.show(mActivity.getSupportFragmentManager(), tag2);
+
+        assertThat(mActivity.getSupportFragmentManager().findFragmentByTag(tag1)).isNotNull();
+        assertThat(mActivity.getSupportFragmentManager().findFragmentByTag(tag2)).isNotNull();
+
+        // Add root fragment
+        Fragment root = Fragment.instantiate(mContext,
+                mContext.getString(R.string.config_settings_hierarchy_root_fragment));
+        mActivity.launchFragment(root);
+
+        assertThat(mActivity.getSupportFragmentManager().findFragmentByTag(tag1)).isNull();
+        assertThat(mActivity.getSupportFragmentManager().findFragmentByTag(tag2)).isNull();
+    }
+
     /** Simple Fragment for testing use. */
     public static class TestFragment extends Fragment {
     }
+
+    /** Simple Dialog Fragment for testing use. */
+    public static class TestDialogFragment extends DialogFragment {
+
+        @NonNull
+        @Override
+        public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+            return new AlertDialog.Builder(getContext()).setTitle("Test Dialog").create();
+        }
+    }
 }