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

Commit f3de83a7 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Integrate pip to split flow with shell-transition"

parents e7b34993 e5d8c806
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -309,10 +309,11 @@ public class WMShellModule {
            PipAnimationController pipAnimationController, PipBoundsAlgorithm pipBoundsAlgorithm,
            PipBoundsState pipBoundsState, PipTransitionState pipTransitionState,
            PhonePipMenuController pipMenuController,
            PipSurfaceTransactionHelper pipSurfaceTransactionHelper) {
            PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
            Optional<SplitScreenController> splitScreenOptional) {
        return new PipTransition(context, pipBoundsState, pipTransitionState, pipMenuController,
                pipBoundsAlgorithm, pipAnimationController, transitions, shellTaskOrganizer,
                pipSurfaceTransactionHelper);
                pipSurfaceTransactionHelper, splitScreenOptional);
    }

    @WMSingleton
+23 −3
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import static android.util.RotationUtils.rotateBounds;

import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP;
import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString;
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.pip.PipAnimationController.ANIM_TYPE_ALPHA;
import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_BOUNDS;
import static com.android.wm.shell.pip.PipAnimationController.FRACTION_START;
@@ -40,6 +42,10 @@ import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTI
import static com.android.wm.shell.pip.PipAnimationController.isInPipDirection;
import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection;
import static com.android.wm.shell.pip.PipAnimationController.isRemovePipDirection;
import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP_TO_SPLIT;
import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -394,6 +400,18 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        mPipUiEventLoggerLogger.log(
                PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN);
        final WindowContainerTransaction wct = new WindowContainerTransaction();

        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 destinationBounds = mPipBoundsState.getDisplayBounds();
        final int direction = syncWithSplitScreenBounds(destinationBounds, requestEnterSplit)
                ? TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
@@ -414,7 +432,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        mPipTransitionState.setTransitionState(PipTransitionState.EXITING_PIP);

        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
            mPipTransitionController.startTransition(destinationBounds, wct);
            mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct, destinationBounds);
            return;
        }
        mSyncTransactionQueue.queue(wct);
@@ -479,7 +497,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
            wct.setBounds(mToken, null);
            wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
            wct.reorder(mToken, false);
            mPipTransitionController.startTransition(null, wct);
            mPipTransitionController.startExitTransition(TRANSIT_REMOVE_PIP, wct,
                    null /* destinationBounds */);
            return;
        }

@@ -1280,7 +1299,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
    public void applyFinishBoundsResize(@NonNull WindowContainerTransaction wct,
            @PipAnimationController.TransitionDirection int direction, boolean wasPipTopLeft) {
        if (direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
            mSplitScreenOptional.get().enterSplitScreen(mTaskInfo.taskId, wasPipTopLeft, wct);
            mSplitScreenOptional.ifPresent(splitScreenController ->
                    splitScreenController.enterSplitScreen(mTaskInfo.taskId, wasPipTopLeft, wct));
        } else {
            mTaskOrganizer.applyTransaction(wct);
        }
+56 −10
Original line number Diff line number Diff line
@@ -30,8 +30,9 @@ import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTI
import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
import static com.android.wm.shell.pip.PipAnimationController.isInPipDirection;
import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection;
import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP_TO_SPLIT;
import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP;
import static com.android.wm.shell.transition.Transitions.isOpeningType;

import android.app.ActivityManager;
import android.app.TaskInfo;
@@ -51,8 +52,11 @@ import androidx.annotation.Nullable;

import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.transition.Transitions;

import java.util.Optional;

/**
 * Implementation of transitions for PiP on phone. Responsible for enter (alpha, bounds) and
 * exit animation.
@@ -64,6 +68,7 @@ public class PipTransition extends PipTransitionController {
    private final PipTransitionState mPipTransitionState;
    private final int mEnterExitAnimationDuration;
    private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
    private final Optional<SplitScreenController> mSplitScreenOptional;
    private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
    private Transitions.TransitionFinishCallback mFinishCallback;
    private Rect mExitDestinationBounds = new Rect();
@@ -77,13 +82,15 @@ public class PipTransition extends PipTransitionController {
            PipAnimationController pipAnimationController,
            Transitions transitions,
            @NonNull ShellTaskOrganizer shellTaskOrganizer,
            PipSurfaceTransactionHelper pipSurfaceTransactionHelper) {
            PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
            Optional<SplitScreenController> splitScreenOptional) {
        super(pipBoundsState, pipMenuController, pipBoundsAlgorithm,
                pipAnimationController, transitions, shellTaskOrganizer);
        mPipTransitionState = pipTransitionState;
        mEnterExitAnimationDuration = context.getResources()
                .getInteger(R.integer.config_pipResizeAnimationDuration);
        mSurfaceTransactionHelper = pipSurfaceTransactionHelper;
        mSplitScreenOptional = splitScreenOptional;
    }

    @Override
@@ -101,13 +108,12 @@ public class PipTransition extends PipTransitionController {
    }

    @Override
    public void startTransition(Rect destinationBounds, WindowContainerTransaction out) {
    public void startExitTransition(int type, WindowContainerTransaction out,
            @Nullable Rect destinationBounds) {
        if (destinationBounds != null) {
            mExitDestinationBounds.set(destinationBounds);
            mExitTransition = mTransitions.startTransition(TRANSIT_EXIT_PIP, out, this);
        } else {
            mTransitions.startTransition(TRANSIT_REMOVE_PIP, out, this);
        }
        mExitTransition = mTransitions.startTransition(type, out, this);
    }

    @Override
@@ -116,9 +122,15 @@ public class PipTransition extends PipTransitionController {
            @android.annotation.NonNull SurfaceControl.Transaction startTransaction,
            @android.annotation.NonNull SurfaceControl.Transaction finishTransaction,
            @android.annotation.NonNull Transitions.TransitionFinishCallback finishCallback) {

        if (mExitTransition == transition || info.getType() == TRANSIT_EXIT_PIP) {
        final int type = info.getType();
        if (mExitTransition == transition) {
            mExitTransition = null;

            if (type == TRANSIT_EXIT_PIP_TO_SPLIT) {
                return startExitToSplitAnimation(
                        info, startTransaction, finishTransaction, finishCallback);
            }

            if (info.getChanges().size() == 1) {
                if (mFinishCallback != null) {
                    mFinishCallback.onTransitionFinished(null, null);
@@ -138,7 +150,7 @@ public class PipTransition extends PipTransitionController {
            }
        }

        if (info.getType() == TRANSIT_REMOVE_PIP) {
        if (type == TRANSIT_REMOVE_PIP) {
            if (mFinishCallback != null) {
                mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */);
                mFinishCallback = null;
