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

Commit 7e1f5f56 authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Simplified ActivityStack.shouldBeVisible()

The method can now be simplified since we have a stack per task so
if a stack should be visible is now a question of if it is occluded
by another stack.

Also,
- Fixed an issue where the windowing mode of the primary split-screen
stack was changing to split-screen-secondary instead of fullscreen
when we are exiting split-screen mode because we are not allowed to
to create fullscreen stack when there is a primary split-screen stack. We
now clear the reference to the primary split-screen stack when exiting
split-screen mode.
- Re-worked windowing mode resolution to be inside ActivityDisplay
object since the determination of the windowing mode is dependant on the
display.

Test: bit FrameworksServicesTests:com.android.server.am.ActivityStackTests
Test: Existing tests pass.
Test: go/wm-smoke
Bug: 64146578
Fixes: 67914671
Change-Id: I7e8cfe49fbf6a5836ded022bb11adcde58ae689c
parent 58488631
Loading
Loading
Loading
Loading
+134 −34
Original line number Diff line number Diff line
@@ -38,7 +38,9 @@ import static com.android.server.am.proto.ActivityDisplayProto.CONFIGURATION_CON
import static com.android.server.am.proto.ActivityDisplayProto.STACKS;
import static com.android.server.am.proto.ActivityDisplayProto.ID;

