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

Commit 943ebe70 authored by Bryce Lee's avatar Bryce Lee
Browse files

Prevent NPE in ActivityStack#shouldbeVisible.

If there is a visibleBehind activity, we check to see if the top
activity in the top stack is not fullscreen. However, it is possible
for the top stack to be empty. This can happen if the previously top
activity is being re-installed.

This changelist addresses the issue by checking if the top activity is
null before referencing it.

Change-Id: I6de904bed1c7035ed1e112c9cacc1b6c2bac4e8f
Fixes: 32180256
Test: bit FrameworksServicesTests:com.android.server.am.ActivityStackTests#testShouldBeVisibleWithVisibleBehindActivity
parent f996c714
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -232,7 +232,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
    static final int STACK_VISIBLE = 1;
    // Stack is considered visible, but only becuase it has activity that is visible behind other
    // activities and there is a specific combination of stacks.
    private static final int STACK_VISIBLE_ACTIVITY_BEHIND = 2;
    static final int STACK_VISIBLE_ACTIVITY_BEHIND = 2;

    @VisibleForTesting
    /* The various modes for the method {@link #removeTask}. */
@@ -1652,7 +1652,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai

        if (StackId.isBackdropToTranslucentActivity(mStackId)
                && hasVisibleBehindActivity() && StackId.isHomeOrRecentsStack(topStackId)
                && !topStack.topActivity().fullscreen) {
                && (topStack.topActivity() == null || !topStack.topActivity().fullscreen)) {
            // The fullscreen or assistant stack should be visible if it has a visible behind
            // activity behind the home or recents stack that is translucent.
            return STACK_VISIBLE_ACTIVITY_BEHIND;
+22 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.platform.test.annotations.Presubmit;
@@ -97,4 +98,25 @@ public class ActivityStackTests extends ActivityTestsBase {

        testStack.stopActivityLocked(activityRecord);
    }

    /**
     * This test verifies that {@link ActivityStack#STACK_VISIBLE_ACTIVITY_BEHIND} is returned from
     * {@link ActivityStack#shouldBeVisible(ActivityRecord)} from a fullscreen workspace stack with
     * a visible behind activity when top focused stack is the home stack.
     */
    @Test
    public void testShouldBeVisibleWithVisibleBehindActivity() throws Exception {
        final ActivityManagerService service = createActivityManagerService();
        final TaskRecord task = createTask(service, testActivityComponent,
                ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID);
        final ActivityStack fullscreenWorkspaceStackId = task.getStack();
        final ActivityStack homeStack = service.mStackSupervisor.getStack(
                ActivityManager.StackId.HOME_STACK_ID, true /*createStaticStackIfNeeded*/,
                true /*onTop*/);
        final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task);
        service.mStackSupervisor.setFocusStackUnchecked("testEmptyStackShouldBeVisible", homeStack);
        service.mStackSupervisor.requestVisibleBehindLocked(activityRecord, true);
        assertEquals(ActivityStack.STACK_VISIBLE_ACTIVITY_BEHIND,
                fullscreenWorkspaceStackId.shouldBeVisible(null /*starting*/));
    }
}
+4 −2
Original line number Diff line number Diff line
@@ -151,9 +151,12 @@ public class ActivityTestsBase {
     * setup not available in the test environment. Also specifies an injector for
     */
    protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
        private final ActivityDisplay mDisplay;

        public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
            super(service, looper);
            mWindowManager = prepareMockWindowManager();
            mDisplay = new ActivityDisplay();
        }

        // No home stack is set.
@@ -185,9 +188,8 @@ public class ActivityTestsBase {

        public <T extends ActivityStack> T createTestStack(ActivityManagerService service,
                int stackId, boolean onTop) {
            final ActivityDisplay display = new ActivityDisplay();
            final TestActivityContainer container =
                    new TestActivityContainer(service, stackId, display, onTop);
                    new TestActivityContainer(service, stackId, mDisplay, onTop);
            mActivityContainers.put(stackId, container);
            return (T) container.getStack();
        }