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

Commit d4162ee6 authored by Graciela Wissen Putri's avatar Graciela Wissen Putri
Browse files

[2/n] Only DesktopModeLaunchParamsModifier resolve freeform launch

Only allow DesktopModeLaunchParamsModifier to resolve freeform bounds if
the task is launching in freeform and in freeform display (desktop).

With multiple desks, freeform tasks are children of a root task
controlled by DesksOrganizer, so don't skip resolving freeform bounds if
launching freeform tasks with multiple desks enabled.

Flag: com.android.window.flags.enable_freeform_display_launch_params
      com.android.window.flags.enable_multiple_desktops_backend
Bug: 401564801
Test: atest DesktopModeLaunchParamsModifierTests
Change-Id: If1f1784dc8dfcdc5eee9aa4d35a23a340310052c
parent 5c537c04
Loading
Loading
Loading
Loading
+59 −12
Original line number Diff line number Diff line
@@ -24,10 +24,12 @@ import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE_PER_TASK;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
import static android.window.DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND;

import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.DesktopModeHelper.canEnterDesktopMode;
import static com.android.server.wm.LaunchParamsUtil.getPreferredLaunchTaskDisplayArea;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -36,10 +38,14 @@ import android.app.WindowConfiguration;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.util.Slog;
import android.window.DesktopExperienceFlags;
import android.window.DesktopModeFlags;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wm.LaunchParamsController.LaunchParamsModifier;

import java.util.Objects;

/**
 * The class that defines default launch params for tasks in desktop mode
 */
@@ -53,9 +59,12 @@ class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
    private StringBuilder mLogBuilder;

    @NonNull private final Context mContext;
    @NonNull private final ActivityTaskSupervisor mSupervisor;

    DesktopModeLaunchParamsModifier(@NonNull Context context) {
    DesktopModeLaunchParamsModifier(@NonNull Context context,
            @NonNull ActivityTaskSupervisor supervisor) {
        mContext = context;
        mSupervisor = supervisor;
    }

    @Override
@@ -83,6 +92,33 @@ class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
            return RESULT_SKIP;
        }

        // Determine the suggested display area to launch the activity/task.
        final TaskDisplayArea suggestedDisplayArea = getPreferredLaunchTaskDisplayArea(mSupervisor,
                task, options, source, currentParams, activity, request, this::appendLog);
        outParams.mPreferredTaskDisplayArea = suggestedDisplayArea;
        final DisplayContent display = suggestedDisplayArea.mDisplayContent;
        appendLog("display-id=" + display.getDisplayId()
                + " task-display-area-windowing-mode=" + suggestedDisplayArea.getWindowingMode()
                + " suggested-display-area=" + suggestedDisplayArea);

        final boolean inDesktopMode = suggestedDisplayArea.inFreeformWindowingMode()
                || suggestedDisplayArea.getTopMostVisibleFreeformActivity() != null;
        if (DesktopExperienceFlags.ENABLE_FREEFORM_DISPLAY_LAUNCH_PARAMS.isTrue() && task == null
                && (isRequestingFreeformWindowMode(null, options, currentParams)
                    || inDesktopMode)) {
            if (options != null) {
                final int windowingMode = options.getLaunchWindowingMode();
                if (windowingMode == WINDOWING_MODE_UNDEFINED
                        || windowingMode == WINDOWING_MODE_FREEFORM) {
                    // Launching freeform in desktop but not ready to resolve bounds since task is
                    // null, return RESULT_DONE to prevent other modifiers from setting bounds.
                    outParams.mWindowingMode = options.getLaunchWindowingMode();
                    appendLog("launch-freeform");
                    return RESULT_DONE;
                }
            }
        }

        if (task == null || !task.isAttached()) {
            appendLog("task null, skipping");
            return RESULT_SKIP;
@@ -94,7 +130,12 @@ class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
            return RESULT_SKIP;
        }

        if (task.getCreatedByOrganizerTask() != null) {
        final Task organizerTask = task.getCreatedByOrganizerTask();
        // In multiple desks, freeform tasks are always children of a root task controlled
        // by DesksOrganizer, so don't skip resolving freeform bounds.
        if (organizerTask != null
                && !(ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()
                    && organizerTask.inFreeformWindowingMode())) {
            appendLog("has created-by-organizer-task, skipping");
            return RESULT_SKIP;
        }
@@ -103,10 +144,6 @@ class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
            appendLog("not standard or undefined activity type, skipping");
            return RESULT_SKIP;
        }
        if (phase < PHASE_WINDOWING_MODE) {
            appendLog("not in windowing mode or bounds phase, skipping");
            return RESULT_SKIP;
        }

        // Copy over any values
        outParams.set(currentParams);
