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

Commit 1caf1f7a authored by Ats Jenk's avatar Ats Jenk Committed by Android (Google) Code Review
Browse files

Merge "Exit split if task moves to bubble via trampoline" into main

parents 6dc66003 438d181c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1085,6 +1085,8 @@ public class SplitScreenController implements SplitDragPolicy.Starter,
                return "FULLSCREEN_REQUEST";
            case EXIT_REASON_DRAG_TO_FULLSCREEN:
                return "EXIT_REASON_DRAG_TO_FULLSCREEN";
            case EXIT_REASON_CHILD_TASK_ENTER_BUBBLE:
                return "CHILD_TASK_ENTER_BUBBLE";
            default:
                return "unknown reason, reason int = " + exitReason;
        }
+39 −4
Original line number Diff line number Diff line
@@ -491,7 +491,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                    this /*stageListenerCallbacks*/,
                    mSyncQueue,
                    iconProvider,
                    mWindowDecorViewModel);
                    mWindowDecorViewModel,
                    mBubbleController);
        } else {
            mMainStage = new StageTaskListener(
                    mContext,
@@ -500,7 +501,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                    this /*stageListenerCallbacks*/,
                    mSyncQueue,
                    iconProvider,
                    mWindowDecorViewModel, STAGE_TYPE_MAIN);
                    mWindowDecorViewModel, STAGE_TYPE_MAIN,
                    bubbleController);
            mSideStage = new StageTaskListener(
                    mContext,
                    mTaskOrganizer,
@@ -508,7 +510,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                    this /*stageListenerCallbacks*/,
                    mSyncQueue,
                    iconProvider,
                    mWindowDecorViewModel, STAGE_TYPE_SIDE);
                    mWindowDecorViewModel, STAGE_TYPE_SIDE,
                    mBubbleController);
        }
        mTransitions = transitions;
        mDisplayController = displayController;
