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

Commit b3968b81 authored by Kazuki Takise's avatar Kazuki Takise
Browse files

Calculate freeform bounds for fullscreen task

Currently several pieces of logic in LaunchParamsModifier assume
that bounds doesn't need to be calculated for fullscreen tasks, but
this is incorrect in that the bounds calculated in
LaunchParamsModifier can be used as last non-fullscreen bounds for
fullscreen tasks. Last non-fullscreen bounds is useful in an
environment such as ARC++ where the windowing mode of a task
changes between freeform and fullscreen.

With this CL, freeform bounds calculation (ActivityOption, layout,
getTaskBounds) is applied to fullscreen tasks too.

This CL also involves some refactoring around getting bounds from
ActivityOption and WindowLayout (especially for fullscreen tasks
and tasks whose windowing mode is MULTI_WINDOW).

Bug: 185427982
Test: atest WmTests:TaskLaunchParamsModifierTests
Change-Id: I3ccaf1ebfa7bcc11c371b0043fbfa11366f7a8f3
parent 41fb1179
Loading
Loading
Loading
Loading
+37 −26
Original line number Diff line number Diff line
@@ -181,26 +181,34 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
        // is set with the suggestedDisplayArea. If it is set, but the eventual TaskDisplayArea is
        // different, we should recalculating the bounds.
        boolean hasInitialBoundsForSuggestedDisplayAreaInFreeformWindow = false;
        final boolean canApplyFreeformPolicy =
        // Note that initial bounds needs to be set to fullscreen tasks too as it's used as restore
        // bounds.
        final boolean canCalculateBoundsForFullscreenTask =
                canCalculateBoundsForFullscreenTask(suggestedDisplayArea, launchMode);
        final boolean canApplyFreeformWindowPolicy =
                canApplyFreeformWindowPolicy(suggestedDisplayArea, launchMode);
        if (mSupervisor.canUseActivityOptionsLaunchBounds(options)
                && (canApplyFreeformPolicy || canApplyPipWindowPolicy(launchMode))) {
        final boolean canApplyWindowLayout = layout != null
                && (canApplyFreeformWindowPolicy || canCalculateBoundsForFullscreenTask);
        final boolean canApplyBoundsFromActivityOptions =
                mSupervisor.canUseActivityOptionsLaunchBounds(options)
                        && (canApplyFreeformWindowPolicy
                        || canApplyPipWindowPolicy(launchMode)
                        || canCalculateBoundsForFullscreenTask);

        if (canApplyBoundsFromActivityOptions) {
            hasInitialBounds = true;
            launchMode = launchMode == WINDOWING_MODE_UNDEFINED
            // |launchMode| at this point can be fullscreen, PIP, MultiWindow, etc. Only set
            // freeform windowing mode if appropriate by checking |canApplyFreeformWindowPolicy|.
            launchMode = launchMode == WINDOWING_MODE_UNDEFINED && canApplyFreeformWindowPolicy
                    ? WINDOWING_MODE_FREEFORM
                    : launchMode;
            outParams.mBounds.set(options.getLaunchBounds());
            if (DEBUG) appendLog("activity-options-bounds=" + outParams.mBounds);
        } else if (launchMode == WINDOWING_MODE_PINNED) {
            // System controls PIP window's bounds, so don't apply launch bounds.
            if (DEBUG) appendLog("empty-window-layout-for-pip");
        } else if (launchMode == WINDOWING_MODE_FULLSCREEN) {
            if (DEBUG) appendLog("activity-options-fullscreen=" + outParams.mBounds);
        } else if (layout != null && canApplyFreeformPolicy) {
        } else if (canApplyWindowLayout) {
            mTmpBounds.set(currentParams.mBounds);
            getLayoutBounds(suggestedDisplayArea, root, layout, mTmpBounds);
            if (!mTmpBounds.isEmpty()) {
                launchMode = WINDOWING_MODE_FREEFORM;
                launchMode = canApplyFreeformWindowPolicy ? WINDOWING_MODE_FREEFORM : launchMode;
                outParams.mBounds.set(mTmpBounds);
                hasInitialBounds = true;
                hasInitialBoundsForSuggestedDisplayAreaInFreeformWindow = true;
@@ -210,6 +218,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
            }
        } else if (launchMode == WINDOWING_MODE_MULTI_WINDOW
                && options != null && options.getLaunchBounds() != null) {
            // TODO: Investigate whether we can migrate this clause to the
            //  |canApplyBoundsFromActivityOptions| case above.
            outParams.mBounds.set(options.getLaunchBounds());
            hasInitialBounds = true;
            if (DEBUG) appendLog("multiwindow-activity-options-bounds=" + outParams.mBounds);
@@ -249,11 +259,9 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
            if (!currentParams.mBounds.isEmpty()) {
                // Carry over bounds from callers regardless of launch mode because bounds is still
                // used to restore last non-fullscreen bounds when launch mode is not freeform.
                // Therefore it's not a resolution step for non-freeform launch mode and only
                // consider it fully resolved only when launch mode is freeform.
                outParams.mBounds.set(currentParams.mBounds);
                if (launchMode == WINDOWING_MODE_FREEFORM) {
                fullyResolvedCurrentParam = true;
                if (launchMode == WINDOWING_MODE_FREEFORM) {
                    if (DEBUG) appendLog("inherit-bounds=" + outParams.mBounds);
                }
            }
@@ -368,7 +376,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
                // an existing task.
                adjustBoundsToAvoidConflictInDisplayArea(taskDisplayArea, outParams.mBounds);
            }
        } else if (taskDisplayArea.inFreeformWindowingMode()) {
        } else {
            if (source != null && source.inFreeformWindowingMode()
                    && resolvedMode == WINDOWING_MODE_FREEFORM
                    && outParams.mBounds.isEmpty()
@@ -545,10 +553,19 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
        return display.getDisplayId() == source.getDisplayId();
    }

    private boolean canCalculateBoundsForFullscreenTask(@NonNull TaskDisplayArea displayArea,
                                                        int launchMode) {
        return mSupervisor.mService.mSupportsFreeformWindowManagement
                && ((displayArea.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
                && launchMode == WINDOWING_MODE_UNDEFINED)
                || launchMode == WINDOWING_MODE_FULLSCREEN);
    }

    private boolean canApplyFreeformWindowPolicy(@NonNull TaskDisplayArea suggestedDisplayArea,
            int launchMode) {
        return mSupervisor.mService.mSupportsFreeformWindowManagement
                && (suggestedDisplayArea.inFreeformWindowingMode()
                && ((suggestedDisplayArea.inFreeformWindowingMode()
                && launchMode == WINDOWING_MODE_UNDEFINED)
                || launchMode == WINDOWING_MODE_FREEFORM);
    }

@@ -710,16 +727,10 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
    private void getTaskBounds(@NonNull ActivityRecord root, @NonNull TaskDisplayArea displayArea,
            @NonNull ActivityInfo.WindowLayout layout, int resolvedMode, boolean hasInitialBounds,
            @NonNull Rect inOutBounds) {
        if (resolvedMode == WINDOWING_MODE_FULLSCREEN) {
            // We don't handle letterboxing here. Letterboxing will be handled by valid checks
            // later.
            inOutBounds.setEmpty();
            if (DEBUG) appendLog("maximized-bounds");
            return;
        }

        if (resolvedMode != WINDOWING_MODE_FREEFORM) {
            // We don't apply freeform bounds adjustment to other windowing modes.
        if (resolvedMode != WINDOWING_MODE_FREEFORM
                && resolvedMode != WINDOWING_MODE_FULLSCREEN) {
            // This function should be used only for freeform bounds adjustment. Freeform bounds
            // needs to be set to fullscreen tasks too as restore bounds.
            if (DEBUG) {
                appendLog("skip-bounds-" + WindowConfiguration.windowingModeToString(resolvedMode));
            }
+25 −0
Original line number Diff line number Diff line
@@ -570,6 +570,29 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
                WINDOWING_MODE_FULLSCREEN);
    }

    @Test
    public void testBoundsInOptionsInfersFullscreenWithBoundsOnFreeformSupportFullscreenDisplay() {
        final TestDisplayContent fullscreenDisplay = createNewDisplayContent(
                WINDOWING_MODE_FULLSCREEN);
        mAtm.mTaskSupervisor.mService.mSupportsFreeformWindowManagement = true;

        final ActivityOptions options = ActivityOptions.makeBasic();
        final Rect expectedBounds = new Rect(0, 0, 100, 100);
        options.setLaunchBounds(expectedBounds);

        mCurrent.mPreferredTaskDisplayArea = fullscreenDisplay.getDefaultTaskDisplayArea();

        assertEquals(RESULT_CONTINUE,
                new CalculateRequestBuilder().setOptions(options).calculate());

        // Setting bounds shouldn't lead to freeform windowing mode on fullscreen display by
        // default (even with freeform support), but we need to check here if the bounds is set even
        // with fullscreen windowing mode in case it's restored later.
        assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode,
                WINDOWING_MODE_FULLSCREEN);
        assertEquals(expectedBounds, mResult.mBounds);
    }

    @Test
    public void testInheritsFreeformModeFromSourceOnFullscreenDisplay() {
        final TestDisplayContent fullscreenDisplay = createNewDisplayContent(
@@ -952,6 +975,8 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
                WINDOWING_MODE_FULLSCREEN);
        final ActivityRecord source = createSourceActivity(fullscreenDisplay);
        source.getTask().setWindowingMode(WINDOWING_MODE_FREEFORM);
        // Set some bounds to avoid conflict with the other activity.
        source.setBounds(100, 100, 200, 200);

        final ActivityOptions options = ActivityOptions.makeBasic();
        final Rect expected = new Rect(0, 0, 150, 150);