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

Commit b9a8dd77 authored by Ahmed Fakhry's avatar Ahmed Fakhry
Browse files

Fix splitscreen with freeform windows

Apps running in freeform window mode may have any arbitrary bounds, and
therefore will not inherit the bounds of their parent root tasks of the
main and side stages, causing splitscreen to be broken.

To fix this, the bounds of these leaf tasks must be cleared when they're
put in splitscreen.

Detailed explanation and demo video of the fixes can be found here:
https://b.corp.google.com/issues/357913557#comment3

Fixes: 357913557
Test: Manually with splitting 2 running apps, and splitting and
      launching new one
Flag: EXEMPT bugfix
Change-Id: Ic8a5aeecbddef4ce0ea7a648a166c5430ceb3280
parent 582028f6
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -684,6 +685,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        setSideStagePosition(splitPosition, wct);
        options1 = options1 != null ? options1 : new Bundle();
        addActivityOptions(options1, mSideStage);
        prepareTasksForSplitScreen(new int[] {taskId1, taskId2}, wct);
        wct.startTask(taskId1, options1);

        startWithTask(wct, taskId2, options2, snapPosition, remoteTransition, instanceId);
@@ -714,6 +716,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        options1 = options1 != null ? options1 : new Bundle();
        addActivityOptions(options1, mSideStage);
        wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
        prepareTasksForSplitScreen(new int[] {taskId}, wct);

        startWithTask(wct, taskId, options2, snapPosition, remoteTransition, instanceId);
    }
@@ -757,10 +760,29 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        options1 = options1 != null ? options1 : new Bundle();
        addActivityOptions(options1, mSideStage);
        wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1);
        prepareTasksForSplitScreen(new int[] {taskId}, wct);

        startWithTask(wct, taskId, options2, snapPosition, remoteTransition, instanceId);
    }

    /**
     * Prepares the tasks whose IDs are provided in `taskIds` for split screen by clearing their
     * bounds and windowing mode so that they can inherit the bounds and the windowing mode of
     * their root stages.
     *
     * @param taskIds an array of task IDs whose bounds will be cleared.
     * @param wct     transaction to clear the bounds on the tasks.
     */
    private void prepareTasksForSplitScreen(int[] taskIds, WindowContainerTransaction wct) {
        for (int taskId : taskIds) {
            ActivityManager.RunningTaskInfo task = mTaskOrganizer.getRunningTaskInfo(taskId);
            if (task != null) {
                wct.setWindowingMode(task.token, WINDOWING_MODE_UNDEFINED)
                        .setBounds(task.token, null);
            }
        }
    }

    /**
     * Starts with the second task to a split pair in one transition.
     *