@@ -1747,7 +1750,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    /**
     * Starts a new transition to dismiss split.
     */
    private void dismissSplit(@StageType int stageToTop, @ExitReason int exitReason) {
    @VisibleForTesting
    void dismissSplit(@StageType int stageToTop, @ExitReason int exitReason) {
        if (!isSplitActive()) {
            return;
        }
@@ -2361,6 +2365,37 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        }
    }

    @Override
    public void onChildTaskMovedToBubble(StageTaskListener stage, int taskId) {
        if (stage.getChildCount() != 0) {
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
                    "onChildTaskMovedToBubble: task=%d in stage=%s moved to bubble, ignore, "
                            + "childCount=%d",
                    taskId, stageTypeToString(stage.getId()), stage.getChildCount());
            return;
        }
        int stageToTop = STAGE_TYPE_UNDEFINED;
        if (enableFlexibleSplit()) {
            for (StageTaskListener activeStage : mStageOrderOperator.getActiveStages()) {
                // See if any other stage still has children
                if (activeStage.getChildCount() > 0) {
                    stageToTop = activeStage.getId();
                    break;
                }
            }
        } else {
            final StageTaskListener remainingStage = stage == mMainStage ? mSideStage : mMainStage;
            if (remainingStage.getChildCount() > 0) {
                stageToTop = remainingStage.getId();
            }
        }
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
                "onChildTaskMovedToBubble: taskId=%d in stage=%s moved to bubble exit split "
                        + "stageToTop=%s",
                taskId, stageTypeToString(stage.getId()), stageTypeToString(stageToTop));
        dismissSplit(stageToTop, EXIT_REASON_CHILD_TASK_ENTER_BUBBLE);
    }

    private void updateRecentTasksSplitPair() {
        // Preventing from single task update while processing recents.
        if (!mShouldUpdateRecents || !mPausingTasks.isEmpty()) {
+8 −4
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.Context
import com.android.internal.protolog.ProtoLog
import com.android.launcher3.icons.IconProvider
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.bubbles.BubbleController
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.protolog.ShellProtoLogGroup
import com.android.wm.shell.shared.split.SplitScreenConstants
@@ -52,7 +53,8 @@ class StageOrderOperator (
        stageCallbacks: StageTaskListener.StageListenerCallbacks,
        syncQueue: SyncTransactionQueue,
        iconProvider: IconProvider,
        windowDecorViewModel: Optional<WindowDecorViewModel>
        windowDecorViewModel: Optional<WindowDecorViewModel>,
        bubbleController: Optional<BubbleController>,
) {

    private val MAX_STAGES = 3
@@ -77,14 +79,16 @@ class StageOrderOperator (

    init {
        for(i in 0 until MAX_STAGES) {
            allStages.add(StageTaskListener(context,
            allStages.add(StageTaskListener(
                context,
                taskOrganizer,
                displayId,
                stageCallbacks,
                syncQueue,
                iconProvider,
                windowDecorViewModel,
                stageIds[i])
                stageIds[i],
                bubbleController)
            )
        }
    }
+15 −3
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFIN
import static android.view.RemoteAnimationTarget.MODE_OPENING;

import static com.android.wm.shell.Flags.enableFlexibleSplit;
import static com.android.wm.shell.Flags.fixExitSplitOnEnterBubble;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
@@ -51,6 +52,7 @@ import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.common.SurfaceUtils;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.split.SplitDecorManager;
@@ -93,6 +95,8 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
        void onChildTaskStatusChanged(StageTaskListener stage, int taskId, boolean present,
                boolean visible);

        /** Called when a child task vanished and is now in a bubble. */
        void onChildTaskMovedToBubble(StageTaskListener stage, int taskId);

        /** Called when the root task on current display vanishes. */
        void onRootTaskVanished(ActivityManager.RunningTaskInfo taskInfo);
@@ -106,6 +110,7 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
    private final SyncTransactionQueue mSyncQueue;
    private final IconProvider mIconProvider;
    private final Optional<WindowDecorViewModel> mWindowDecorViewModel;
    private final Optional<BubbleController> mBubbleController;

    /** Whether or not the root task has been created. */
    boolean mHasRootTask = false;
@@ -124,12 +129,14 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
    StageTaskListener(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
            StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
            IconProvider iconProvider,
            Optional<WindowDecorViewModel> windowDecorViewModel, int id) {
            Optional<WindowDecorViewModel> windowDecorViewModel, int id,
            Optional<BubbleController> bubbleController) {
        mContext = context;
        mCallbacks = callbacks;
        mSyncQueue = syncQueue;
        mIconProvider = iconProvider;
        mWindowDecorViewModel = windowDecorViewModel;
        mBubbleController = bubbleController;
        taskOrganizer.createRootTask(
                new TaskOrganizer.CreateRootTaskRequest()
                        .setName(stageTypeToString(id).toLowerCase())
@@ -334,8 +341,13 @@ public class StageTaskListener implements ShellTaskOrganizer.TaskListener {
        } else if (mChildrenTaskInfo.contains(taskId)) {
            mChildrenTaskInfo.remove(taskId);
            mChildrenLeashes.remove(taskId);
            if (fixExitSplitOnEnterBubble()
                    && mBubbleController.map(c -> c.shouldBeAppBubble(taskInfo)).orElse(false)) {
                mCallbacks.onChildTaskMovedToBubble(this, taskId);
            } else {
                mCallbacks.onChildTaskStatusChanged(this, taskId, false /* present */,
                        taskInfo.isVisible);
            }
        } else {
            throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
                    + "\n mRootTaskInfo: " + mRootTaskInfo);
+6 −2
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.bubbles.BubbleController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
@@ -138,6 +139,7 @@ public class SplitTransitionTests extends ShellTestCase {
    private FakeDesktopState mDesktopState;
    @Mock private IActivityTaskManager mActivityTaskManager;
    @Mock private MSDLPlayer mMSDLPlayer;
    @Mock private BubbleController mBubbleController;
    private final TestShellExecutor mTestShellExecutor = new TestShellExecutor();
    private SplitLayout mSplitLayout;
    private StageTaskListener mMainStage;
@@ -164,11 +166,13 @@ public class SplitTransitionTests extends ShellTestCase {
        mSplitLayout = SplitTestUtils.createMockSplitLayout();
        mMainStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
                StageTaskListener.StageListenerCallbacks.class), mSyncQueue,
                mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_MAIN));
                mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_MAIN,
                Optional.of(mBubbleController)));
        mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
        mSideStage = spy(new StageTaskListener(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
                StageTaskListener.StageListenerCallbacks.class), mSyncQueue,
                mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_SIDE));
                mIconProvider, Optional.of(mWindowDecorViewModel), STAGE_TYPE_SIDE,
                Optional.of(mBubbleController)));
        mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
        mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
                mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController,
Loading