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

Commit 02ed3533 authored by Ats Jenk's avatar Ats Jenk
Browse files

Split root task should not allow bounds for child tasks

Call the new WindowContainerTransaction API
setDisableChildTaskBoundsOverride when split root task is ready.
Calling this on the root task ensures that when a task is reparented
under the split root task, the child task bounds are cleared.
Split screen requires that the tasks inherit the bounds of the root
tasks, if task has bounds set on it, it won't pick up the split bounds,
resulting in incorrect placement on screen.

Bug: 427245857
Test: atest WMShellUnitTests:StageCoordinatorTests
Flag: com.android.wm.shell.split_disable_child_task_bounds

Change-Id: Icd2bbc10d7b2c9398c95040af74e891ad6393cee
parent 47803e8d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import static com.android.window.flags.Flags.enableNonDefaultDisplaySplit;
import static com.android.wm.shell.Flags.enableEnterSplitRemoveBubble;
import static com.android.wm.shell.Flags.enableFlexibleSplit;
import static com.android.wm.shell.Flags.enableFlexibleTwoAppSplit;
import static com.android.wm.shell.Flags.splitDisableChildTaskBounds;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_FLEX_HYBRID;
import static com.android.wm.shell.common.split.SplitLayout.RESTING_DIM_LAYER;
@@ -2542,6 +2543,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            mSplitLayout.getInvisibleBounds(mTempRect1);
            wct.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
        }
        if (splitDisableChildTaskBounds()) {
            wct.setDisallowOverrideBoundsForChildren(rootTaskInfo.token, true);
        }
        mSyncQueue.queue(wct);
        if (!enableFlexibleSplit()) {
            mSyncQueue.runInSync(t -> {
+30 −1
Original line number Diff line number Diff line
@@ -21,8 +21,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN;

import static com.android.wm.shell.Flags.FLAG_ENABLE_ENTER_SPLIT_REMOVE_BUBBLE;
import static com.android.wm.shell.Flags.FLAG_SPLIT_DISABLE_CHILD_TASK_BOUNDS;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_UNDEFINED;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -74,6 +76,7 @@ import android.window.DisplayAreaInfo;
import android.window.RemoteTransition;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import android.window.WindowContainerTransaction.HierarchyOp;

import androidx.annotation.Nullable;
import androidx.test.annotation.UiThreadTest;
@@ -121,6 +124,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

@@ -549,7 +553,7 @@ public class StageCoordinatorTests extends ShellTestCase {
        int windowingMode = mWctCaptor.getValue().getChanges().get(mBinder).getWindowingMode();
        assertEquals(windowingMode, WINDOWING_MODE_UNDEFINED);
        assertThat(mWctCaptor.getValue().getHierarchyOps().stream().filter(
                        WindowContainerTransaction.HierarchyOp::isReparent).findFirst().get()
                        HierarchyOp::isReparent).findFirst().get()
                .getNewParent()).isNull();
    }

@@ -642,6 +646,31 @@ public class StageCoordinatorTests extends ShellTestCase {
        assertThat(options.getLaunchBounds()).isNull();
    }

    @Test
    @EnableFlags(FLAG_SPLIT_DISABLE_CHILD_TASK_BOUNDS)
    public void onRootTaskAppeared_disableChildTaskBounds() {
        // root tasks for stages are created in setUp, mark them set
        mMainStage.mHasRootTask = true;
        mSideStage.mHasRootTask = true;
        ActivityManager.RunningTaskInfo rootTaskInfo =
                mSplitMultiDisplayHelper.getDisplayRootTaskInfo(DEFAULT_DISPLAY);
        mStageCoordinator.onRootTaskAppeared(rootTaskInfo);

        ArgumentCaptor<WindowContainerTransaction> wctCaptor =
                ArgumentCaptor.forClass(WindowContainerTransaction.class);
        verify(mSyncQueue).queue(wctCaptor.capture());

        WindowContainerTransaction capturedWct = wctCaptor.getValue();
        List<HierarchyOp> disableChildBoundsOps = capturedWct.getHierarchyOps().stream()
                .filter(op -> op.getType()
                        == HIERARCHY_OP_TYPE_DISALLOW_OVERRIDE_BOUNDS_FOR_CHILDREN)
                .toList();
        assertThat(disableChildBoundsOps).hasSize(1);
        HierarchyOp op = disableChildBoundsOps.getFirst();
        assertThat(op.getContainer()).isEqualTo(rootTaskInfo.token.asBinder());
        assertThat(op.getDisallowOverrideBoundsForChildren()).isTrue();
    }

    private Transitions createTestTransitions() {
        ShellInit shellInit = new ShellInit(mMainExecutor);
        final Transitions t = new Transitions(mContext, shellInit, mock(ShellController.class),