summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2023-04-28 20:04:51 +0800
committer Riddle Hsu <riddlehsu@google.com> 2023-05-02 23:49:35 +0800
commitfb6a72dd59ebdebe3a12e85bb2f130db27f932f3 (patch)
tree834545dba3c85a2314f0ddc3f91da6087cfa3706
parent357dfbc115f0a0143e363b5865d4a134073d9b8f (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
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java33
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java8
-rw-r--r--services/core/java/com/android/server/wm/Transition.java2
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();