From fb6a72dd59ebdebe3a12e85bb2f130db27f932f3 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Fri, 28 Apr 2023 20:04:51 +0800 Subject: 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 --- .../com/android/wm/shell/pip/PipTaskOrganizer.java | 33 +++++++++++++++++----- .../com/android/wm/shell/pip/PipTransition.java | 8 ++++++ 2 files changed, 34 insertions(+), 7 deletions(-) (limited to 'libs') diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index 566c130c7573..642aee9dd90f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -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,14 +1789,26 @@ 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); - destinationBoundsOut.set(isPipToTopLeft() ? topLeft : bottomRight); - return true; + 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; } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index 99cb6f782d01..98db707d1105 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -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; -- cgit v1.2.3-59-g8ed1b