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

Commit fb6a72dd authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Set fullscreen mode to task at the end of exit-pip animation

This restores to legacy behavior for pip-to-fullscreen:
 Animation starts: set activity to fullscreen
 Animation ends: set task to fullscreen
Otherwise the app will receive the callbacks immediately:
(see ActivityRecord#canReceiveKeys,isFocusable,
 Task#onConfigurationChangedInner
 TaskSupervisor#scheduleUpdatePictureInPictureModeIfNeeded)
 - onResumed
 - onWindowFocusChanged
 - onPictureInPictureModeChanged
And then the app may trigger more actions to disturb the
animation, e.g. toggle global UI mode, start/finish activity,
change requested orientation.

Another approach is to add workaround in WM core to skip the
events if the activity is in exit-pip transition, and then
invoke them at the end of transition.

Bug: 273177981
Test: Expand PiP to fullscreen, the lifecycle callbacks of the
      PiP are called at the end of animation.
Change-Id: Ia9a17c6ea471016c28bfc10afeb37cc13e6c0999
parent 357dfbc1
Loading
Loading
Loading
Loading
+26 −7
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ 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.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
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;
@@ -531,12 +532,18 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
            }
        }

        final Rect destinationBounds = getExitDestinationBounds();
        final Rect displayBounds = mPipBoundsState.getDisplayBounds();
        final Rect destinationBounds = new Rect(displayBounds);
        final int direction = syncWithSplitScreenBounds(destinationBounds, requestEnterSplit)
                ? TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
                : TRANSITION_DIRECTION_LEAVE_PIP;
        // 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.ENABLE_SHELL_TRANSITIONS && direction == TRANSITION_DIRECTION_LEAVE_PIP) {
        if (Transitions.SHELL_TRANSITIONS_ROTATION || (Transitions.ENABLE_SHELL_TRANSITIONS
                && !toFullscreen)) {
            // 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.
@@ -612,7 +619,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        removePip();
    }

    private void applyWindowingModeChangeOnExit(WindowContainerTransaction wct, int direction) {
    void applyWindowingModeChangeOnExit(WindowContainerTransaction wct, int direction) {
        // Reset the final windowing mode.
        wct.setWindowingMode(mToken, getOutPipWindowingMode());
        // Simply reset the activity mode set prior to the animation running.
@@ -1782,15 +1789,27 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
     * @return {@code true} if destinationBounds is altered for split screen
     */
    private boolean syncWithSplitScreenBounds(Rect destinationBoundsOut, boolean enterSplit) {
        if (!enterSplit || !mSplitScreenOptional.isPresent()) {
        if (mSplitScreenOptional.isEmpty()) {
            return false;
        }
        final SplitScreenController split = mSplitScreenOptional.get();
        final int position = mTaskInfo.lastParentTaskIdBeforePip > 0
                ? split.getSplitPosition(mTaskInfo.lastParentTaskIdBeforePip)
                : SPLIT_POSITION_UNDEFINED;
        if (position == SPLIT_POSITION_UNDEFINED && !enterSplit) {
            return false;
        }
        final Rect topLeft = new Rect();
        final Rect bottomRight = new Rect();
        mSplitScreenOptional.get().getStageBounds(topLeft, bottomRight);
        split.getStageBounds(topLeft, bottomRight);
        if (enterSplit) {
            destinationBoundsOut.set(isPipToTopLeft() ? topLeft : bottomRight);
            return true;
        }
        // Moving to an existing split task.
        destinationBoundsOut.set(position == SPLIT_POSITION_TOP_OR_LEFT ? topLeft : bottomRight);
        return false;
    }

    /**
     * Fades out and removes an overlay surface.
+8 −0
Original line number Diff line number Diff line
@@ -508,8 +508,16 @@ public class PipTransition extends PipTransitionController {
        currentBounds.offset(-offset.x, -offset.y);
        startTransaction.setPosition(pipLeash, currentBounds.left, currentBounds.top);

        final WindowContainerToken pipTaskToken = pipChange.getContainer();
        final boolean toFullscreen = pipChange.getEndAbsBounds().equals(
                mPipBoundsState.getDisplayBounds());
        mFinishCallback = (wct, wctCB) -> {
            mPipOrganizer.onExitPipFinished(taskInfo);
            if (!Transitions.SHELL_TRANSITIONS_ROTATION && toFullscreen) {
                wct = wct != null ? wct : new WindowContainerTransaction();
                wct.setBounds(pipTaskToken, null);
                mPipOrganizer.applyWindowingModeChangeOnExit(wct, TRANSITION_DIRECTION_LEAVE_PIP);
            }
            finishCallback.onTransitionFinished(wct, wctCB);
        };
        mFinishTransaction = finishTransaction;
+1 −1
Original line number Diff line number Diff line
@@ -2198,7 +2198,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
                        // Display won't be rotated for multi window Task, so the fixed rotation
                        // won't be applied. This can happen when the windowing mode is changed
                        // before the previous fixed rotation is applied.
                        && !task.inMultiWindowMode()) {
                        && (!task.inMultiWindowMode() || !topRunningActivity.inMultiWindowMode())) {
                    // If Activity is in fixed rotation, its will be applied with the next rotation,
                    // when the Task is still in the previous rotation.
                    final int taskRotation = task.getWindowConfiguration().getDisplayRotation();