diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 7723a469aaa92..fb87576ba809c 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -192,6 +192,7 @@ class ActivityStarter { private Task mInTask; private TaskFragment mInTaskFragment; + private TaskFragment mAddingToTaskFragment; @VisibleForTesting boolean mAddingToTask; @@ -2254,20 +2255,27 @@ class ActivityStarter { // In this situation we want to remove all activities from the task up to the one // being started. In most cases this means we are resetting the task to its initial // state. - final ActivityRecord top = targetTask.performClearTop(mStartActivity, mLaunchFlags); + final ActivityRecord clearTop = targetTask.performClearTop(mStartActivity, + mLaunchFlags); - if (top != null) { - if (top.isRootOfTask()) { + if (clearTop != null && !clearTop.finishing) { + if (clearTop.isRootOfTask()) { // Activity aliases may mean we use different intents for the top activity, // so make sure the task now has the identity of the new intent. - top.getTask().setIntent(mStartActivity); + clearTop.getTask().setIntent(mStartActivity); } - deliverNewIntent(top, intentGrants); + deliverNewIntent(clearTop, intentGrants); } else { // A special case: we need to start the activity because it is not currently // running, and the caller has asked to clear the current task to have this // activity at the top. mAddingToTask = true; + // Adding the new activity to the same embedded TF of the clear-top activity if + // possible. + if (clearTop != null && clearTop.getTaskFragment() != null + && clearTop.getTaskFragment().isEmbedded()) { + mAddingToTaskFragment = clearTop.getTaskFragment(); + } if (targetTask.getRootTask() == null) { // Target root task got cleared when we all activities were removed above. // Go ahead and reset it. @@ -2892,14 +2900,19 @@ class ActivityStarter { newParent = mInTaskFragment; } } else { - final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */, - false /* includingEmbeddedTask */); - final TaskFragment taskFragment = top != null ? top.getTaskFragment() : null; - if (taskFragment != null && taskFragment.isEmbedded() - && canEmbedActivity(taskFragment, mStartActivity, false /* newTask */, task)) { + TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null; + if (candidateTf == null) { + final ActivityRecord top = task.topRunningActivity(false /* focusableOnly */, + false /* includingEmbeddedTask */); + if (top != null) { + candidateTf = top.getTaskFragment(); + } + } + if (candidateTf != null && candidateTf.isEmbedded() + && canEmbedActivity(candidateTf, mStartActivity, false /* newTask */, task)) { // Use the embedded TaskFragment of the top activity as the new parent if the // activity can be embedded. - newParent = top.getTaskFragment(); + newParent = candidateTf; } } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 1bec2a5d68fa3..bf5246f2339a2 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1644,7 +1644,7 @@ class Task extends TaskFragment { * activities on top of it and return the instance. * * @param newR Description of the new activity being started. - * @return Returns the old activity that should be continued to be used, + * @return Returns the existing activity in the task that performs the clear-top operation, * or {@code null} if none was found. */ private ActivityRecord clearTopActivities(ActivityRecord newR, int launchFlags) { @@ -1663,7 +1663,6 @@ class Task extends TaskFragment { && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) { if (!r.finishing) { r.finishIfPossible("clear-task-top", false /* oomAdj */); - return null; } } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java index 9304761fc1c96..202168bae869a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java @@ -266,7 +266,7 @@ public class TaskTests extends WindowTestsBase { // Detach from process so the activities can be removed from hierarchy when finishing. activity1.detachFromProcess(); activity2.detachFromProcess(); - assertNull(task.performClearTop(activity1, 0 /* launchFlags */)); + assertTrue(task.performClearTop(activity1, 0 /* launchFlags */).finishing); assertFalse(task.hasChild()); // In real case, the task should be preserved for adding new activity. assertTrue(task.isAttached());