import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.WindowConfiguration;
import android.util.IntArray;
import android.util.Slog;
@@ -205,6 +207,18 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
        return createStack(windowingMode, activityType, onTop);
    }

    /**
     * Returns an existing stack compatible with the input params or creates one
     * if a compatible stack doesn't exist.
     * @see #getOrCreateStack(int, int, boolean)
     */
    <T extends ActivityStack> T getOrCreateStack(@Nullable ActivityRecord r,
            @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, int activityType,
            boolean onTop) {
        final int windowingMode = resolveWindowingMode(r, options, candidateTask, activityType);
        return getOrCreateStack(windowingMode, activityType, onTop);
    }

    /**
     * Creates a stack matching the input windowing mode and activity type on this display.
     * @param windowingMode The windowing mode the stack should be created in. If
@@ -235,7 +249,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
        }

        final ActivityManagerService service = mSupervisor.mService;
        if (!mSupervisor.isWindowingModeSupported(windowingMode, service.mSupportsMultiWindow,
        if (!isWindowingModeSupported(windowingMode, service.mSupportsMultiWindow,
                service.mSupportsSplitScreenMultiWindow, service.mSupportsFreeformWindowManagement,
                service.mSupportsPictureInPicture, activityType)) {
            throw new IllegalArgumentException("Can't create stack for unsupported windowingMode="
@@ -252,33 +266,27 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
            }
        }

        windowingMode = updateWindowingModeForSplitScreenIfNeeded(windowingMode, activityType);

        final int stackId = mSupervisor.getNextStackId();

        final T stack = createStackUnchecked(windowingMode, activityType, stackId, onTop);

        if (mDisplayId == DEFAULT_DISPLAY && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
            // Make sure recents stack exist when creating a dock stack as it normally need to be on
            // the other side of the docked stack and we make visibility decisions based on that.
            // TODO: Not sure if this is needed after we change to calculate visibility based on
            // stack z-order vs. id.
            getOrCreateStack(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_RECENTS, onTop);
        }

        return stack;
        return createStackUnchecked(windowingMode, activityType, stackId, onTop);
    }

    @VisibleForTesting
    <T extends ActivityStack> T createStackUnchecked(int windowingMode, int activityType,
            int stackId, boolean onTop) {
        switch (windowingMode) {
            case WINDOWING_MODE_PINNED:
        if (windowingMode == WINDOWING_MODE_PINNED) {
            return (T) new PinnedActivityStack(this, stackId, mSupervisor, onTop);
            default:
                return (T) new ActivityStack(
        }
        final T stack = (T) new ActivityStack(
                        this, stackId, mSupervisor, windowingMode, activityType, onTop);

        if (mDisplayId == DEFAULT_DISPLAY && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
            // Make sure recents stack exist when creating a dock stack as it normally needs to be
            // on the other side of the docked stack and we make visibility decisions based on that.
            // TODO: Not sure if this is needed after we change to calculate visibility based on
            // stack z-order vs. id.
            getOrCreateStack(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_RECENTS, onTop);
        }
        return stack;
    }

    /**
@@ -372,6 +380,105 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
        }
    }

    /**
     * Returns true if the {@param windowingMode} is supported based on other parameters passed in.
     * @param windowingMode The windowing mode we are checking support for.
     * @param supportsMultiWindow If we should consider support for multi-window mode in general.
     * @param supportsSplitScreen If we should consider support for split-screen multi-window.
     * @param supportsFreeform If we should consider support for freeform multi-window.
     * @param supportsPip If we should consider support for picture-in-picture mutli-window.
     * @param activityType The activity type under consideration.
     * @return true if the windowing mode is supported.
     */
    private boolean isWindowingModeSupported(int windowingMode, boolean supportsMultiWindow,
            boolean supportsSplitScreen, boolean supportsFreeform, boolean supportsPip,
            int activityType) {

        if (windowingMode == WINDOWING_MODE_UNDEFINED
                || windowingMode == WINDOWING_MODE_FULLSCREEN) {
            return true;
        }
        if (!supportsMultiWindow) {
            return false;
        }

        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
                || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
            return supportsSplitScreen && WindowConfiguration.supportSplitScreenWindowingMode(
                    windowingMode, activityType);
        }

        if (!supportsFreeform && windowingMode == WINDOWING_MODE_FREEFORM) {
            return false;
        }

        if (!supportsPip && windowingMode == WINDOWING_MODE_PINNED) {
            return false;
        }
        return true;
    }

    int resolveWindowingMode(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
            @Nullable TaskRecord task, int activityType) {

        // First preference if the windowing mode in the activity options if set.
        int windowingMode = (options != null)
                ? options.getLaunchWindowingMode() : WINDOWING_MODE_UNDEFINED;

        // If windowing mode is unset, then next preference is the candidate task, then the
        // activity record.
        if (windowingMode == WINDOWING_MODE_UNDEFINED) {
            if (task != null) {
                windowingMode = task.getWindowingMode();
            }
            if (windowingMode == WINDOWING_MODE_UNDEFINED && r != null) {
                windowingMode = r.getWindowingMode();
            }
            if (windowingMode == WINDOWING_MODE_UNDEFINED) {
                // Use the display's windowing mode.
                windowingMode = getWindowingMode();
            }
        }

        // Make sure the windowing mode we are trying to use makes sense for what is supported.
        final ActivityManagerService service = mSupervisor.mService;
        boolean supportsMultiWindow = service.mSupportsMultiWindow;
        boolean supportsSplitScreen = service.mSupportsSplitScreenMultiWindow;
        boolean supportsFreeform = service.mSupportsFreeformWindowManagement;
        boolean supportsPip = service.mSupportsPictureInPicture;
        if (supportsMultiWindow) {
            if (task != null) {
                supportsMultiWindow = task.isResizeable();
                supportsSplitScreen = task.supportsSplitScreenWindowingMode();
                // TODO: Do we need to check for freeform and Pip support here?
            } else if (r != null) {
                supportsMultiWindow = r.isResizeable();
                supportsSplitScreen = r.supportsSplitScreenWindowingMode();
                supportsFreeform = r.supportsFreeform();
                supportsPip = r.supportsPictureInPicture();
            }
        }

        final boolean inSplitScreenMode = hasSplitScreenPrimaryStack();
        if (!inSplitScreenMode
                && windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) {
            // Switch to fullscreen windowing mode if we are not in split-screen mode and we are
            // trying to launch in split-screen secondary.
            windowingMode = WINDOWING_MODE_FULLSCREEN;
        } else if (inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN
                && supportsSplitScreen) {
            windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
        }

        if (windowingMode != WINDOWING_MODE_UNDEFINED
                && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen,
                supportsFreeform, supportsPip, activityType)) {
            return windowingMode;
        }
        // Return the display's windowing mode
        return getWindowingMode();
    }

    /** Returns the top visible stack activity type that isn't in the exclude windowing mode. */
    int getTopVisibleStackActivityType(int excludeWindowingMode) {
        for (int i = mStacks.size() - 1; i >= 0; --i) {
@@ -408,6 +515,14 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
        }
    }

    /** We are in the process of exiting split-screen mode. */
    void onExitingSplitScreenMode() {
        // Remove reference to the primary-split-screen stack so it no longer has any effect on the
        // display. For example, we want to be able to create fullscreen stack for standard activity
        // types when exiting split-screen mode.
        mSplitScreenPrimaryStack = null;
    }

    ActivityStack getSplitScreenPrimaryStack() {
        return mSplitScreenPrimaryStack;
    }
