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

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

Merge "Make pip task could be enter split" into udc-dev am: 3b1ad3eb

parents de047d86 3b1ad3eb
Loading
Loading
Loading
Loading
+21 −25
Original line number Diff line number Diff line
@@ -534,17 +534,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
            return;
        }

        if (ENABLE_SHELL_TRANSITIONS) {
            if (requestEnterSplit && mSplitScreenOptional.isPresent()) {
                mSplitScreenOptional.get().prepareEnterSplitScreen(wct, mTaskInfo,
                        isPipTopLeft()
                                ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT);
                mPipTransitionController.startExitTransition(
                        TRANSIT_EXIT_PIP_TO_SPLIT, wct, null /* destinationBounds */);
                return;
            }
        }

        final Rect displayBounds = mPipBoundsState.getDisplayBounds();
        final Rect destinationBounds = new Rect(displayBounds);
        final int direction = syncWithSplitScreenBounds(destinationBounds, requestEnterSplit)
@@ -553,10 +542,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        // For exiting to fullscreen, the windowing mode of task will be changed to fullscreen
        // until the animation is finished. Otherwise if the activity is resumed and focused at the
        // begin of aniamtion, the app may do something too early to distub the animation.
        final boolean toFullscreen = destinationBounds.equals(displayBounds);

        if (Transitions.SHELL_TRANSITIONS_ROTATION || (Transitions.ENABLE_SHELL_TRANSITIONS
                && !toFullscreen)) {
        if (Transitions.SHELL_TRANSITIONS_ROTATION) {
            // When exit to fullscreen with Shell transition enabled, we update the Task windowing
            // mode directly so that it can also trigger display rotation and visibility update in
            // the same transition if there will be any.
@@ -588,9 +575,29 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        mPipTransitionState.setTransitionState(PipTransitionState.EXITING_PIP);

        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
            if (requestEnterSplit && mSplitScreenOptional.isPresent()) {
                wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
                mSplitScreenOptional.get().prepareEnterSplitScreen(wct, mTaskInfo,
                        isPipToTopLeft()
                                ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT);
                mPipTransitionController.startExitTransition(
                        TRANSIT_EXIT_PIP_TO_SPLIT, wct, destinationBounds);
                return;
            }

            if (mSplitScreenOptional.isPresent()) {
                // If pip activity will reparent to origin task case and if the origin task still
                // under split root, apply exit split transaction to make it expand to fullscreen.
                SplitScreenController split = mSplitScreenOptional.get();
                if (split.isTaskInSplitScreen(mTaskInfo.lastParentTaskIdBeforePip)) {
                    split.prepareExitSplitScreen(wct, split.getStageOfTask(
                            mTaskInfo.lastParentTaskIdBeforePip));
                }
            }
            mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct, destinationBounds);
            return;
        }

        if (mSplitScreenOptional.isPresent()) {
            // If pip activity will reparent to origin task case and if the origin task still under
            // split root, just exit split screen here to ensure it could expand to fullscreen.
@@ -1666,17 +1673,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        }
    }

    private boolean isPipTopLeft() {
        if (!mSplitScreenOptional.isPresent()) {
            return false;
        }
        final Rect topLeft = new Rect();
        final Rect bottomRight = new Rect();
        mSplitScreenOptional.get().getStageBounds(topLeft, bottomRight);

        return topLeft.contains(mPipBoundsState.getBounds());
    }

    private boolean isPipToTopLeft() {
        if (!mSplitScreenOptional.isPresent()) {
            return false;
+1 −6
Original line number Diff line number Diff line
@@ -989,12 +989,7 @@ public class PipTransition extends PipTransitionController {
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback,
            @NonNull TaskInfo taskInfo) {
        final int changeSize = info.getChanges().size();
        if (changeSize < 4) {
            throw new RuntimeException(
                    "Got an exit-pip-to-split transition with unexpected change-list");
        }
        for (int i = changeSize - 1; i >= 0; i--) {
        for (int i = info.getChanges().size() - 1; i >= 0; i--) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            final int mode = change.getMode();

+8 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.NonNull;

import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.split.SplitScreenUtils;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;

@@ -223,6 +224,13 @@ public abstract class PipTransitionController implements Transitions.TransitionH
        return false;
    }

    /** Whether a particular package is same as current pip package. */
    public boolean isInPipPackage(String packageName) {
        final TaskInfo inPipTask = mPipOrganizer.getTaskInfo();
        return packageName != null && inPipTask != null
                && packageName.equals(SplitScreenUtils.getPackageName(inPipTask.baseIntent));
    }

    /** Add PiP-related changes to `outWCT` for the given request. */
    public void augmentRequest(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request, @NonNull WindowContainerTransaction outWCT) {
+31 −7
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.draganddrop.DragAndDropPolicy;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
@@ -332,6 +333,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
        return mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED;
    }

    /** Get the split stage of task is under it. */
    public @StageType int getStageOfTask(int taskId) {
        return mStageCoordinator.getStageOfTask(taskId);
    }

    /** Check split is foreground and task is under split or not by taskId. */
    public boolean isTaskInSplitScreenForeground(int taskId) {
        return isTaskInSplitScreen(taskId) && isSplitScreenVisible();
@@ -378,17 +384,35 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
        mStageCoordinator.setSideStagePosition(sideStagePosition, null /* wct */);
    }

    public void enterSplitScreen(int taskId, boolean leftOrTop) {
        enterSplitScreen(taskId, leftOrTop, new WindowContainerTransaction());
    }

    /**
     * Doing necessary window transaction for other transition handler need to enter split in
     * transition.
     */
    public void prepareEnterSplitScreen(WindowContainerTransaction wct,
            ActivityManager.RunningTaskInfo taskInfo, int startPosition) {
        mStageCoordinator.prepareEnterSplitScreen(wct, taskInfo, startPosition);
        mStageCoordinator.prepareEnterSplitScreen(wct, taskInfo, startPosition,
                false /* resizeAnim */);
    }

    /**
     * Doing necessary surface transaction for other transition handler need to enter split in
     * transition when finished.
     */
    public void finishEnterSplitScreen(SurfaceControl.Transaction finishT) {
        mStageCoordinator.finishEnterSplitScreen(finishT);
    }

    public void finishEnterSplitScreen(SurfaceControl.Transaction t) {
        mStageCoordinator.finishEnterSplitScreen(t);
    /**
     * Doing necessary window transaction for other transition handler need to exit split in
     * transition.
     */
    public void prepareExitSplitScreen(WindowContainerTransaction wct,
            @StageType int stageToTop) {
        mStageCoordinator.prepareExitSplitScreen(stageToTop, wct);
    }

    public void enterSplitScreen(int taskId, boolean leftOrTop) {
        enterSplitScreen(taskId, leftOrTop, new WindowContainerTransaction());
    }

    public void enterSplitScreen(int taskId, boolean leftOrTop, WindowContainerTransaction wct) {
+34 −24
Original line number Diff line number Diff line
@@ -389,7 +389,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,

    boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitPosition int stagePosition,
            WindowContainerTransaction wct) {
        prepareEnterSplitScreen(wct, task, stagePosition);
        prepareEnterSplitScreen(wct, task, stagePosition, false /* resizeAnim */);
        if (ENABLE_SHELL_TRANSITIONS) {
            mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct,
                    null, this,
@@ -487,20 +487,26 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    /** Launches an activity into split. */
    void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
            @Nullable Bundle options) {
        mSplitRequest = new SplitRequest(intent.getIntent(), position);
        if (!ENABLE_SHELL_TRANSITIONS) {
            startIntentLegacy(intent, fillInIntent, position, options);
            return;
        }

        final WindowContainerTransaction wct = new WindowContainerTransaction();

        options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
        wct.sendPendingIntent(intent, fillInIntent, options);

        // If this should be mixed, just send the intent to avoid split handle transition directly.
        if (mMixedHandler != null && mMixedHandler.shouldSplitEnterMixed(intent)) {
            mTaskOrganizer.applyTransaction(wct);
            return;
        }

        // If split screen is not activated, we're expecting to open a pair of apps to split.
        final int extraTransitType = mMainStage.isActive()
                ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
        prepareEnterSplitScreen(wct, null /* taskInfo */, position);
        prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering);

        mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
                extraTransitType, !mIsDropEntering);
@@ -557,7 +563,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        if (isEnteringSplit && mLogger.isEnterRequestedByDrag()) {
            updateWindowBounds(mSplitLayout, wct);
        }
        mSplitRequest = new SplitRequest(intent.getIntent(), position);
        wct.sendPendingIntent(intent, fillInIntent, options);
        mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
    }
@@ -1445,7 +1450,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
     * an existing WindowContainerTransaction (rather than applying immediately). This is intended
     * to be used when exiting split might be bundled with other window operations.
     */
    private void prepareExitSplitScreen(@StageType int stageToTop,
    void prepareExitSplitScreen(@StageType int stageToTop,
            @NonNull WindowContainerTransaction wct) {
        if (!mMainStage.isActive()) return;
        mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
@@ -1453,7 +1458,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    }

    private void prepareEnterSplitScreen(WindowContainerTransaction wct) {
        prepareEnterSplitScreen(wct, null /* taskInfo */, SPLIT_POSITION_UNDEFINED);
        prepareEnterSplitScreen(wct, null /* taskInfo */, SPLIT_POSITION_UNDEFINED,
                !mIsDropEntering);
    }

    /**
@@ -1461,17 +1467,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
     * into side stage.
     */
    void prepareEnterSplitScreen(WindowContainerTransaction wct,
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition,
            boolean resizeAnim) {
        onSplitScreenEnter();
        if (isSplitActive()) {
            prepareBringSplit(wct, taskInfo, startPosition);
            prepareBringSplit(wct, taskInfo, startPosition, resizeAnim);
        } else {
            prepareActiveSplit(wct, taskInfo, startPosition);
            prepareActiveSplit(wct, taskInfo, startPosition, resizeAnim);
        }
    }

    private void prepareBringSplit(WindowContainerTransaction wct,
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition,
            boolean resizeAnim) {
        if (taskInfo != null) {
            wct.startTask(taskInfo.taskId,
                    resolveStartStage(STAGE_TYPE_UNDEFINED, startPosition, null, wct));
@@ -1483,12 +1491,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            // won't guarantee to put the task to the indicated new position.
            mMainStage.evictAllChildren(wct);
            mMainStage.reparentTopTask(wct);
            prepareSplitLayout(wct);
            prepareSplitLayout(wct, resizeAnim);
        }
    }

    private void prepareActiveSplit(WindowContainerTransaction wct,
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition,
            boolean resizeAnim) {
        if (!ENABLE_SHELL_TRANSITIONS) {
            // Legacy transition we need to create divider here, shell transition case we will
            // create it on #finishEnterSplitScreen
@@ -1499,17 +1508,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            mSideStage.addTask(taskInfo, wct);
        }
        mMainStage.activate(wct, true /* includingTopTask */);
        prepareSplitLayout(wct);
        prepareSplitLayout(wct, resizeAnim);
    }

    private void prepareSplitLayout(WindowContainerTransaction wct) {
        if (mIsDropEntering) {
            mSplitLayout.resetDividerPosition();
        } else {
    private void prepareSplitLayout(WindowContainerTransaction wct, boolean resizeAnim) {
        if (resizeAnim) {
            mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT);
        } else {
            mSplitLayout.resetDividerPosition();
        }
        updateWindowBounds(mSplitLayout, wct);
        if (!mIsDropEntering) {
        if (resizeAnim) {
            // Reset its smallest width dp to avoid is change layout before it actually resized to
            // split bounds.
            wct.setSmallestScreenWidthDp(mMainStage.mRootTaskInfo.token,
@@ -1519,21 +1528,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        setRootForceTranslucent(false, wct);
    }

    void finishEnterSplitScreen(SurfaceControl.Transaction t) {
        mSplitLayout.update(t);
    void finishEnterSplitScreen(SurfaceControl.Transaction finishT) {
        mSplitLayout.update(finishT);
        mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash,
                getMainStageBounds());
        mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash,
                getSideStageBounds());
        setDividerVisibility(true, t);
        setDividerVisibility(true, finishT);
        // Ensure divider surface are re-parented back into the hierarchy at the end of the
        // transition. See Transition#buildFinishTransaction for more detail.
        t.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash);
        finishT.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash);

        updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
        t.show(mRootTaskLeash);
        updateSurfaceBounds(mSplitLayout, finishT, false /* applyResizingOffset */);
        finishT.show(mRootTaskLeash);
        setSplitsVisible(true);
        mIsDropEntering = false;
        mSplitRequest = null;
        updateRecentTasksSplitPair();
        if (!mLogger.hasStartedSession()) {
            mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
Loading