Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ec2a355 authored by Winson Chung's avatar Winson Chung
Browse files

Re-enable task trimming

- Skip trimming tasks that are behind the home stack as they can not be
  returned to.
- Adding tag to event log when trimming the task to indicate it was trimmed
  by the recent tasks list
- Update tests to use task builder

Bug: 34270611
Test: Launch task from assistant, ensure that the assistant is not removed
Test: com.android.server.am.RecentTasksTest
Test: #testBackStackTasks_expectNoTrim
Test: #testBehindHomeStackTasks_expectTaskTrimmed
Test: #testOtherDisplayTasks_expectNoTrim
Change-Id: I538c9010f7ce7844bfa93ff3c8900dea6f91bc95
parent 1b5be51f
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -5121,7 +5121,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                    // because we don't support returning them across task boundaries. Also, to
                    // keep backwards compatibility we remove the task from recents when finishing
                    // task with root activity.
                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
                            finishWithRootActivity, "finish-activity");
                    if (!res) {
                        Slog.i(TAG, "Removing task failed to finish activity");
                    }
@@ -10299,7 +10300,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        synchronized (this) {
            final long ident = Binder.clearCallingIdentity();
            try {
                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
                        "remove-task");
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
+1 −1
Original line number Diff line number Diff line
@@ -4009,7 +4009,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                // TODO: If the callers to removeTask() changes such that we have multiple places
                //       where we are destroying the task, move this back into removeTask()
                mStackSupervisor.removeTaskByIdLocked(task.taskId, false /* killProcess */,
                        !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY);
                        !REMOVE_FROM_RECENTS, PAUSE_IMMEDIATELY, reason);
            }

            // We must keep the task around until all activities are destroyed. The following
+13 −6
Original line number Diff line number Diff line
@@ -2737,7 +2737,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        } else {
            for (int i = tasks.size() - 1; i >= 0; i--) {
                removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */,
                        REMOVE_FROM_RECENTS);
                        REMOVE_FROM_RECENTS, "remove-stack");
            }
        }
    }
@@ -2770,8 +2770,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
    /**
     * See {@link #removeTaskByIdLocked(int, boolean, boolean, boolean)}
     */
    boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents) {
        return removeTaskByIdLocked(taskId, killProcess, removeFromRecents, !PAUSE_IMMEDIATELY);
    boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents,
            String reason) {
        return removeTaskByIdLocked(taskId, killProcess, removeFromRecents, !PAUSE_IMMEDIATELY,
                reason);
    }

    /**
@@ -2785,10 +2787,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
     * @return Returns true if the given task was found and removed.
     */
    boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents,
            boolean pauseImmediately) {
            boolean pauseImmediately, String reason) {
        final TaskRecord tr = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
        if (tr != null) {
            tr.removeTaskActivitiesLocked(pauseImmediately);
            tr.removeTaskActivitiesLocked(pauseImmediately, reason);
            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
            mService.mLockTaskController.clearLockedTask(tr);
            if (tr.isPersistable) {
@@ -2922,7 +2924,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D

    @Override
    public void onRecentTaskRemoved(TaskRecord task, boolean wasTrimmed) {
        // TODO: Trim active task once b/68045330 is fixed
        if (wasTrimmed) {
            // Task was trimmed from the recent tasks list -- remove the active task record as well
            // since the user won't really be able to go back to it
            removeTaskByIdLocked(task.taskId, false /* killProcess */,
                    false /* removeFromRecents */, !PAUSE_IMMEDIATELY, "recent-task-trimmed");
        }
        task.removedFromRecents();
    }

+1 −1
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ class AppTaskImpl extends IAppTask.Stub {
            try {
                // We remove the task from recents to preserve backwards
                if (!mService.mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
                        REMOVE_FROM_RECENTS)) {
                        REMOVE_FROM_RECENTS, "finish-and-remove-task")) {
                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
                }
            } finally {
+42 −4
Original line number Diff line number Diff line
@@ -80,6 +80,20 @@ import java.util.concurrent.TimeUnit;
/**
 * Class for managing the recent tasks list. The list is ordered by most recent (index 0) to the
 * least recent.
 *
 * The trimming logic can be boiled down to the following.  For recent task list with a number of
 * tasks, the visible tasks are an interleaving subset of tasks that would normally be presented to
 * the user. Non-visible tasks are not considered for trimming. Of the visible tasks, only a
 * sub-range are presented to the user, based on the device type, last task active time, or other
 * task state. Tasks that are not in the visible range and are not returnable from the SystemUI
 * (considering the back stack) are considered trimmable. If the device does not support recent
 * tasks, then trimming is completely disabled.
 *
 * eg.
 * L = [TTTTTTTTTTTTTTTTTTTTTTTTTT] // list of tasks
 *     [VVV  VV   VVVV  V V V     ] // Visible tasks
 *     [RRR  RR   XXXX  X X X     ] // Visible range tasks, eg. if the device only shows 5 tasks,
 *                                  // 'X' tasks are trimmed.
 */
class RecentTasks {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "RecentTasks" : TAG_AM;
@@ -496,7 +510,8 @@ class RecentTasks {
            if (tr.userId != userId) return;
            if (!taskPackageName.equals(packageName)) return;

            mService.mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
            mService.mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS,
                    "remove-package-task");
        }
    }

@@ -513,7 +528,7 @@ class RecentTasks {
                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
            if (sameComponent) {
                mService.mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
                        REMOVE_FROM_RECENTS);
                        REMOVE_FROM_RECENTS, "disabled-package");
            }
        }
    }
@@ -1001,12 +1016,13 @@ class RecentTasks {
                    continue;
                } else {
                    numVisibleTasks++;
                    if (isInVisibleRange(task, numVisibleTasks)) {
                    if (isInVisibleRange(task, numVisibleTasks) || !isTrimmable(task)) {
                        // Keep visible tasks in range
                        i++;
                        continue;
                    } else {
                        // Fall through to trim visible tasks that are no longer in range
                        // Fall through to trim visible tasks that are no longer in range and
                        // trimmable
                        if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG,
                                "Trimming out-of-range visible task=" + task);
                    }
@@ -1121,6 +1137,28 @@ class RecentTasks {
        return false;
    }

    /**
     * @return whether the given task can be trimmed even if it is outside the visible range.
     */
    protected boolean isTrimmable(TaskRecord task) {
        final ActivityStack stack = task.getStack();
        final ActivityStack homeStack = mService.mStackSupervisor.mHomeStack;

        // No stack for task, just trim it
        if (stack == null) {
            return true;
        }

        // Ignore tasks from different displays
        if (stack.getDisplay() != homeStack.getDisplay()) {
            return false;
        }

        // Trim tasks that are in stacks that are behind the home stack
        final ActivityDisplay display = stack.getDisplay();
        return display.getIndexOf(stack) < display.getIndexOf(homeStack);
    }

    /**
     * If needed, remove oldest existing entries in recents that are for the same kind
     * of task as the given one.
Loading