From f7f7f9c4d5836e5608752126060e63b2fdc564d2 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Tue, 18 Jun 2019 16:47:51 +0800 Subject: [PATCH] Do not use top running activities in other tasks when reset tasks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There were no running activities left in the resetting task, because all activities in the task were set as finishing. The next top running activity from other tasks was selected and returning it as the new taskTop. However, we shouldn’t return the activity that was not belonging to the resetting task because other tasks below would be reused for the newly starting activity. Bug: 135033489 Test: atest ActivityStackTests Change-Id: Ia3793cd3d65837fdbc4cd43c2639e86184f6fb15 --- .../com/android/server/wm/ActivityStack.java | 17 ++++++++++++++--- .../android/server/wm/ActivityStackTests.java | 13 +++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 12eab5096a13f..3875ee429bc12 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -3579,6 +3579,16 @@ class ActivityStack extends ConfigurationContainer { return taskInsertionPoint; } + /** + * Reset the task by reparenting the activities that have same affinity to the task or + * reparenting the activities that have different affinityies out of the task, while these + * activities allow task reparenting. + * + * @param taskTop Top activity of the task might be reset. + * @param newActivity The activity that going to be started. + * @return The non-finishing top activity of the task after reset or the original task top + * activity if all activities within the task are finishing. + */ final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop, ActivityRecord newActivity) { final boolean forceReset = @@ -3609,9 +3619,10 @@ class ActivityStack extends ConfigurationContainer { int taskNdx = mTaskHistory.indexOf(task); if (taskNdx >= 0) { - do { - taskTop = mTaskHistory.get(taskNdx--).getTopActivity(); - } while (taskTop == null && taskNdx >= 0); + ActivityRecord newTop = mTaskHistory.get(taskNdx).getTopActivity(); + if (newTop != null) { + taskTop = newTop; + } } if (topOptions != null) { diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index e5278d81767e4..a97217cd8628f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -1079,6 +1079,19 @@ public class ActivityStackTests extends ActivityTestsBase { assertTrue(listener.mChanged); } + @Test + public void testResetTaskWithFinishingActivities() { + final ActivityRecord taskTop = + new ActivityBuilder(mService).setStack(mStack).setCreateTask(true).build(); + // Make all activities in the task are finishing to simulate TaskRecord#getTopActivity + // returns null. + taskTop.finishing = true; + + final ActivityRecord newR = new ActivityBuilder(mService).build(); + final ActivityRecord result = mStack.resetTaskIfNeededLocked(taskTop, newR); + assertThat(result).isEqualTo(taskTop); + } + private void verifyShouldSleepActivities(boolean focusedStack, boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { final ActivityDisplay display = mock(ActivityDisplay.class);