Enable clearing back stack while using intents

Provide a flag that can be used to know where the intent came from. If
it comes from Car Settings package, skip clearing the back stack.

Bug: 139803849
Test: manual, robolectric
Change-Id: I8343d12535c80681f8987d1250b8afec69403c37
Merged-In: I8343d12535c80681f8987d1250b8afec69403c37
diff --git a/src/com/android/car/settings/common/CarSettingActivity.java b/src/com/android/car/settings/common/CarSettingActivity.java
index 1a33ccc..d495dd7 100644
--- a/src/com/android/car/settings/common/CarSettingActivity.java
+++ b/src/com/android/car/settings/common/CarSettingActivity.java
@@ -18,6 +18,7 @@
 
 import android.content.Intent;
 import android.os.Bundle;
+import android.text.TextUtils;
 
 import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
@@ -65,7 +66,17 @@
         if (mHasNewIntent) {
             Fragment fragment = FragmentResolver.getFragmentForIntent(/* context= */ this,
                     getIntent());
-            launchIfDifferent(fragment);
+            if (fragment == null) {
+                LOG.w("Intent has no specified settings page. Defaulting to the root fragment");
+                fragment = getRootFragment();
+            }
+
+            if (!intentFromSettings(getIntent())) {
+                clearBackStack();
+                launchFragment(fragment);
+            } else {
+                launchIfDifferent(fragment);
+            }
             mHasNewIntent = false;
         }
     }
@@ -77,8 +88,7 @@
         if (fragment.getClass().getName().equals(
                 getString(R.string.config_settings_hierarchy_root_fragment))
                 && getSupportFragmentManager().getBackStackEntryCount() > 1) {
-            getSupportFragmentManager().popBackStackImmediate(/* name= */ null,
-                    FragmentManager.POP_BACK_STACK_INCLUSIVE);
+            clearBackStack();
         }
 
         super.launchFragment(fragment);
@@ -94,7 +104,21 @@
         if (getCurrentFragment() != null) {
             return getCurrentFragment();
         }
+        return getRootFragment();
+    }
+
+    private Fragment getRootFragment() {
         return Fragment.instantiate(this,
                 getString(R.string.config_settings_hierarchy_root_fragment));
     }
+
+    private void clearBackStack() {
+        getSupportFragmentManager().popBackStackImmediate(/* name= */ null,
+                FragmentManager.POP_BACK_STACK_INCLUSIVE);
+    }
+
+    private boolean intentFromSettings(Intent intent) {
+        String pkgName = intent.getStringExtra(Intent.EXTRA_CALLING_PACKAGE);
+        return TextUtils.equals(pkgName, getPackageName());
+    }
 }
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 09c464b..a0e2c3a 100644
--- a/tests/robotests/src/com/android/car/settings/common/CarSettingActivityTest.java
+++ b/tests/robotests/src/com/android/car/settings/common/CarSettingActivityTest.java
@@ -83,7 +83,36 @@
     }
 
     @Test
-    public void launchWithEmptyIntent_resolveToDefaultFragment() {
+    public void launchWithIntent_hasNoBackstack() {
+        MockitoAnnotations.initMocks(this);
+        Intent intent = new Intent(Settings.ACTION_DATE_SETTINGS);
+        CarSettingActivity activity =
+                Robolectric.buildActivity(CarSettingActivity.class, intent).setup().get();
+        assertThat(activity.getSupportFragmentManager().getBackStackEntryCount()).isEqualTo(1);
+    }
+
+    @Test
+    public void launchWithIntentFromExternalPackage_hasNoBackstack() {
+        MockitoAnnotations.initMocks(this);
+        Intent intent = new Intent(Settings.ACTION_DATE_SETTINGS);
+        intent.putExtra(Intent.EXTRA_CALLING_PACKAGE, "com.test.package");
+        CarSettingActivity activity =
+                Robolectric.buildActivity(CarSettingActivity.class, intent).setup().get();
+        assertThat(activity.getSupportFragmentManager().getBackStackEntryCount()).isEqualTo(1);
+    }
+
+    @Test
+    public void launchWithIntentFromSettings_hasBackstack() {
+        MockitoAnnotations.initMocks(this);
+        Intent intent = new Intent(Settings.ACTION_DATE_SETTINGS);
+        intent.putExtra(Intent.EXTRA_CALLING_PACKAGE, mContext.getPackageName());
+        CarSettingActivity activity =
+                Robolectric.buildActivity(CarSettingActivity.class, intent).setup().get();
+        assertThat(activity.getSupportFragmentManager().getBackStackEntryCount()).isEqualTo(2);
+    }
+
+    @Test
+    public void launchCarSettings_resolveToDefaultFragment() {
         CarSettingActivity activity =
                 Robolectric.buildActivity(CarSettingActivity.class).setup().get();
         assertThat(activity.getSupportFragmentManager().findFragmentById(R.id.fragment_container))
@@ -91,6 +120,16 @@
     }
 
     @Test
+    public void launchWithEmptyIntent_resolveToDefaultFragment() {
+        MockitoAnnotations.initMocks(this);
+        Intent intent = new Intent();
+        CarSettingActivity activity =
+                Robolectric.buildActivity(CarSettingActivity.class, intent).setup().get();
+        assertThat(activity.getSupportFragmentManager().findFragmentById(R.id.fragment_container))
+                .isInstanceOf(DummyFragment.class);
+    }
+
+    @Test
     public void onResume_newIntent_launchesNewFragment() {
         mActivityController.start().postCreate(null).resume();
         TestFragment testFragment = new TestFragment();