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

Commit 9fac209d authored by Jeremy Sim's avatar Jeremy Sim
Browse files

Add correct offsets to offscreen tasks in flexible split

This CL makes it so that task offsets are added when apps go offscreen in flexible split. We do this to avoid a config change/app redraw while the task is temporarily outside the screen's bounds.

Fixes an issue where the config would constantly recalculate when shifting between focused apps in flexible split.

There is still a small issue with the navigation bar causing a small shift, which is a KI and we should fix in another patch.

Fixes: 401087186
Flag: com.android.wm.shell.enable_flexible_two_app_split
Test: Tested flexible split in phone and tablet modes, and verified that the app doesn't constantly redraw anymore. Also thoroughly tested launch adjacent and app pair launch to make sure that they aren't affected.
Change-Id: Ic8ddb91e7b877b847a31ffc17be0fbf37fe53fb7
parent bca73325
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1276,6 +1276,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
            ActivityManager.RunningTaskInfo task, Rect bounds) {
        wct.setBounds(task.token, bounds);
        wct.setSmallestScreenWidthDp(task.token, getSmallestWidthDp(bounds));
        wct.setScreenSizeDp(task.token, task.configuration.screenWidthDp,
                task.configuration.screenHeightDp);
    }

    private int getSmallestWidthDp(Rect bounds) {
+4 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.wm.shell.splitscreen;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.RemoteAnimationTarget.MODE_OPENING;

@@ -453,6 +455,8 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
        wct.setBounds(mRootTaskInfo.token, null);
        wct.setAppBounds(mRootTaskInfo.token, null);
        wct.setSmallestScreenWidthDp(mRootTaskInfo.token, SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
        wct.setScreenSizeDp(mRootTaskInfo.token, SCREEN_WIDTH_DP_UNDEFINED,
                SCREEN_HEIGHT_DP_UNDEFINED);
    }

    void onSplitScreenListenerRegistered(SplitScreen.SplitScreenListener listener,
+22 −5
Original line number Diff line number Diff line
@@ -807,13 +807,30 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                    if (task != null) {
                        if (c.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
                                && c.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
                            final Rect oldBounds = container.getRequestedOverrideBounds();
                            final Rect newBounds =
                                    change.getConfiguration().windowConfiguration.getBounds();
                            if (oldBounds.width() == newBounds.width()
                                    && oldBounds.height() == newBounds.height()) {
                                task.mOffsetXForInsets = oldBounds.left - newBounds.left;
                                task.mOffsetYForInsets = oldBounds.top - newBounds.top;
                            final Rect display = container.getMaxBounds();

                            // In two cases -- IME shift and flexible split -- the task's bounds can
                            // temporarily exceed the display's bounds. In these cases, we want to
                            // avoid recalculating the config (which causes an app redraw). The
                            // below offset achieves that. Notably, to avoid affecting the launch
                            // adjacent case (which starts offscreen), we do nothing when the task
                            // is fully outside the display.
                            boolean offscreen = !display.contains(newBounds)
                                    && Rect.intersects(display, newBounds);

                            if (offscreen) {
                                if (newBounds.top < display.top) {
                                    task.mOffsetYForInsets = display.top - newBounds.top;
                                } else if (newBounds.bottom > display.bottom) {
                                    task.mOffsetYForInsets = display.bottom - newBounds.bottom;
                                }
                                if (newBounds.left < display.left) {
                                    task.mOffsetXForInsets = display.left - newBounds.left;
                                } else if (newBounds.right > display.right) {
                                    task.mOffsetXForInsets = display.right - newBounds.right;
                                }
                            } else {
                                task.mOffsetXForInsets = task.mOffsetYForInsets = 0;
                            }