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

Commit 513346d8 authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Don't allow non-dockable activities/tasks in docked stack.

Prevent activities and tasks that are not resizeable and don't
support crop windows resize mode from going into the docked stack.

Bug: 26774816
Change-Id: I1fd23114685be15908e80e8bc5a0216d8bfd049e
parent 1990221c
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.am;

import static android.app.ActivityManager.StackId;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
@@ -759,10 +760,19 @@ final class ActivityRecord {
        return !isHomeActivity() && ActivityInfo.isResizeableMode(info.resizeMode);
    }

    boolean isResizeableOrForced() {
        return !isHomeActivity() && (isResizeable() || service.mForceResizableActivities);
    }

    boolean supportsPictureInPicture() {
        return !isHomeActivity() && info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
    }

    boolean canGoInDockedStack() {
        return !isHomeActivity()
                && (isResizeableOrForced() || info.resizeMode == RESIZE_MODE_CROP_WINDOWS);
    }

    boolean isAlwaysFocusable() {
        return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
    }
+1 −2
Original line number Diff line number Diff line
@@ -1414,8 +1414,7 @@ final class ActivityStack {
            // task in the focus stack doesn't support any form of resizing.
            final ActivityRecord r = focusedStack.topRunningActivityLocked();
            final TaskRecord task = r != null ? r.task : null;
            return task == null || task.isResizeable() || task.inCropWindowsResizeMode()
                    ? STACK_VISIBLE : STACK_INVISIBLE;
            return task == null || task.canGoInDockedStack() ? STACK_VISIBLE : STACK_INVISIBLE;
        }

        // Find the first stack below focused stack that actually got something visible.
+22 −3
Original line number Diff line number Diff line
@@ -1723,7 +1723,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
                    stackId = task.getLaunchStackId();
                }
                if (stackId != task.stack.mStackId) {
                    moveTaskToStackUncheckedLocked(task, stackId, ON_TOP, !FORCE_FOCUS, reason);
                    final ActivityStack stack = moveTaskToStackUncheckedLocked(
                            task, stackId, ON_TOP, !FORCE_FOCUS, reason);
                    stackId = stack.mStackId;
                    // moveTaskToStackUncheckedLocked() should already placed the task on top,
                    // still need moveTaskToFrontLocked() below for any transition settings.
                }