@@ -154,7 +166,7 @@ public class PipTransition extends PipTransitionController {

        // We only support TRANSIT_PIP type (from RootWindowContainer) or TRANSIT_OPEN (from apps
        // that enter PiP instantly on opening, mostly from CTS/Flicker tests)
        if (info.getType() != TRANSIT_PIP && info.getType() != TRANSIT_OPEN) {
        if (type != TRANSIT_PIP && type != TRANSIT_OPEN) {
            // In case the PIP window is part of rotation transition, reset the bounds and rounded
            // corner.
            for (int i = info.getChanges().size() - 1; i >= 0; --i) {
@@ -368,6 +380,40 @@ public class PipTransition extends PipTransitionController {
        return true;
    }

    private boolean startExitToSplitAnimation(TransitionInfo info,
            SurfaceControl.Transaction startTransaction,
            SurfaceControl.Transaction finishTransaction,
            Transitions.TransitionFinishCallback finishCallback) {
        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--) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            final int mode = change.getMode();

            if (mode == TRANSIT_CHANGE && change.getParent() != null) {
                // TODO: perform resize/expand animation for reparented child task.
                continue;
            }

            if (isOpeningType(mode) && change.getParent() == null) {
                final SurfaceControl leash = change.getLeash();
                final Rect endBounds = change.getEndAbsBounds();
                startTransaction
                        .show(leash)
                        .setAlpha(leash, 1f)
                        .setPosition(leash, endBounds.left, endBounds.top)
                        .setWindowCrop(leash, endBounds.width(), endBounds.height());
            }
        }
        mSplitScreenOptional.get().finishEnterSplitScreen(startTransaction);
        startTransaction.apply();
        finishCallback.onTransitionFinished(null, null);
        return true;
    }

    private void finishResizeForMenu(Rect destinationBounds) {
        mPipMenuController.movePipMenu(null, null, destinationBounds);
        mPipMenuController.updateMenuBounds(destinationBounds);
+4 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;

import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_REMOVE_STACK;

import android.annotation.Nullable;
import android.app.PictureInPictureParams;
import android.app.TaskInfo;
import android.content.ComponentName;
@@ -98,9 +99,10 @@ public abstract class PipTransitionController implements Transitions.TransitionH
    }

    /**
     * Called when the Shell wants to starts a transition/animation.
     * Called when the Shell wants to start an exit Pip transition/animation.
     */
    public void startTransition(Rect destinationBounds, WindowContainerTransaction out) {
    public void startExitTransition(int type, WindowContainerTransaction out,
            @Nullable Rect destinationBounds) {
        // Default implementation does nothing.
    }

+9 −0
Original line number Diff line number Diff line
@@ -239,6 +239,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
        enterSplitScreen(taskId, leftOrTop, new WindowContainerTransaction());
    }

    public void prepareEnterSplitScreen(WindowContainerTransaction wct,
            ActivityManager.RunningTaskInfo taskInfo, int startPosition) {
        mStageCoordinator.prepareEnterSplitScreen(wct, taskInfo, startPosition);
    }

    public void finishEnterSplitScreen(SurfaceControl.Transaction t) {
        mStageCoordinator.finishEnterSplitScreen(t);
    }

    public void enterSplitScreen(int taskId, boolean leftOrTop, WindowContainerTransaction wct) {
        final int stageType = isSplitScreenVisible() ? STAGE_TYPE_UNDEFINED : STAGE_TYPE_SIDE;
        final int stagePosition =
Loading