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

Commit e5c78113 authored by Tony Huang's avatar Tony Huang Committed by Automerger Merge Worker
Browse files

Merge changes Icb7ba7d1,If6d5e6ec into udc-dev am: 8b616a88

parents 1a761d9d 8b616a88
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -59,4 +59,17 @@ public class SplitScreenConstants {

    /** Flag applied to a transition change to identify it as a divider bar for animation. */
    public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM;

    public static final String splitPositionToString(@SplitPosition int pos) {
        switch (pos) {
            case SPLIT_POSITION_UNDEFINED:
                return "SPLIT_POSITION_UNDEFINED";
            case SPLIT_POSITION_TOP_OR_LEFT:
                return "SPLIT_POSITION_TOP_OR_LEFT";
            case SPLIT_POSITION_BOTTOM_OR_RIGHT:
                return "SPLIT_POSITION_BOTTOM_OR_RIGHT";
            default:
                return "UNKNOWN";
        }
    }
}
+70 −33
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIV
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.common.split.SplitScreenConstants.splitPositionToString;
import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
@@ -378,40 +379,18 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,

    boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitPosition int stagePosition,
            WindowContainerTransaction wct) {
        StageTaskListener targetStage;
        int sideStagePosition;
        if (isSplitScreenVisible()) {
            // If the split screen is foreground, retrieves target stage based on position.
            targetStage = stagePosition == mSideStagePosition ? mSideStage : mMainStage;
            sideStagePosition = mSideStagePosition;
        } else {
            targetStage = mSideStage;
            sideStagePosition = stagePosition;
        }

        if (!isSplitActive()) {
            mSplitLayout.init();
        prepareEnterSplitScreen(wct, task, stagePosition);
        if (ENABLE_SHELL_TRANSITIONS) {
            mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct,
                    null, this, null /* consumedCallback */, null /* finishedCallback */,
                    isSplitScreenVisible()
                            ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
        } else {
            mSyncQueue.queue(wct);
            mSyncQueue.runInSync(t -> {
                updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
                setDividerVisibility(true, t);
            });
        } else {
            setSideStagePosition(sideStagePosition, wct);
            targetStage.addTask(task, wct);
            targetStage.evictAllChildren(wct);
            if (!isSplitScreenVisible()) {
                final StageTaskListener anotherStage = targetStage == mMainStage
                        ? mSideStage : mMainStage;
                anotherStage.reparentTopTask(wct);
                anotherStage.evictAllChildren(wct);
                wct.reorder(mRootTaskInfo.token, true);
        }
            setRootForceTranslucent(false, wct);
            mSyncQueue.queue(wct);
        }

        // Due to drag already pip task entering split by this method so need to reset flag here.
        mIsDropEntering = false;
        return true;
@@ -1509,9 +1488,51 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
     */
    void prepareEnterSplitScreen(WindowContainerTransaction wct,
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
        if (mMainStage.isActive()) return;

        onSplitScreenEnter();
        if (isSplitActive()) {
            prepareBringSplit(wct, taskInfo, startPosition);
        } else {
            prepareActiveSplit(wct, taskInfo, startPosition);
        }
    }

    private void prepareBringSplit(WindowContainerTransaction wct,
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
        StageTaskListener targetStage;
        if (isSplitScreenVisible()) {
            // If the split screen is foreground, retrieves target stage based on position.
            targetStage = startPosition == mSideStagePosition ? mSideStage : mMainStage;
        } else {
            targetStage = mSideStage;
        }

        if (taskInfo != null) {
            wct.startTask(taskInfo.taskId,
                    resolveStartStage(STAGE_TYPE_UNDEFINED, startPosition, null, wct));
            targetStage.evictAllChildren(wct);
        }
        // If running background, we need to reparent current top visible task to another stage
        // and evict all tasks current under its.
        if (!isSplitScreenVisible()) {
            // Recreate so we need to reset position rather than keep position of background split.
            mSplitLayout.resetDividerPosition();
            updateWindowBounds(mSplitLayout, wct);
            final StageTaskListener anotherStage = targetStage == mMainStage
                    ? mSideStage : mMainStage;
            anotherStage.evictAllChildren(wct);
            anotherStage.reparentTopTask(wct);
            wct.reorder(mRootTaskInfo.token, true);
            setRootForceTranslucent(false, wct);
        }
    }

    private void prepareActiveSplit(WindowContainerTransaction wct,
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
        if (!ENABLE_SHELL_TRANSITIONS) {
            // Legacy transition we need to create divider here, shell transition case we will
            // create it on #finishEnterSplitScreen
            mSplitLayout.init();
        }
        if (taskInfo != null) {
            setSideStagePosition(startPosition, wct);
            mSideStage.addTask(taskInfo, wct);
@@ -2383,7 +2404,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                }

                final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                if (taskInfo == null || !taskInfo.hasParentTask()) continue;
                if (taskInfo == null) continue;
                if (taskInfo.token.equals(mRootTaskInfo.token)) {
                    if (isOpeningType(change.getMode())) {
                        // Split is opened by someone so set it as visible.
                        setSplitsVisible(true);
                    } else if (isClosingType(change.getMode())) {
                        // Split is closed by someone so set it as invisible.
                        setSplitsVisible(false);
                    }
                    continue;
                }
                final StageTaskListener stage = getStageOfTask(taskInfo);
                if (stage == null) continue;
                if (isOpeningType(change.getMode())) {
@@ -2823,12 +2854,18 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        final String childPrefix = innerPrefix + "  ";
        pw.println(prefix + TAG + " mDisplayId=" + mDisplayId);
        pw.println(innerPrefix + "mDividerVisible=" + mDividerVisible);
        pw.println(innerPrefix + "isSplitActive=" + isSplitActive());
        pw.println(innerPrefix + "isSplitVisible=" + isSplitScreenVisible());
        pw.println(innerPrefix + "MainStage");
        pw.println(childPrefix + "stagePosition=" + getMainStagePosition());
        pw.println(childPrefix + "stagePosition=" + splitPositionToString(getMainStagePosition()));
        pw.println(childPrefix + "isActive=" + mMainStage.isActive());
        mMainStage.dump(pw, childPrefix);
        pw.println(innerPrefix + "MainStageListener");
        mMainStageListener.dump(pw, childPrefix);
        pw.println(innerPrefix + "SideStage");
        pw.println(childPrefix + "stagePosition=" + getSideStagePosition());
        pw.println(childPrefix + "stagePosition=" + splitPositionToString(getSideStagePosition()));
        mSideStage.dump(pw, childPrefix);
        pw.println(innerPrefix + "SideStageListener");
        mSideStageListener.dump(pw, childPrefix);
        if (mMainStage.isActive()) {
            pw.println(innerPrefix + "SplitLayout");
+8 −1
Original line number Diff line number Diff line
@@ -421,6 +421,13 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
    public void dump(@NonNull PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
        final String childPrefix = innerPrefix + "  ";
        pw.println(prefix + this);
        if (mChildrenTaskInfo.size() > 0) {
            pw.println(prefix + "Children list:");
            for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
                final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
                pw.println(childPrefix + "Task#" + i + " taskID=" + taskInfo.taskId
                        + " baseActivity=" + taskInfo.baseActivity);
            }
        }
    }
}
+8 −8
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
        /** Pip was entered while handling an intent with its own remoteTransition. */
        static final int TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE = 3;

        /** Recents transition while split-screen active. */
        /** Recents transition while split-screen foreground. */
        static final int TYPE_RECENTS_DURING_SPLIT = 4;

        /** The default animation for this mixed transition. */
@@ -152,7 +152,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
            @NonNull TransitionRequestInfo request) {
        if (mPipHandler.requestHasPipEnter(request) && mSplitHandler.isSplitScreenVisible()) {
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a PiP-enter request while "
                    + "Split-Screen is active, so treat it as Mixed.");
                    + "Split-Screen is foreground, so treat it as Mixed.");
            if (request.getRemoteTransition() != null) {
                throw new IllegalStateException("Unexpected remote transition in"
                        + "pip-enter-from-split request");
@@ -183,13 +183,13 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
            mixed.mLeftoversHandler = handler.first;
            mActiveTransitions.add(mixed);
            return handler.second;
        } else if (mSplitHandler.isSplitActive()
        } else if (mSplitHandler.isSplitScreenVisible()
                && isOpeningType(request.getType())
                && request.getTriggerTask() != null
                && request.getTriggerTask().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
                && request.getTriggerTask().getActivityType() == ACTIVITY_TYPE_HOME) {
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a going-home request while "
                    + "Split-Screen is active, so treat it as Mixed.");
                    + "Split-Screen is foreground, so treat it as Mixed.");
            Pair<Transitions.TransitionHandler, WindowContainerTransaction> handler =
                    mPlayer.dispatchRequest(transition, request, this);
            if (handler == null) {
@@ -211,7 +211,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,

    @Override
    public Transitions.TransitionHandler handleRecentsRequest(WindowContainerTransaction outWCT) {
        if (mRecentsHandler != null && mSplitHandler.isSplitActive()) {
        if (mRecentsHandler != null && mSplitHandler.isSplitScreenVisible()) {
            return this;
        }
        return null;
@@ -219,9 +219,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,

    @Override
    public void setRecentsTransition(IBinder transition) {
        if (mSplitHandler.isSplitActive()) {
        if (mSplitHandler.isSplitScreenVisible()) {
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while "
                    + "Split-Screen is active, so treat it as Mixed.");
                    + "Split-Screen is foreground, so treat it as Mixed.");
            final MixedTransition mixed = new MixedTransition(
                    MixedTransition.TYPE_RECENTS_DURING_SPLIT, transition);
            mixed.mLeftoversHandler = mRecentsHandler;
@@ -351,7 +351,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback) {
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animating a mixed transition for "
                + "entering PIP while Split-Screen is active.");
                + "entering PIP while Split-Screen is foreground.");
        TransitionInfo.Change pipChange = null;
        TransitionInfo.Change wallpaper = null;
        final TransitionInfo everythingElse = subCopy(info, TRANSIT_TO_BACK, true /* changes */);
+10 −8
Original line number Diff line number Diff line
@@ -152,10 +152,15 @@ public class StageCoordinatorTests extends ShellTestCase {
        when(mStageCoordinator.isSplitActive()).thenReturn(true);

        final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        final WindowContainerTransaction wct = spy(new WindowContainerTransaction());

        mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
        verify(mSideStage).addTask(eq(task), eq(wct));
        verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
                eq(SPLIT_POSITION_BOTTOM_OR_RIGHT));
        verify(mMainStage).reparentTopTask(eq(wct));
        verify(mMainStage).evictAllChildren(eq(wct));
        verify(mSideStage).evictAllChildren(eq(wct));
        verify(mSplitLayout).resetDividerPosition();
        assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
        assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
    }
@@ -171,14 +176,11 @@ public class StageCoordinatorTests extends ShellTestCase {
        final WindowContainerTransaction wct = new WindowContainerTransaction();

        mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
        verify(mMainStage).addTask(eq(task), eq(wct));
        verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
                eq(SPLIT_POSITION_BOTTOM_OR_RIGHT));
        verify(mMainStage).evictAllChildren(eq(wct));
        assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
        assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getSideStagePosition());

        mStageCoordinator.moveToStage(task, SPLIT_POSITION_TOP_OR_LEFT, wct);
        verify(mSideStage).addTask(eq(task), eq(wct));
        assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getSideStagePosition());
        assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
    }

    @Test