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

Commit 526dbe40 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 0c3f17d6 3b1ad3eb
Loading
Loading
Loading
Loading
+21 −25
Original line number Original line Diff line number Diff line
@@ -534,17 +534,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
            return;
            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 displayBounds = mPipBoundsState.getDisplayBounds();
        final Rect destinationBounds = new Rect(displayBounds);
        final Rect destinationBounds = new Rect(displayBounds);
        final int direction = syncWithSplitScreenBounds(destinationBounds, requestEnterSplit)
        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
        // 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
        // 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.
        // 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
        if (Transitions.SHELL_TRANSITIONS_ROTATION) {
                && !toFullscreen)) {
            // When exit to fullscreen with Shell transition enabled, we update the Task windowing
            // 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
            // mode directly so that it can also trigger display rotation and visibility update in
            // the same transition if there will be any.
            // the same transition if there will be any.
@@ -588,9 +575,29 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        mPipTransitionState.setTransitionState(PipTransitionState.EXITING_PIP);
        mPipTransitionState.setTransitionState(PipTransitionState.EXITING_PIP);


        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
        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);
            mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct, destinationBounds);
            return;
            return;
        }
        }

        if (mSplitScreenOptional.isPresent()) {
        if (mSplitScreenOptional.isPresent()) {
            // If pip activity will reparent to origin task case and if the origin task still under
            // 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.
            // 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() {
    private boolean isPipToTopLeft() {
        if (!mSplitScreenOptional.isPresent()) {
        if (!mSplitScreenOptional.isPresent()) {
            return false;
            return false;
+1 −6
Original line number Original line Diff line number Diff line
@@ -989,12 +989,7 @@ public class PipTransition extends PipTransitionController {
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback,
            @NonNull Transitions.TransitionFinishCallback finishCallback,
            @NonNull TaskInfo taskInfo) {
            @NonNull TaskInfo taskInfo) {
        final int changeSize = info.getChanges().size();
        for (int i = info.getChanges().size() - 1; i >= 0; i--) {
        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--) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            final TransitionInfo.Change change = info.getChanges().get(i);
            final int mode = change.getMode();
            final int mode = change.getMode();


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


import com.android.wm.shell.ShellTaskOrganizer;
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.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.transition.Transitions;


@@ -223,6 +224,13 @@ public abstract class PipTransitionController implements Transitions.TransitionH
        return false;
        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. */
    /** Add PiP-related changes to `outWCT` for the given request. */
    public void augmentRequest(@NonNull IBinder transition,
    public void augmentRequest(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request, @NonNull WindowContainerTransaction outWCT) {
            @NonNull TransitionRequestInfo request, @NonNull WindowContainerTransaction outWCT) {
+31 −7
Original line number Original line 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.draganddrop.DragAndDropPolicy;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.recents.RecentTasksController;
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.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellController;
@@ -332,6 +333,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
        return mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED;
        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. */
    /** Check split is foreground and task is under split or not by taskId. */
    public boolean isTaskInSplitScreenForeground(int taskId) {
    public boolean isTaskInSplitScreenForeground(int taskId) {
        return isTaskInSplitScreen(taskId) && isSplitScreenVisible();
        return isTaskInSplitScreen(taskId) && isSplitScreenVisible();
@@ -378,17 +384,35 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
        mStageCoordinator.setSideStagePosition(sideStagePosition, null /* wct */);
        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,
    public void prepareEnterSplitScreen(WindowContainerTransaction wct,
            ActivityManager.RunningTaskInfo taskInfo, int startPosition) {
            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) {
    public void enterSplitScreen(int taskId, boolean leftOrTop, WindowContainerTransaction wct) {
+34 −24
Original line number Original line Diff line number Diff line
@@ -389,7 +389,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,


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


        final WindowContainerTransaction wct = new WindowContainerTransaction();
        final WindowContainerTransaction wct = new WindowContainerTransaction();

        options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
        options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
        wct.sendPendingIntent(intent, fillInIntent, options);
        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.
        // If split screen is not activated, we're expecting to open a pair of apps to split.
        final int extraTransitType = mMainStage.isActive()
        final int extraTransitType = mMainStage.isActive()
                ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
                ? 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,
        mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
                extraTransitType, !mIsDropEntering);
                extraTransitType, !mIsDropEntering);
@@ -557,7 +563,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        if (isEnteringSplit && mLogger.isEnterRequestedByDrag()) {
        if (isEnteringSplit && mLogger.isEnterRequestedByDrag()) {
            updateWindowBounds(mSplitLayout, wct);
            updateWindowBounds(mSplitLayout, wct);
        }
        }
        mSplitRequest = new SplitRequest(intent.getIntent(), position);
        wct.sendPendingIntent(intent, fillInIntent, options);
        wct.sendPendingIntent(intent, fillInIntent, options);
        mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
        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
     * an existing WindowContainerTransaction (rather than applying immediately). This is intended
     * to be used when exiting split might be bundled with other window operations.
     * 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) {
            @NonNull WindowContainerTransaction wct) {
        if (!mMainStage.isActive()) return;
        if (!mMainStage.isActive()) return;
        mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
        mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
@@ -1453,7 +1458,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    }
    }


    private void prepareEnterSplitScreen(WindowContainerTransaction wct) {
    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.
     * into side stage.
     */
     */
    void prepareEnterSplitScreen(WindowContainerTransaction wct,
    void prepareEnterSplitScreen(WindowContainerTransaction wct,
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition,
            boolean resizeAnim) {
        onSplitScreenEnter();
        onSplitScreenEnter();
        if (isSplitActive()) {
        if (isSplitActive()) {
            prepareBringSplit(wct, taskInfo, startPosition);
            prepareBringSplit(wct, taskInfo, startPosition, resizeAnim);
        } else {
        } else {
            prepareActiveSplit(wct, taskInfo, startPosition);
            prepareActiveSplit(wct, taskInfo, startPosition, resizeAnim);
        }
        }
    }
    }


    private void prepareBringSplit(WindowContainerTransaction wct,
    private void prepareBringSplit(WindowContainerTransaction wct,
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
            @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition,
            boolean resizeAnim) {
        if (taskInfo != null) {
        if (taskInfo != null) {
            wct.startTask(taskInfo.taskId,
            wct.startTask(taskInfo.taskId,
                    resolveStartStage(STAGE_TYPE_UNDEFINED, startPosition, null, wct));
                    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.
            // won't guarantee to put the task to the indicated new position.
            mMainStage.evictAllChildren(wct);
            mMainStage.evictAllChildren(wct);
            mMainStage.reparentTopTask(wct);
            mMainStage.reparentTopTask(wct);
            prepareSplitLayout(wct);
            prepareSplitLayout(wct, resizeAnim);
        }
        }
    }
    }


    private void prepareActiveSplit(WindowContainerTransaction wct,
    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) {
        if (!ENABLE_SHELL_TRANSITIONS) {
            // Legacy transition we need to create divider here, shell transition case we will
            // Legacy transition we need to create divider here, shell transition case we will
            // create it on #finishEnterSplitScreen
            // create it on #finishEnterSplitScreen
@@ -1499,17 +1508,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            mSideStage.addTask(taskInfo, wct);
            mSideStage.addTask(taskInfo, wct);
        }
        }
        mMainStage.activate(wct, true /* includingTopTask */);
        mMainStage.activate(wct, true /* includingTopTask */);
        prepareSplitLayout(wct);
        prepareSplitLayout(wct, resizeAnim);
    }
    }


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


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


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