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

Commit 92b7b659 authored by Bryce Lee's avatar Bryce Lee
Browse files

Do not try to restore a task id if it does not exist.

Previously, we were trying to restore the recent task regardless of
if it was found in recents or a stack. This would lead to
referencing a null object later.

Change-Id: I014a751d3254ad267c32ac0b54783b31b8d17e93
Test: bit FrameworksServicesTests:com.android.server.am.ActivityStackSupervisorTests
Fixes: 36688598
parent d2778f32
Loading
Loading
Loading
Loading
+11 −5
Original line number Original line Diff line number Diff line
@@ -745,7 +745,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
    }
    }


    /**
    /**
     * Returns a {@link TaskRecord} for the input id if available. Null otherwise.
     * Returns a {@link TaskRecord} for the input id if available. {@code null} otherwise.
     * @param id Id of the task we would like returned.
     * @param id Id of the task we would like returned.
     * @param matchMode The mode to match the given task id in.
     * @param matchMode The mode to match the given task id in.
     * @param stackId The stack to restore the task to (default launch stack will be used if
     * @param stackId The stack to restore the task to (default launch stack will be used if
@@ -765,7 +765,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                ActivityStack stack = stacks.get(stackNdx);
                ActivityStack stack = stacks.get(stackNdx);
                TaskRecord task = stack.taskForIdLocked(id);
                final TaskRecord task = stack.taskForIdLocked(id);
                if (task != null) {
                if (task != null) {
                    return task;
                    return task;
                }
                }
@@ -780,11 +780,17 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        // Otherwise, check the recent tasks and return if we find it there and we are not restoring
        // Otherwise, check the recent tasks and return if we find it there and we are not restoring
        // the task from recents
        // the task from recents
        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
        TaskRecord task = mRecentTasks.taskForIdLocked(id);
        final TaskRecord task = mRecentTasks.taskForIdLocked(id);
        if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {

            if (DEBUG_RECENTS && task == null) {
        if (task == null) {
            if (DEBUG_RECENTS) {
                Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
                Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
            }
            }

            return null;
        }

        if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
            return task;
            return task;
        }
        }


+54 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.server.am;

import static org.junit.Assert.assertNull;

import android.os.Debug;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.runner.RunWith;
import org.junit.Test;

import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;

/**
 * Tests for the {@link ActivityStackSupervisor} class.
 *
 * Build/Install/Run:
 *  bit FrameworksServicesTests:com.android.server.am.ActivityStackSupervisorTests
 */
@MediumTest
@Presubmit
@RunWith(AndroidJUnit4.class)
public class ActivityStackSupervisorTests extends ActivityTestsBase {
    /**
     * This test ensures that we do not try to restore a task based off an invalid task id. The
     * stack supervisor is a test version so there will be no tasks present. We should expect
     * {@code null} to be returned in this case.
     */
    @Test
    public void testRestoringInvalidTask() throws Exception {
        Debug.waitForDebugger();
        final ActivityManagerService service = createActivityManagerService();
        TaskRecord task = service.mStackSupervisor.anyTaskForIdLocked(0 /*taskId*/,
                MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, 0 /*stackId*/);
        assertNull(task);
    }
}