@@ -2133,7 +2135,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
    private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
        if (stackId == INVALID_STACK_ID) {
            stackId = task.getLaunchStackId();
        } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) {
            // Preferred stack is the docked stack, but the task can't go in the docked stack.
            // Put it in the fullscreen stack.
            stackId = FULLSCREEN_WORKSPACE_STACK_ID;
        }

        if (task.stack != null) {
            // Task has already been restored once. See if we need to do anything more
            if (task.stack.mStackId == stackId) {
@@ -2169,8 +2176,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
     * Moves the specified task record to the input stack id.
     * WARNING: This method performs an unchecked/raw move of the task and
     * can leave the system in an unstable state if used incorrectly.
     * Use {@link #moveTaskToStackLocked} to perform safe task movement
     * to a stack.
     * Use {@link #moveTaskToStackLocked} to perform safe task movement to a stack.
     * @param task Task to move.
     * @param stackId Id of stack to move task to.
     * @param toTop True if the task should be placed at the top of the stack.
@@ -2191,6 +2197,18 @@ public final class ActivityStackSupervisor implements DisplayListener {
                && (prevStack.topRunningActivityLocked() == r);

        final int resizeMode = task.mResizeMode;

        if (stackId == DOCKED_STACK_ID && resizeMode == RESIZE_MODE_UNRESIZEABLE) {
            // We don't allow moving a unresizeable task to the docked stack since the docked
            // stack is used for split-screen mode and will cause things like the docked divider to
            // show up. We instead leave the task in its current stack or move it to the fullscreen
            // stack if it isn't currently in a stack.
            stackId = (prevStack != null) ? prevStack.mStackId : FULLSCREEN_WORKSPACE_STACK_ID;
            // TODO: display toast that activity doesn't support multi-window mode.
            Slog.w(TAG, "Can not move unresizeable task=" + task
                    + " to docked stack. Moving to stackId=" + stackId + " instead.");
        }

        // Temporarily disable resizeablility of task we are moving. We don't want it to be resized
        // if a docked stack is created below which will lead to the stack we are moving from and
        // its resizeable tasks being resized.
@@ -2238,6 +2256,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
        }
        final ActivityStack stack = moveTaskToStackUncheckedLocked(
                task, stackId, toTop, forceFocus, "moveTaskToStack:" + reason);
        stackId = stack.mStackId;

        if (!animate) {
            stack.mNoAnimActivities.add(topActivity);
+13 −7
Original line number Diff line number Diff line
@@ -1484,8 +1484,9 @@ class ActivityStarter {
            mInTask.updateOverrideConfiguration(mLaunchBounds);
            int stackId = mInTask.getLaunchStackId();
            if (stackId != mInTask.stack.mStackId) {
                mSupervisor.moveTaskToStackUncheckedLocked(
                final ActivityStack stack = mSupervisor.moveTaskToStackUncheckedLocked(
                        mInTask, stackId, ON_TOP, !FORCE_FOCUS, "inTaskToFront");
                stackId = stack.mStackId;
            }
            if (StackId.resizeStackWithLaunchBounds(stackId)) {
                mSupervisor.resizeStackLocked(stackId, mLaunchBounds,
@@ -1627,10 +1628,9 @@ class ActivityStarter {
        // If the freeform or docked stack has focus, and the activity to be launched is resizeable,
        // we can also put it in the focused stack.
        final int focusedStackId = mSupervisor.mFocusedStack.mStackId;
        final boolean canUseFocusedStack =
                focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID
                        || focusedStackId == DOCKED_STACK_ID
                        || (focusedStackId == FREEFORM_WORKSPACE_STACK_ID && r.isResizeable());
        final boolean canUseFocusedStack = focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID
                || (focusedStackId == DOCKED_STACK_ID && r.canGoInDockedStack())
                || (focusedStackId == FREEFORM_WORKSPACE_STACK_ID && r.isResizeableOrForced());
        if (canUseFocusedStack && (!newTask
                || mSupervisor.mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
@@ -1666,6 +1666,10 @@ class ActivityStarter {

        if (isValidLaunchStackId(launchStackId, r)) {
            return mSupervisor.getStack(launchStackId, CREATE_IF_NEEDED, ON_TOP);
        } else if (launchStackId == DOCKED_STACK_ID) {
            // The preferred launch stack is the docked stack, but it isn't a valid launch stack
            // for this activity, so we put the activity in the fullscreen stack.
            return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
        }

        if (!launchToSideAllowed || (launchFlags & FLAG_ACTIVITY_LAUNCH_TO_SIDE) == 0) {
@@ -1701,9 +1705,11 @@ class ActivityStarter {
            return false;
        }

        final boolean resizeable = r.isResizeable() || mService.mForceResizableActivities;
        if (stackId == DOCKED_STACK_ID && r.canGoInDockedStack()) {
            return true;
        }

        if (stackId != FULLSCREEN_WORKSPACE_STACK_ID && !resizeable) {
        if (stackId != FULLSCREEN_WORKSPACE_STACK_ID && !r.isResizeableOrForced()) {
            return false;
        }

+4 −0
Original line number Diff line number Diff line
@@ -943,6 +943,10 @@ final class TaskRecord {
        return !isResizeable() && mResizeMode == RESIZE_MODE_CROP_WINDOWS;
    }

    boolean canGoInDockedStack() {
        return isResizeable() || inCropWindowsResizeMode();
    }

    /**
     * Find the activity in the history stack within the given task.  Returns
     * the index within the history at which it's found, or < 0 if not found.