@@ -131,10 +168,13 @@ class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
        }

        if (phase == PHASE_WINDOWING_MODE) {
            if (DesktopExperienceFlags.ENABLE_FREEFORM_DISPLAY_LAUNCH_PARAMS.isTrue()) {
                return RESULT_DONE;
            }
            return RESULT_CONTINUE;
        }

        if (!currentParams.mBounds.isEmpty()) {
        if (!currentParams.mBounds.isEmpty() && !inDesktopMode) {
            appendLog("currentParams has bounds set, not overriding");
            return RESULT_SKIP;
        }
@@ -143,6 +183,10 @@ class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
            if (DesktopModeFlags.DISABLE_DESKTOP_LAUNCH_PARAMS_OUTSIDE_DESKTOP_BUG_FIX.isTrue()) {
                // We are in desktop, return result done to prevent other modifiers from modifying
                // exiting task bounds or resolved windowing mode.
                if (DesktopExperienceFlags.ENABLE_FREEFORM_DISPLAY_LAUNCH_PARAMS.isTrue()) {
                    outParams.mBounds.set(task.getRequestedOverrideBounds());
                }
                appendLog("task-has-override-bounds=%s", task.getRequestedOverrideBounds());
                return RESULT_DONE;
            }
            appendLog("current task has bounds set, not overriding");
@@ -170,6 +214,10 @@ class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
            // this modifier is now also responsible to respecting the options launch windowing
            // mode.
            outParams.mWindowingMode = options.getLaunchWindowingMode();
            appendLog("inherit-options=" + options.getLaunchWindowingMode());
            return RESULT_DONE;
        }
        if (DesktopExperienceFlags.ENABLE_FREEFORM_DISPLAY_LAUNCH_PARAMS.isTrue()) {
            return RESULT_DONE;
        }
        return RESULT_CONTINUE;
@@ -195,13 +243,12 @@ class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
    }

    private boolean isRequestingFreeformWindowMode(
            @NonNull Task task,
            @Nullable Task task,
            @Nullable ActivityOptions options,
            @NonNull LaunchParamsController.LaunchParams currentParams) {
        return task.inFreeformWindowingMode()
        return (task != null && task.inFreeformWindowingMode())
                || (options != null && options.getLaunchWindowingMode() == WINDOWING_MODE_FREEFORM)
                || (currentParams.hasWindowingMode()
                && currentParams.mWindowingMode == WINDOWING_MODE_FREEFORM);
                || currentParams.mWindowingMode == WINDOWING_MODE_FREEFORM;
    }

    /**
@@ -239,7 +286,7 @@ class DesktopModeLaunchParamsModifier implements LaunchParamsModifier {
            @Nullable ActivityRecord launchingActivity,
            @NonNull Task launchingTask) {
        if (existingTaskActivity == null || launchingActivity == null) return false;
        return (existingTaskActivity.packageName == launchingActivity.packageName)
        return (Objects.equals(existingTaskActivity.packageName, launchingActivity.packageName))
                && isLaunchingNewSingleTask(launchingActivity.launchMode)
                && isClosingExitingInstance(launchingTask.getBaseIntent().getFlags());
    }
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ class LaunchParamsController {
    void registerDefaultModifiers(ActivityTaskSupervisor supervisor) {
        // {@link TaskLaunchParamsModifier} handles window layout preferences.
        registerModifier(new TaskLaunchParamsModifier(supervisor));
        registerModifier(new DesktopModeLaunchParamsModifier(mService.mContext));
        registerModifier(new DesktopModeLaunchParamsModifier(mService.mContext, supervisor));
    }

    /**
+43 −16
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@ import static com.android.internal.policy.SystemBarUtils.getDesktopViewAppHeader
import static com.android.server.wm.DesktopModeBoundsCalculator.DESKTOP_MODE_INITIAL_BOUNDS_SCALE;
import static com.android.server.wm.DesktopModeBoundsCalculator.DESKTOP_MODE_LANDSCAPE_APP_PADDING;
import static com.android.server.wm.DesktopModeBoundsCalculator.centerInScreen;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
@@ -57,10 +56,12 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import android.annotation.NonNull;
import android.app.ActivityOptions;
import android.compat.testing.PlatformCompatChangeRule;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
@@ -106,7 +107,7 @@ public class DesktopModeLaunchParamsModifierTests extends
        mResult = new LaunchParamsController.LaunchParams();
        mResult.reset();

        mTarget = spy(new DesktopModeLaunchParamsModifier(mContext));
        mTarget = spy(new DesktopModeLaunchParamsModifier(mContext, mSupervisor));
        doReturn(true).when(mTarget).isEnteringDesktopMode(any(), any(), any());
    }

@@ -220,16 +221,6 @@ public class DesktopModeLaunchParamsModifierTests extends
                new CalculateRequestBuilder().setTask(task).setOptions(options).calculate());
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
    public void testReturnsSkipIfNotBoundsPhase() {
        setupDesktopModeLaunchParamsModifier();

        final Task task = new TaskBuilder(mSupervisor).build();
        assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(task).setPhase(
                PHASE_DISPLAY).calculate());
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
    public void testReturnsSkipIfTaskNotUsingActivityTypeStandardOrUndefined() {
@@ -270,6 +261,24 @@ public class DesktopModeLaunchParamsModifierTests extends
        mCurrent.mBounds.set(/* left */ 0, /* top */ 0, /* right */ 100, /* bottom */ 100);
        assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(task).calculate());
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_FREEFORM_DISPLAY_LAUNCH_PARAMS)
    public void testReturnsDoneIfTaskNullLaunchInFreeform() {
        setupDesktopModeLaunchParamsModifier();

        final DisplayContent display = createDisplayContent(ORIENTATION_LANDSCAPE,
                LANDSCAPE_DISPLAY_BOUNDS, WINDOWING_MODE_FREEFORM);

        final ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
        options.setLaunchDisplayId(display.mDisplayId);

        assertEquals(RESULT_DONE, new CalculateRequestBuilder().setTask(null)
                .setOptions(options).calculate());
        assertEquals(options.getLaunchWindowingMode(), mResult.mWindowingMode);
    }

    @Test
    @EnableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
            Flags.FLAG_PRESERVE_RECENTS_TASK_CONFIGURATION_ON_RELAUNCH})