@@ -424,21 +539,6 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
        return mPinnedStack != null;
    }

    int updateWindowingModeForSplitScreenIfNeeded(int windowingMode, int activityType) {
        final boolean inSplitScreenMode = hasSplitScreenPrimaryStack();
        if (!inSplitScreenMode
                && windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) {
            // Switch to fullscreen windowing mode if we are not in split-screen mode and we are
            // trying to launch in split-screen secondary.
            return WINDOWING_MODE_FULLSCREEN;
        } else if (inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN
                && WindowConfiguration.supportSplitScreenWindowingMode(
                windowingMode, activityType)) {
            return WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
        }
        return windowingMode;
    }

    @Override
    public String toString() {
        return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
+3 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
@@ -10318,7 +10319,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
            final ActivityStack stack = display.createStack(
                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /*onTop*/);
                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
                    ON_TOP);
            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
        }
    }
+12 −4
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.IApplicationToken;
import android.view.WindowManager.LayoutParams;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.ReferrerIntent;
@@ -232,7 +233,9 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
    final String processName; // process where this component wants to run
    final String taskAffinity; // as per ActivityInfo.taskAffinity
    final boolean stateNotNeeded; // As per ActivityInfo.flags
    boolean fullscreen; // covers the full screen?
    boolean fullscreen; // The activity is opaque and fills the entire space of this task.
    // TODO: See if it possible to combine this with the fullscreen field.
    final boolean hasWallpaper; // Has a wallpaper window as a background.
    final boolean noDisplay;  // activity is not displayed?
    private final boolean componentSpecified;  // did caller specify an explicit component?
    final boolean rootVoiceInteraction;  // was this the root activity of a voice interaction?
@@ -883,9 +886,14 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo

        Entry ent = AttributeCache.instance().get(packageName,
                realTheme, com.android.internal.R.styleable.Window, userId);
        fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array);
        noDisplay = ent != null && ent.array.getBoolean(
                com.android.internal.R.styleable.Window_windowNoDisplay, false);
        if (ent != null) {
            fullscreen = !ActivityInfo.isTranslucentOrFloating(ent.array);
            hasWallpaper = ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
            noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
        } else {
            hasWallpaper = false;
            noDisplay = false;
        }

        setActivityType(_componentSpecified, _launchedFromUid, _intent, options, sourceRecord);

+59 −128

File changed.

Preview size limit exceeded, changes collapsed.

+38 −131
Original line number Diff line number Diff line
@@ -110,7 +110,6 @@ import android.app.AppOpsManager;
import android.app.ProfilerInfo;
import android.app.ResultInfo;
import android.app.WaitResult;
import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -223,13 +222,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
    // at the top of its container (e.g. stack).
    static final boolean ON_TOP = true;

    // Used to indicate that an objects (e.g. task) removal from its container
    // (e.g. stack) is due to it moving to another container.
    static final boolean MOVING = true;

    // Force the focus to change to the stack we are moving a task to..
    static final boolean FORCE_FOCUS = true;

    // Don't execute any calls to resume.
    static final boolean DEFER_RESUME = true;

@@ -405,6 +397,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
     * object each time.
     */
    private final Rect tempRect = new Rect();
    private final ActivityOptions mTmpOptions = ActivityOptions.makeBasic();

    // The default minimal size that will be used if the activity doesn't specify its minimal size.
    // It will be calculated when the default display gets added.
