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

Commit e1fb953f authored by Matthew Duggan's avatar Matthew Duggan
Browse files

Fix windowing mode for non-resizable tasks

This contains 4 connected fixes for making the Dream activity
non-resizable and fullscreen:

1.  Non-resizable tasks should not be allowed to be in a multi-window
mode.

2. Task#mForceResizableActivities should only be applied to "standard"
activities (eg, Home and Dream should not be forced resizable).

3. Dreams should be set to non-resizable to ensure the activity behind
is not visible, as asserted by the DreamManagerServiceTests CTS test.

4. To ensure the non-resizable dream activity is launched fullscreen,
always create a new one-level task for the Dream - avoid creating an
additional child task as it is not needed, there is only ever one
DreamActivity.

Bug: 168775742
Test: atest CtsWindowManagerDeviceTestCases:DreamManagerServiceTests
Change-Id: Iffe57061cac2044699da78d84d64df0dddfb3a26
parent 7c2008c6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -796,6 +796,9 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
    /**
     * Returns {@code true} if the windowingMode represents a window in multi-window mode.
     * I.e. sharing the screen with another activity.
     *
     * TODO(b/171672645): This API could be misleading - in 'undefined' mode it's determined by the
     * parent's mode
     * @hide
     */
    public static boolean inMultiWindowMode(int windowingMode) {
+2 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
@@ -1294,6 +1295,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        a.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
        a.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
        a.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
        a.resizeMode = RESIZE_MODE_UNRESIZEABLE;

        final ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchActivityType(ACTIVITY_TYPE_DREAM);
+7 −0
Original line number Diff line number Diff line
@@ -4997,6 +4997,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                || windowingMode == WINDOWING_MODE_MULTI_WINDOW);
    }

    static boolean canReuseExistingTask(int windowingMode, int activityType) {
        // Existing Tasks can be reused if a new stack will be created anyway, or for the Dream -
        // because there can only ever be one DreamActivity.
        return alwaysCreateStack(windowingMode, activityType)
                || activityType == ACTIVITY_TYPE_DREAM;
    }

    @Nullable
    Task getFocusedStack() {
        return getItemFromTaskDisplayAreas(TaskDisplayArea::getFocusedStack);
+14 −3
Original line number Diff line number Diff line
@@ -2813,16 +2813,25 @@ class Task extends WindowContainer<WindowContainer> {

        int windowingMode =
                getResolvedOverrideConfiguration().windowConfiguration.getWindowingMode();
        final int parentWindowingMode = newParentConfig.windowConfiguration.getWindowingMode();

        // Resolve override windowing mode to fullscreen for home task (even on freeform
        // display), or split-screen if in split-screen mode.
        if (getActivityType() == ACTIVITY_TYPE_HOME && windowingMode == WINDOWING_MODE_UNDEFINED) {
            final int parentWindowingMode = newParentConfig.windowConfiguration.getWindowingMode();
            windowingMode = WindowConfiguration.isSplitScreenWindowingMode(parentWindowingMode)
                    ? parentWindowingMode : WINDOWING_MODE_FULLSCREEN;
            getResolvedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode);
        }

        // Do not allow non-resizable non-pinned tasks to be in a multi-window mode - they should
        // use their parent's windowing mode, or fullscreen.
        if (!isResizeable() && windowingMode != WINDOWING_MODE_PINNED
                && WindowConfiguration.inMultiWindowMode(windowingMode)) {
            windowingMode = WindowConfiguration.inMultiWindowMode(parentWindowingMode)
                    ? WINDOWING_MODE_FULLSCREEN : parentWindowingMode;
            getResolvedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode);
        }

        if (isLeafTask()) {
            resolveLeafOnlyOverrideConfigs(newParentConfig, mTmpBounds /* previousBounds */);
        }
@@ -3312,7 +3321,9 @@ class Task extends WindowContainer<WindowContainer> {
    }

    boolean isResizeable(boolean checkSupportsPip) {
        return (mAtmService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
        final boolean forceResizable = mAtmService.mForceResizableActivities
                && getActivityType() == ACTIVITY_TYPE_STANDARD;
        return (forceResizable || ActivityInfo.isResizeableMode(mResizeMode)
                || (checkSupportsPip && mSupportsPictureInPicture));
    }

@@ -7174,7 +7185,7 @@ class Task extends WindowContainer<WindowContainer> {
            ActivityRecord source, ActivityOptions options) {

        Task task;
        if (DisplayContent.alwaysCreateStack(getWindowingMode(), getActivityType())) {
        if (DisplayContent.canReuseExistingTask(getWindowingMode(), getActivityType())) {
            // This stack will only contain one task, so just return itself since all stacks ara now
            // tasks and all tasks are now stacks.
            task = reuseAsLeafTask(voiceSession, voiceInteractor, intent, info, activity);