@@ -493,6 +502,9 @@ public class DesktopModeLaunchParamsModifierTests extends
        final ActivityRecord activity = createActivity(display, SCREEN_ORIENTATION_PORTRAIT,
                task, /* ignoreOrientationRequest */ false);

        // Mock desired aspect ratio so min override can take effect.
        setDesiredAspectRatio(activity, /* aspectRatio */ 1f);

        final int desiredHeight =
                (int) (LANDSCAPE_DISPLAY_BOUNDS.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
        final int desiredWidth =
@@ -517,6 +529,9 @@ public class DesktopModeLaunchParamsModifierTests extends
        final ActivityRecord activity = createActivity(display, SCREEN_ORIENTATION_PORTRAIT,
                task, /* ignoreOrientationRequest */ false);

        // Mock desired aspect ratio so min override can take effect.
        setDesiredAspectRatio(activity, /* aspectRatio */ 1f);

        final int desiredHeight =
                (int) (LANDSCAPE_DISPLAY_BOUNDS.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
        final int desiredWidth =
@@ -541,6 +556,9 @@ public class DesktopModeLaunchParamsModifierTests extends
        final ActivityRecord activity = createActivity(display, SCREEN_ORIENTATION_PORTRAIT,
                task, /* ignoreOrientationRequest */ false);

        // Mock desired aspect ratio so min override can take effect.
        setDesiredAspectRatio(activity, /* aspectRatio */ 1f);

        final int desiredHeight =
                (int) (LANDSCAPE_DISPLAY_BOUNDS.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
        final int desiredWidth =
@@ -565,6 +583,9 @@ public class DesktopModeLaunchParamsModifierTests extends
        final ActivityRecord activity = createActivity(display, SCREEN_ORIENTATION_PORTRAIT,
                task, /* ignoreOrientationRequest */ false);

        // Mock desired aspect ratio so min override can take effect.
        setDesiredAspectRatio(activity, /* aspectRatio */ 1f);

        final int desiredHeight =
                (int) (LANDSCAPE_DISPLAY_BOUNDS.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
        final int desiredWidth =
@@ -1627,14 +1648,20 @@ public class DesktopModeLaunchParamsModifierTests extends
                .getUserMinAspectRatioOverrideCode();
    }

    private TestDisplayContent createDisplayContent(int orientation, Rect displayBounds) {
    private TestDisplayContent createDisplayContent(@Configuration.Orientation int orientation,
            @NonNull Rect displayBounds) {
        return createDisplayContent(orientation, displayBounds, WINDOWING_MODE_FULLSCREEN);
    }

    private TestDisplayContent createDisplayContent(@Configuration.Orientation int orientation,
            @NonNull Rect displayBounds, int windowingMode) {
        final TestDisplayContent display = new TestDisplayContent
                .Builder(mAtm, displayBounds.width(), displayBounds.height())
                .setPosition(DisplayContent.POSITION_TOP).build();
        display.setBounds(displayBounds);
        display.getConfiguration().densityDpi = DENSITY_DEFAULT;
        display.getConfiguration().orientation = ORIENTATION_LANDSCAPE;
        display.getDefaultTaskDisplayArea().setWindowingMode(orientation);
        display.getConfiguration().orientation = orientation;
        display.getDefaultTaskDisplayArea().setWindowingMode(windowingMode);

        return display;
    }