From 6c9dcad4b33e1ebb47ae12618a716b60d9681808 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 13 Mar 2018 16:57:55 -0700 Subject: [PATCH] Update old stack check for finding recent task index to remove - The recents task list was previously checking the stack of the task to optimize finding similar tasks to remove. In P, each task generally has its own stack, so this check is invalid. Instead, we should check the activity type to skip early if the activity types don't match. - Add another test to ensure that when a new multiple-task non-document task is added, that it will replace any existing matching task Bug: 72476837 Test: atest FrameworksServicesTests:RecentTasksTest Change-Id: I457fd5b2cd6dd1eb5e2533912df7e3948e0366b1 Signed-off-by: Winson Chung --- .../com/android/server/am/RecentTasks.java | 12 ++--- .../android/server/am/RecentTasksTest.java | 52 +++++++++++++++++-- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java index f1b3dfa5c0034..3f05ecee77ef1 100644 --- a/services/core/java/com/android/server/am/RecentTasks.java +++ b/services/core/java/com/android/server/am/RecentTasks.java @@ -1238,20 +1238,16 @@ class RecentTasks { * list (if any). */ private int findRemoveIndexForAddTask(TaskRecord task) { - int recentsCount = mTasks.size(); + final int recentsCount = mTasks.size(); + final int taskActivityType = task.getActivityType(); final Intent intent = task.intent; final boolean document = intent != null && intent.isDocument(); int maxRecents = task.maxRecents - 1; - final ActivityStack stack = task.getStack(); for (int i = 0; i < recentsCount; i++) { final TaskRecord tr = mTasks.get(i); - final ActivityStack trStack = tr.getStack(); - + final int trActivityType = tr.getActivityType(); if (task != tr) { - if (stack != null && trStack != null && stack != trStack) { - continue; - } - if (task.userId != tr.userId) { + if (taskActivityType != trActivityType || task.userId != tr.userId) { continue; } final Intent trIntent = tr.intent; diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java index 24566fcf8f0d0..376f5b1937164 100644 --- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java +++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java @@ -17,6 +17,7 @@ package com.android.server.am; import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; @@ -24,6 +25,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.view.Display.DEFAULT_DISPLAY; import static org.junit.Assert.assertFalse; @@ -74,7 +76,7 @@ import java.util.Random; import java.util.Set; /** - * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java + * atest FrameworksServicesTests:RecentTasksTest */ @MediumTest @Presubmit @@ -145,7 +147,7 @@ public class RecentTasksTest extends ActivityTestsBase { mRecentTasks = (TestRecentTasks) mService.getRecentTasks(); mRecentTasks.loadParametersFromResources(mContext.getResources()); mHomeStack = mService.mStackSupervisor.getDefaultDisplay().createStack( - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); mStack = mService.mStackSupervisor.getDefaultDisplay().createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); ((MyTestActivityStackSupervisor) mService.mStackSupervisor).setHomeStack(mHomeStack); @@ -236,7 +238,7 @@ public class RecentTasksTest extends ActivityTestsBase { } @Test - public void testAddTasksMultipleTasks_expectNoTrim() throws Exception { + public void testAddTasksMultipleDocumentTasks_expectNoTrim() throws Exception { // Add same multiple-task document tasks does not trim the first tasks TaskRecord documentTask1 = createDocumentTask(".DocumentTask1", FLAG_ACTIVITY_MULTIPLE_TASK); @@ -251,6 +253,50 @@ public class RecentTasksTest extends ActivityTestsBase { assertTrue(mCallbacksRecorder.removed.isEmpty()); } + @Test + public void testAddTasksMultipleTasks_expectRemovedNoTrim() throws Exception { + // Add multiple same-affinity non-document tasks, ensure that it removes the other task, + // but that it does not trim it + TaskRecord task1 = createTaskBuilder(".Task1") + .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK) + .build(); + TaskRecord task2 = createTaskBuilder(".Task1") + .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK) + .build(); + mRecentTasks.add(task1); + assertTrue(mCallbacksRecorder.added.size() == 1); + assertTrue(mCallbacksRecorder.added.contains(task1)); + assertTrue(mCallbacksRecorder.trimmed.isEmpty()); + assertTrue(mCallbacksRecorder.removed.isEmpty()); + mCallbacksRecorder.clear(); + mRecentTasks.add(task2); + assertTrue(mCallbacksRecorder.added.size() == 1); + assertTrue(mCallbacksRecorder.added.contains(task2)); + assertTrue(mCallbacksRecorder.trimmed.isEmpty()); + assertTrue(mCallbacksRecorder.removed.size() == 1); + assertTrue(mCallbacksRecorder.removed.contains(task1)); + } + + @Test + public void testAddTasksDifferentStacks_expectNoRemove() throws Exception { + // Adding the same task with different activity types should not trigger removal of the + // other task + TaskRecord task1 = createTaskBuilder(".Task1") + .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK) + .setStack(mHomeStack).build(); + TaskRecord task2 = createTaskBuilder(".Task1") + .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK) + .setStack(mStack).build(); + mRecentTasks.add(task1); + mRecentTasks.add(task2); + assertTrue(mCallbacksRecorder.added.size() == 2); + assertTrue(mCallbacksRecorder.added.contains(task1)); + assertTrue(mCallbacksRecorder.added.contains(task2)); + assertTrue(mCallbacksRecorder.trimmed.isEmpty()); + assertTrue(mCallbacksRecorder.removed.isEmpty()); + + } + @Test public void testUsersTasks() throws Exception { mRecentTasks.setOnlyTestVisibleRange();