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

Commit d2730076 authored by Winson Chung's avatar Winson Chung
Browse files

Fixing up some logic around excluded tasks

- We already check for the excluded task flag in isInVisibleRange, so we
  should handle skipping that check in there. This fixes the issue where
  an excluded task behind a non-visible task would still fail to show
  even if it was the last visible task.

Bug: 125475435
Test: atest WmTests:RecentTasksTest
Change-Id: I26e79197c3d2bda30f597dd7d4fa879784f14dc8
parent 8f8deb20
Loading
Loading
Loading
Loading
+50 −49
Original line number Diff line number Diff line
@@ -845,6 +845,11 @@ class RecentTasks {
        return mService.mAmInternal.getCurrentProfileIds();
    }

    @VisibleForTesting
    boolean isUserRunning(int userId, int flags) {
        return mService.mAmInternal.isUserRunning(userId, flags);
    }

    /**
     * @return the list of recent tasks for presentation.
     */
@@ -861,7 +866,7 @@ class RecentTasks {
            boolean getTasksAllowed, boolean getDetailedTasks, int userId, int callingUid) {
        final boolean withExcluded = (flags & RECENT_WITH_EXCLUDED) != 0;

        if (!mService.mAmInternal.isUserRunning(userId, FLAG_AND_UNLOCKED)) {
        if (!isUserRunning(userId, FLAG_AND_UNLOCKED)) {
            Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
            return new ArrayList<>();
        }
@@ -881,7 +886,7 @@ class RecentTasks {

            if (isVisibleRecentTask(tr)) {
                numVisibleTasks++;
                if (isInVisibleRange(tr, numVisibleTasks)) {
                if (isInVisibleRange(tr, numVisibleTasks, withExcluded)) {
                    // Fall through
                } else {
                    // Not in visible range
@@ -908,17 +913,6 @@ class RecentTasks {
                continue;
            }

            // Return the entry if desired by the caller.  We always return
            // the first entry, because callers always expect this to be the
            // foreground app.  We may filter others if the caller has
            // not supplied RECENT_WITH_EXCLUDED and there is some reason
            // we should exclude the entry.

            if (i == 0
                    || withExcluded
                    || (tr.intent == null)
                    || ((tr.intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                    == 0)) {
            if (!getTasksAllowed) {
                // If the caller doesn't have the GET_TASKS permission, then only
                // allow them to see a small subset of tasks -- their own and home.
@@ -927,22 +921,26 @@ class RecentTasks {
                    continue;
                }
            }

            if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
                // Don't include auto remove tasks that are finished or finishing.
                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
                            "Skipping, auto-remove without activity: " + tr);
                if (DEBUG_RECENTS) {
                    Slog.d(TAG_RECENTS, "Skipping, auto-remove without activity: " + tr);
                }
                continue;
            }
            if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) {
                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
                            "Skipping, unavail real act: " + tr);
                if (DEBUG_RECENTS) {
                    Slog.d(TAG_RECENTS, "Skipping, unavail real act: " + tr);
                }
                continue;
            }

            if (!tr.mUserSetupComplete) {
                // Don't include task launched while user is not done setting-up.
                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
                            "Skipping, user setup not complete: " + tr);
                if (DEBUG_RECENTS) {
                    Slog.d(TAG_RECENTS, "Skipping, user setup not complete: " + tr);
                }
                continue;
            }

@@ -953,7 +951,6 @@ class RecentTasks {

            res.add(rti);
        }
        }
        return res;
    }

@@ -994,7 +991,7 @@ class RecentTasks {
            final TaskRecord tr = mTasks.get(i);
            if (isVisibleRecentTask(tr)) {
                numVisibleTasks++;
                if (isInVisibleRange(tr, numVisibleTasks)) {
                if (isInVisibleRange(tr, numVisibleTasks, false /* skipExcludedCheck */)) {
                    res.put(tr.taskId, true);
                }
            }
@@ -1215,7 +1212,8 @@ class RecentTasks {
                    continue;
                } else {
                    numVisibleTasks++;
                    if (isInVisibleRange(task, numVisibleTasks) || !isTrimmable(task)) {
                    if (isInVisibleRange(task, numVisibleTasks, false /* skipExcludedCheck */)
                            || !isTrimmable(task)) {
                        // Keep visible tasks in range
                        i++;
                        continue;
@@ -1329,8 +1327,10 @@ class RecentTasks {
    /**
     * @return whether the given visible task is within the policy range.
     */
    private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks) {
        // Keep the last most task even if it is excluded from recents
    private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks,
            boolean skipExcludedCheck) {
        if (!skipExcludedCheck) {
            // Keep the most recent task even if it is excluded from recents
            final boolean isExcludeFromRecents =
                    (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                            == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
@@ -1338,6 +1338,7 @@ class RecentTasks {
                if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true");
                return numVisibleTasks == 1;
            }
        }

        if (mMinNumVisibleTasks >= 0 && numVisibleTasks <= mMinNumVisibleTasks) {
            // Always keep up to the min number of recent tasks, after that fall through to the
+67 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.wm;

import static android.app.ActivityManager.RECENT_WITH_EXCLUDED;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -29,7 +30,9 @@ 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 com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -511,6 +514,52 @@ public class RecentTasksTest extends ActivityTestsBase {
        assertTrimmed(excludedTask1);
    }

    @Test
    public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible() {
        // Create some set of tasks, some of which are visible and some are not
        TaskRecord homeTask = setTaskActivityType(
                createTaskBuilder("com.android.pkg1", ".HomeTask").build(),
                ACTIVITY_TYPE_HOME);
        homeTask.mUserSetupComplete = true;
        mRecentTasks.add(homeTask);
        TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1")
                .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                .build();
        excludedTask1.mUserSetupComplete = true;
        mRecentTasks.add(excludedTask1);

        // Expect that the first visible excluded-from-recents task is visible
        assertGetRecentTasksOrder(0 /* flags */, excludedTask1);
    }

    @Test
    public void testVisibleTasks_excludedFromRecents_withExcluded() {
        // Create some set of tasks, some of which are visible and some are not
        TaskRecord t1 = createTaskBuilder("com.android.pkg1", ".Task1").build();
        t1.mUserSetupComplete = true;
        mRecentTasks.add(t1);
        TaskRecord homeTask = setTaskActivityType(
                createTaskBuilder("com.android.pkg1", ".HomeTask").build(),
                ACTIVITY_TYPE_HOME);
        homeTask.mUserSetupComplete = true;
        mRecentTasks.add(homeTask);
        TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1")
                .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                .build();
        excludedTask1.mUserSetupComplete = true;
        mRecentTasks.add(excludedTask1);
        TaskRecord excludedTask2 = createTaskBuilder(".ExcludedTask2")
                .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                .build();
        excludedTask2.mUserSetupComplete = true;
        mRecentTasks.add(excludedTask2);
        TaskRecord t2 = createTaskBuilder("com.android.pkg2", ".Task1").build();
        t2.mUserSetupComplete = true;
        mRecentTasks.add(t2);

        assertGetRecentTasksOrder(RECENT_WITH_EXCLUDED, t2, excludedTask2, excludedTask1, t1);
    }

    @Test
    public void testVisibleTasks_minNum() {
        mRecentTasks.setOnlyTestVisibleRange();
@@ -830,7 +879,7 @@ public class RecentTasksTest extends ActivityTestsBase {
    }

    /**
     * Ensures that the recent tasks list is in the provided order. Note that the expected tasks
     * Ensures that the raw recent tasks list is in the provided order. Note that the expected tasks
     * should be ordered from least to most recent.
     */
    private void assertRecentTasksOrder(TaskRecord... expectedTasks) {
@@ -841,6 +890,22 @@ public class RecentTasksTest extends ActivityTestsBase {
        }
    }

    /**
     * Ensures that the recent tasks list is in the provided order. Note that the expected tasks
     * should be ordered from least to most recent.
     */
    private void assertGetRecentTasksOrder(int getRecentTaskFlags, TaskRecord... expectedTasks) {
        doNothing().when(mRecentTasks).loadUserRecentsLocked(anyInt());
        doReturn(true).when(mRecentTasks).isUserRunning(anyInt(), anyInt());
        List<RecentTaskInfo> infos = mRecentTasks.getRecentTasks(MAX_VALUE, getRecentTaskFlags,
                true /* getTasksAllowed */, false /* getDetailedTasks */,
                TEST_USER_0_ID, 0).getList();
        assertTrue(expectedTasks.length == infos.size());
        for (int i = 0; i < infos.size(); i++)  {
            assertTrue(expectedTasks[i].taskId == infos.get(i).taskId);
        }
    }

    private void assertNotRestoreTask(Runnable action) {
        // Verify stack count doesn't change because task with fullscreen mode and standard type
        // would have its own stack.
@@ -1018,7 +1083,7 @@ public class RecentTasksTest extends ActivityTestsBase {

        @Override
        protected RecentTasks createRecentTasks() {
            return new TestRecentTasks(this, mTaskPersister);
            return spy(new TestRecentTasks(this, mTaskPersister));
        }

        @Override