diff options
| author | 2023-04-28 20:04:51 +0800 | |
|---|---|---|
| committer | 2023-05-02 23:49:35 +0800 | |
| commit | fb6a72dd59ebdebe3a12e85bb2f130db27f932f3 (patch) | |
| tree | 834545dba3c85a2314f0ddc3f91da6087cfa3706 | |
| parent | 357dfbc115f0a0143e363b5865d4a134073d9b8f (diff) | |
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
3 files changed, 35 insertions, 8 deletions
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; diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index d531ad175f10..af2050fa662a 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -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(); |