@@ -2186,89 +2179,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        return null;
    }

    /**
     * Returns true if the {@param windowingMode} is supported based on other parameters passed in.
     * @param windowingMode The windowing mode we are checking support for.
     * @param supportsMultiWindow If we should consider support for multi-window mode in general.
     * @param supportsSplitScreen If we should consider support for split-screen multi-window.
     * @param supportsFreeform If we should consider support for freeform multi-window.
     * @param supportsPip If we should consider support for picture-in-picture mutli-window.
     * @param activityType The activity type under consideration.
     * @return true if the windowing mode is supported.
     */
    boolean isWindowingModeSupported(int windowingMode, boolean supportsMultiWindow,
            boolean supportsSplitScreen, boolean supportsFreeform, boolean supportsPip,
            int activityType) {

        if (windowingMode == WINDOWING_MODE_UNDEFINED
                || windowingMode == WINDOWING_MODE_FULLSCREEN) {
            return true;
        }
        if (!supportsMultiWindow) {
            return false;
        }

        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
                || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
            return supportsSplitScreen && WindowConfiguration.supportSplitScreenWindowingMode(
                    windowingMode, activityType);
        }

        if (!supportsFreeform && windowingMode == WINDOWING_MODE_FREEFORM) {
            return false;
        }

        if (!supportsPip && windowingMode == WINDOWING_MODE_PINNED) {
            return false;
        }
        return true;
    }

    private int resolveWindowingMode(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
            @Nullable TaskRecord task, int activityType) {

        // First preference if the windowing mode in the activity options if set.
        int windowingMode = (options != null)
                ? options.getLaunchWindowingMode() : WINDOWING_MODE_UNDEFINED;

        // If windowing mode is unset, then next preference is the candidate task, then the
        // activity record.
        if (windowingMode == WINDOWING_MODE_UNDEFINED) {
            if (task != null) {
                windowingMode = task.getWindowingMode();
            }
            if (windowingMode == WINDOWING_MODE_UNDEFINED && r != null) {
                windowingMode = r.getWindowingMode();
            }
        }

        // Make sure the windowing mode we are trying to use makes sense for what is supported.
        boolean supportsMultiWindow = mService.mSupportsMultiWindow;
        boolean supportsSplitScreen = mService.mSupportsSplitScreenMultiWindow;
        boolean supportsFreeform = mService.mSupportsFreeformWindowManagement;
        boolean supportsPip = mService.mSupportsPictureInPicture;
        if (supportsMultiWindow) {
            if (task != null) {
                supportsMultiWindow = task.isResizeable();
                supportsSplitScreen = task.supportsSplitScreenWindowingMode();
                // TODO: Do we need to check for freeform and Pip support here?
            } else if (r != null) {
                supportsMultiWindow = r.isResizeable();
                supportsSplitScreen = r.supportsSplitScreenWindowingMode();
                supportsFreeform = r.supportsFreeform();
                supportsPip = r.supportsPictureInPicture();
            }
        }

        if (windowingMode != WINDOWING_MODE_UNDEFINED
                && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen,
                supportsFreeform, supportsPip, activityType)) {
            return windowingMode;
        }
        // Return root/systems windowing mode
        return getWindowingMode();
    }

    int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
            @Nullable TaskRecord task) {
        // Preference is given to the activity type for the activity then the task since the type
@@ -2329,7 +2239,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        }

        final int activityType = resolveActivityType(r, options, candidateTask);
        int windowingMode = resolveWindowingMode(r, options, candidateTask, activityType);
        T stack = null;

        // Next preference for stack goes to the display Id set in the activity options or the
