Restart or finish HomepageActivity when it's launched unexpectedly

Settings homepage should be started with the flag FLAG_ACTIVITY_NEW_TASK
to ensure it's the first activity in a task. Otherwise, there will be UI
issues.

When homepage is started with FLAG_ACTIVITY_NEW_TASK but not the first
activity, it means another homepage activity has been started, so
finishing the current invocation will bring up the previous activity in
the task.

On the other hand, when homapage is not started with the flag and not
the first activty, it indicates that the invocation is from another
app. Restarting the homepage activity with FLAG_ACTIVITY_NEW_TASK will
keep the UI behavior consistent.

Fix: 297857732
Fix: 309045575
Test: robotest, manual
  1. Start Settings from QuickSettings, go to any subpage, navigate to
     home, click Settings icon on the launcher, and the previously
     opened page should be kept.
  2. On a LS device, start Settings from another app without
     FLAG_ACTIVITY_NEW_TASK, Settings should be started in dual-pane
     mode.
Change-Id: If1f31e26dc37f681bd97c185cbeac2de06bdd48f
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 8016799..48d918c 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -194,8 +194,12 @@
         if (unprovisioned) {
             Log.e(TAG, "Device is not provisioned, exiting Settings");
             finish();
+            return;
         }
 
+        // Settings homepage should be the task root, otherwise there will be UI issues.
+        boolean isTaskRoot = isTaskRoot();
+
         mIsEmbeddingActivityEnabled = ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this);
         if (mIsEmbeddingActivityEnabled) {
             final UserManager um = getSystemService(UserManager.class);
@@ -211,13 +215,34 @@
                 } else {
                     intent.setPackage(getPackageName());
                 }
-                intent.removeFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                if (!isTaskRoot) {
+                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                } else {
+                    intent.removeFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                }
                 startActivityAsUser(intent, um.getProfileParent(userInfo.id).getUserHandle());
                 finish();
                 return;
             }
         }
 
+        if (!isTaskRoot) {
+            if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+                Log.i(TAG, "Activity has been started, finishing");
+            } else {
+                Log.i(TAG, "Homepage should be started with FLAG_ACTIVITY_NEW_TASK, restarting");
+                Intent intent = new Intent(getIntent())
+                        .setPackage(getPackageName())
+                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                                | Intent.FLAG_ACTIVITY_FORWARD_RESULT)
+                        .putExtra(EXTRA_USER_HANDLE, getUser())
+                        .putExtra(EXTRA_INITIAL_REFERRER, getCurrentReferrer());
+                startActivity(intent);
+            }
+            finish();
+            return;
+        }
+
         setupEdgeToEdge();
         setContentView(R.layout.settings_homepage_container);
 
diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
index 0d1ee9c..4c2d745 100644
--- a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
@@ -24,11 +24,13 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -241,6 +243,42 @@
                 & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
     }
 
+    @Test
+    public void onCreate_TaskRoot_shouldNotFinish() {
+        SettingsHomepageActivity activity =
+                spy(Robolectric.buildActivity(SettingsHomepageActivity.class).get());
+        doReturn(true).when(activity).isTaskRoot();
+
+        activity.onCreate(/* savedInstanceState */ null);
+
+        verify(activity, never()).finish();
+    }
+
+    @Test
+    public void onCreate_notTaskRoot_shouldRestartActivity() {
+        SettingsHomepageActivity activity =
+                spy(Robolectric.buildActivity(SettingsHomepageActivity.class).get());
+        doReturn(false).when(activity).isTaskRoot();
+
+        activity.onCreate(/* savedInstanceState */ null);
+
+        verify(activity).finish();
+        verify(activity).startActivity(any(Intent.class));
+    }
+
+    @Test
+    public void onCreate_notTaskRoot_flagNewTask_shouldOnlyFinish() {
+        SettingsHomepageActivity activity =
+                spy(Robolectric.buildActivity(SettingsHomepageActivity.class).get());
+        doReturn(false).when(activity).isTaskRoot();
+        activity.setIntent(new Intent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+
+        activity.onCreate(/* savedInstanceState */ null);
+
+        verify(activity).finish();
+        verify(activity, never()).startActivity(any(Intent.class));
+    }
+
     /** This test is for large screen devices Activity embedding. */
     @Test
     @Config(shadows = ShadowActivityEmbeddingUtils.class)