Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.kt +3 −1 Original line number Diff line number Diff line Loading @@ -46,10 +46,12 @@ class PipDesktopState( /** * Returns whether PiP in Connected Displays is enabled by checking the following: * - PiP in Desktop Windowing is enabled * - PiP in Connected Displays flag is enabled * - PiP2 flag is enabled */ fun isConnectedDisplaysPipEnabled(): Boolean = isDesktopWindowingPipEnabled() && DesktopExperienceFlags.ENABLE_CONNECTED_DISPLAYS_PIP.isTrue && Flags.enablePip2() /** Returns whether the display with the PiP task is in freeform windowing mode. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +46 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.Nullable; import com.android.internal.protolog.ProtoLog; import com.android.internal.util.Preconditions; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.ComponentUtils; Loading @@ -80,6 +81,7 @@ import com.android.wm.shell.pip2.animation.PipAlphaAnimator; import com.android.wm.shell.pip2.animation.PipEnterAnimator; import com.android.wm.shell.pip2.phone.transition.PipExpandHandler; import com.android.wm.shell.pip2.phone.transition.PipTransitionUtils; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.shared.TransitionUtil; import com.android.wm.shell.splitscreen.SplitScreenController; import com.android.wm.shell.sysui.ShellInit; Loading Loading @@ -300,6 +302,10 @@ public class PipTransition extends PipTransitionController implements // playing PiP transitions, so reset those transforms if needed. prepareOtherTargetTransforms(info, startTransaction, finishTransaction); // This PiP transition might have caused a previous PiP to be dismissed. If so, we need // to clean up the PiP state. cleanUpPrevPipIfPresent(info, startTransaction, finishTransaction); // Update the PipTransitionState while supplying the PiP leash and token to be cached. Bundle extra = new Bundle(); extra.putParcelable(PIP_TASK_LEASH, pipChange.getLeash()); Loading Loading @@ -931,6 +937,46 @@ public class PipTransition extends PipTransitionController implements } } /** * This is called by [startAnimation] when a enter PiP transition is received, and before * mPipTransitionState is updated with the incoming PiP task info. If a change is found * for the previous PiP with change TO_BACK, the previous PiP was dismissed by Core. We want to * update the state in PipTransitionState so everything is cleaned up and also ensure the * previous PiP is no longer visible. */ private void cleanUpPrevPipIfPresent(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTx, @NonNull SurfaceControl.Transaction finishTx) { TransitionInfo.Change previousPipChange = null; TaskInfo previousPipTaskInfo = mPipTransitionState.getPipTaskInfo(); if (previousPipTaskInfo == null) { return; } for (TransitionInfo.Change change : info.getChanges()) { if (change.getTaskInfo() != null && change.getTaskInfo().getTaskId() == previousPipTaskInfo.getTaskId() && TransitionUtil.isClosingMode(change.getMode())) { previousPipChange = change; break; } } if (previousPipChange == null) { return; } ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "cleanUpPrevPipIfPresent: Previous PiP with taskId=%d found with closing mode, " + "clean up PiP state", previousPipTaskInfo.getTaskId()); mPipTransitionState.setState(PipTransitionState.EXITING_PIP); mPipTransitionState.setState(PipTransitionState.EXITED_PIP); startTx.setAlpha(previousPipChange.getLeash(), 0); finishTx.setAlpha(previousPipChange.getLeash(), 0); } /** * Sets the type of animation to run upon entering PiP. * Loading services/core/java/com/android/server/wm/RootWindowContainer.java +10 −6 Original line number Diff line number Diff line Loading @@ -2069,13 +2069,17 @@ class RootWindowContainer extends WindowContainer<DisplayContent> try { // This will change the root pinned task's windowing mode to its original mode, ensuring // we only have one root task that is in pinned mode. final Task rootPinnedTask = taskDisplayArea.getRootPinnedTask(); if (rootPinnedTask != null) { transitionController.collect(rootPinnedTask); // The new ActivityRecord should replace the existing PiP, so it's more desirable // that the old PiP disappears instead of turning to full-screen at the same time, // as the Task#dismissPip is trying to do. if (ActivityTaskManagerService.isPip2ExperimentEnabled()) { removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED); } else { final Task rootPinnedTask = taskDisplayArea.getRootPinnedTask(); if (rootPinnedTask != null) { transitionController.collect(rootPinnedTask); removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED); } } transitionController.collect(task); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.kt +3 −1 Original line number Diff line number Diff line Loading @@ -46,10 +46,12 @@ class PipDesktopState( /** * Returns whether PiP in Connected Displays is enabled by checking the following: * - PiP in Desktop Windowing is enabled * - PiP in Connected Displays flag is enabled * - PiP2 flag is enabled */ fun isConnectedDisplaysPipEnabled(): Boolean = isDesktopWindowingPipEnabled() && DesktopExperienceFlags.ENABLE_CONNECTED_DISPLAYS_PIP.isTrue && Flags.enablePip2() /** Returns whether the display with the PiP task is in freeform windowing mode. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +46 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.Nullable; import com.android.internal.protolog.ProtoLog; import com.android.internal.util.Preconditions; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.ComponentUtils; Loading @@ -80,6 +81,7 @@ import com.android.wm.shell.pip2.animation.PipAlphaAnimator; import com.android.wm.shell.pip2.animation.PipEnterAnimator; import com.android.wm.shell.pip2.phone.transition.PipExpandHandler; import com.android.wm.shell.pip2.phone.transition.PipTransitionUtils; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.shared.TransitionUtil; import com.android.wm.shell.splitscreen.SplitScreenController; import com.android.wm.shell.sysui.ShellInit; Loading Loading @@ -300,6 +302,10 @@ public class PipTransition extends PipTransitionController implements // playing PiP transitions, so reset those transforms if needed. prepareOtherTargetTransforms(info, startTransaction, finishTransaction); // This PiP transition might have caused a previous PiP to be dismissed. If so, we need // to clean up the PiP state. cleanUpPrevPipIfPresent(info, startTransaction, finishTransaction); // Update the PipTransitionState while supplying the PiP leash and token to be cached. Bundle extra = new Bundle(); extra.putParcelable(PIP_TASK_LEASH, pipChange.getLeash()); Loading Loading @@ -931,6 +937,46 @@ public class PipTransition extends PipTransitionController implements } } /** * This is called by [startAnimation] when a enter PiP transition is received, and before * mPipTransitionState is updated with the incoming PiP task info. If a change is found * for the previous PiP with change TO_BACK, the previous PiP was dismissed by Core. We want to * update the state in PipTransitionState so everything is cleaned up and also ensure the * previous PiP is no longer visible. */ private void cleanUpPrevPipIfPresent(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTx, @NonNull SurfaceControl.Transaction finishTx) { TransitionInfo.Change previousPipChange = null; TaskInfo previousPipTaskInfo = mPipTransitionState.getPipTaskInfo(); if (previousPipTaskInfo == null) { return; } for (TransitionInfo.Change change : info.getChanges()) { if (change.getTaskInfo() != null && change.getTaskInfo().getTaskId() == previousPipTaskInfo.getTaskId() && TransitionUtil.isClosingMode(change.getMode())) { previousPipChange = change; break; } } if (previousPipChange == null) { return; } ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "cleanUpPrevPipIfPresent: Previous PiP with taskId=%d found with closing mode, " + "clean up PiP state", previousPipTaskInfo.getTaskId()); mPipTransitionState.setState(PipTransitionState.EXITING_PIP); mPipTransitionState.setState(PipTransitionState.EXITED_PIP); startTx.setAlpha(previousPipChange.getLeash(), 0); finishTx.setAlpha(previousPipChange.getLeash(), 0); } /** * Sets the type of animation to run upon entering PiP. * Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +10 −6 Original line number Diff line number Diff line Loading @@ -2069,13 +2069,17 @@ class RootWindowContainer extends WindowContainer<DisplayContent> try { // This will change the root pinned task's windowing mode to its original mode, ensuring // we only have one root task that is in pinned mode. final Task rootPinnedTask = taskDisplayArea.getRootPinnedTask(); if (rootPinnedTask != null) { transitionController.collect(rootPinnedTask); // The new ActivityRecord should replace the existing PiP, so it's more desirable // that the old PiP disappears instead of turning to full-screen at the same time, // as the Task#dismissPip is trying to do. if (ActivityTaskManagerService.isPip2ExperimentEnabled()) { removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED); } else { final Task rootPinnedTask = taskDisplayArea.getRootPinnedTask(); if (rootPinnedTask != null) { transitionController.collect(rootPinnedTask); removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED); } } transitionController.collect(task); Loading