@@ -2347,7 +2256,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            }
            final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId);
            if (display != null) {
                stack = display.getOrCreateStack(windowingMode, activityType, onTop);
                stack = display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
                if (stack != null) {
                    return stack;
                }
@@ -2365,10 +2274,14 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            stack = r.getStack();
        }
        if (stack != null) {
            display = stack.getDisplay();
            if (display != null) {
                final int windowingMode =
                        display.resolveWindowingMode(r, options, candidateTask, activityType);
                if (stack.isCompatible(windowingMode, activityType)) {
                    return stack;
                }
            display = stack.getDisplay();
            }
        }

        if (display == null
@@ -2379,7 +2292,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            display = getDefaultDisplay();
        }

        return display.getOrCreateStack(windowingMode, activityType, onTop);
        return display.getOrCreateStack(r, options, candidateTask, activityType, onTop);
    }

    /**
@@ -2596,6 +2509,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            final ActivityDisplay toDisplay = getActivityDisplay(toDisplayId);

            if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
                // Tell the display we are exiting split-screen mode.
                toDisplay.onExitingSplitScreenMode();
                // We are moving all tasks from the docked stack to the fullscreen stack,
                // which is dismissing the docked stack, so resize all other stacks to
                // fullscreen here already so we don't end up with resize trashing.
@@ -2625,35 +2540,34 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            final ArrayList<TaskRecord> tasks = fromStack.getAllTasks();

            if (!tasks.isEmpty()) {
                mTmpOptions.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
                final int size = tasks.size();
                final ActivityStack fullscreenStack = toDisplay.getOrCreateStack(
                        WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, onTop);
                for (int i = 0; i < size; ++i) {
                    final TaskRecord task = tasks.get(i);
                    final ActivityStack toStack = toDisplay.getOrCreateStack(
                                null, mTmpOptions, task, task.getActivityType(), onTop);

                    if (onTop) {
                        final int returnToType =
                                toDisplay.getTopVisibleStackActivityType(WINDOWING_MODE_PINNED);
                    for (int i = 0; i < size; i++) {
                        final TaskRecord task = tasks.get(i);
                        final boolean isTopTask = i == (size - 1);
                        if (inPinnedWindowingMode) {
                            // Update the return-to to reflect where the pinned stack task was moved
                            // from so that we retain the stack that was previously visible if the
                            // pinned stack is recreated. See moveActivityToPinnedStackLocked().
                            // Update the return-to to reflect where the pinned stack task was
                            // moved from so that we retain the stack that was previously
                            // visible if the pinned stack is recreated.
                            // See moveActivityToPinnedStackLocked().
                            task.setTaskToReturnTo(returnToType);
                        }
                        // Defer resume until all the tasks have been moved to the fullscreen stack
                        task.reparent(fullscreenStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT,
                        task.reparent(toStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT,
                                isTopTask /* animate */, DEFER_RESUME,
                                schedulePictureInPictureModeChange,
                                "moveTasksToFullscreenStack - onTop");
                    }
                    } else {
                    for (int i = 0; i < size; i++) {
                        final TaskRecord task = tasks.get(i);
                        // Position the tasks in the fullscreen stack in order at the bottom of the
                        // stack. Also defer resume until all the tasks have been moved to the
                        // fullscreen stack.
                        task.reparent(fullscreenStack, i /* position */,
                        task.reparent(toStack, ON_TOP,
                                REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE, DEFER_RESUME,
                                schedulePictureInPictureModeChange,
                                "moveTasksToFullscreenStack - NOT_onTop");
@@ -3080,23 +2994,16 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                    + " task=" + task);
        }

        // 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.
        // Leave the task in its current stack or a fullscreen stack if it isn't resizeable and the
        // preferred stack is in multi-window mode.
        if (inMultiWindowMode && !task.isResizeable()) {
            Slog.w(TAG, "Can not move unresizeable task=" + task + " to docked stack."
                    + " Moving to stackId=" + stackId + " instead.");
            // Temporarily disable resizeablility of the task as we don't want it to be resized if,
            // for example, a docked stack is created which will lead to the stack we are moving
            // from being resized and and its resizeable tasks being resized.
            try {
                task.mTemporarilyUnresizable = true;
            Slog.w(TAG, "Can not move unresizeable task=" + task + " to multi-window stack=" + stack
                    + " Moving to a fullscreen stack instead.");
            if (prevStack != null) {
                return prevStack;
            }
            stack = stack.getDisplay().createStack(
                    WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), toTop);
            } finally {
                task.mTemporarilyUnresizable = false;
            }
        }
        return stack;
    }
@@ -4287,9 +4194,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        final boolean isSecondaryDisplayPreferred =
                (preferredDisplayId != DEFAULT_DISPLAY && preferredDisplayId != INVALID_DISPLAY);
        final boolean inSplitScreenMode = actualStack != null
                && actualStack.inSplitScreenWindowingMode();
                && actualStack.getDisplay().hasSplitScreenPrimaryStack();
        if (((!inSplitScreenMode && preferredWindowingMode != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)
                && !isSecondaryDisplayPreferred) || task.isActivityTypeHome()) {
                && !isSecondaryDisplayPreferred) || !task.isActivityTypeStandardOrUndefined()) {
            return;
        }

Loading