Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.kt +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.window.DesktopExperienceFlags import android.window.DesktopModeFlags import com.android.wm.shell.Flags import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.desktopmode.DesktopUserRepositories import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler import java.util.Optional Loading Loading @@ -93,4 +94,7 @@ class PipDesktopState( /** Returns whether there is a drag-to-desktop transition in progress. */ fun isDragToDesktopInProgress(): Boolean = isDesktopWindowingPipEnabled() && dragToDesktopTransitionHandlerOptional.get().inProgress /** Returns the DisplayLayout associated with the display where PiP window is in. */ fun getCurrentDisplayLayout(): DisplayLayout = pipDisplayLayoutState.displayLayout } libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +7 −3 Original line number Diff line number Diff line Loading @@ -153,10 +153,12 @@ public abstract class Pip2Module { @ShellMainThread ShellExecutor mainExecutor, PipTransitionState pipTransitionState, Optional<SplitScreenController> splitScreenControllerOptional, Optional<DesktopPipTransitionController> desktopPipTransitionController, PipDesktopState pipDesktopState, DisplayController displayController) { return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState, splitScreenControllerOptional, pipDesktopState, displayController); splitScreenControllerOptional, desktopPipTransitionController, pipDesktopState, displayController); } @WMSingleton Loading Loading @@ -259,14 +261,16 @@ public abstract class Pip2Module { @WMSingleton @Provides static Optional<DesktopPipTransitionController> provideDesktopPipTransitionController( Context context, Optional<DesktopTasksController> desktopTasksControllerOptional, Context context, ShellTaskOrganizer shellTaskOrganizer, Optional<DesktopTasksController> desktopTasksControllerOptional, Optional<DesktopUserRepositories> desktopUserRepositoriesOptional, PipDesktopState pipDesktopState ) { if (DesktopModeStatus.canEnterDesktopMode(context) && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()) { return Optional.of( new DesktopPipTransitionController(desktopTasksControllerOptional.get(), new DesktopPipTransitionController(shellTaskOrganizer, desktopTasksControllerOptional.get(), desktopUserRepositoriesOptional.get(), pipDesktopState)); } return Optional.empty(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionController.kt +53 −3 Original line number Diff line number Diff line Loading @@ -17,21 +17,71 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager import android.app.ActivityTaskManager import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.graphics.Rect import android.os.IBinder import android.window.DesktopExperienceFlags import android.window.WindowContainerTransaction import com.android.internal.protolog.ProtoLog import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.common.pip.PipDesktopState import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE /** * Controller to perform extra handling to PiP transitions that are entering while in Desktop mode. */ /** Controller to perform extra handling to PiP transitions while in Desktop mode. */ class DesktopPipTransitionController( private val shellTaskOrganizer: ShellTaskOrganizer, private val desktopTasksController: DesktopTasksController, private val desktopUserRepositories: DesktopUserRepositories, private val pipDesktopState: PipDesktopState, ) { /** * This is called by [PipScheduler#getExitPipViaExpandTransaction] before starting a PiP * transition. In the case of multi-activity PiP, we might need to update the parent task's * windowing mode and bounds based on whether we are in Desktop Windowing. * * @param wct WindowContainerTransaction that will apply these changes * @param parentTaskId id taken from TaskInfo#lastParentTaskIdBeforePip */ fun maybeUpdateParentInWct(wct: WindowContainerTransaction, parentTaskId: Int) { if (!pipDesktopState.isDesktopWindowingPipEnabled()) { return } if (parentTaskId == ActivityTaskManager.INVALID_TASK_ID) { logD("maybeUpdateParentInWct: Task is not multi-activity PiP") return } val parentTask = shellTaskOrganizer.getRunningTaskInfo(parentTaskId) if (parentTask == null) { logW( "maybeUpdateParentInWct: Failed to find RunningTaskInfo for parentTaskId %d", parentTaskId, ) return } val defaultFreeformBounds = if (parentTask.lastNonFullscreenBounds.isEmpty) { calculateDefaultDesktopTaskBounds(pipDesktopState.getCurrentDisplayLayout()) } else { parentTask.lastNonFullscreenBounds } val newResolvedWinMode = if (pipDesktopState.isPipInDesktopMode()) WINDOWING_MODE_FREEFORM else WINDOWING_MODE_FULLSCREEN if (newResolvedWinMode != parentTask.windowingMode) { wct.setWindowingMode(parentTask.token, newResolvedWinMode) wct.setBounds( parentTask.token, if (newResolvedWinMode == WINDOWING_MODE_FREEFORM) defaultFreeformBounds else Rect() ) } } /** * This is called by [PipTransition#handleRequest] when a request for entering PiP is received. Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +10 −2 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import com.android.wm.shell.common.ScreenshotUtils; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipDesktopState; import com.android.wm.shell.desktopmode.DesktopPipTransitionController; import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; import com.android.wm.shell.pip2.animation.PipAlphaAnimator; Loading Loading @@ -72,6 +73,7 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange private final PipTransitionState mPipTransitionState; private final DisplayController mDisplayController; private final PipDesktopState mPipDesktopState; private final Optional<DesktopPipTransitionController> mDesktopPipTransitionController; private final Optional<SplitScreenController> mSplitScreenControllerOptional; private PipTransitionController mPipTransitionController; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory Loading @@ -89,6 +91,7 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange ShellExecutor mainExecutor, PipTransitionState pipTransitionState, Optional<SplitScreenController> splitScreenControllerOptional, Optional<DesktopPipTransitionController> desktopPipTransitionController, PipDesktopState pipDesktopState, DisplayController displayController) { mContext = context; Loading @@ -97,6 +100,7 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this); mPipDesktopState = pipDesktopState; mDesktopPipTransitionController = desktopPipTransitionController; mSplitScreenControllerOptional = splitScreenControllerOptional; mDisplayController = displayController; mSurfaceControlTransactionFactory = Loading @@ -118,9 +122,13 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange WindowContainerTransaction wct = new WindowContainerTransaction(); // final expanded bounds to be inherited from the parent wct.setBounds(pipTaskToken, null); // if we are hitting a multi-activity case // windowing mode change will reparent to original host task wct.setWindowingMode(pipTaskToken, mPipDesktopState.getOutPipWindowingMode()); // In multi-activity case, windowing mode change will reparent to original host task, so we // have to update the parent windowing mode to what is expected. mDesktopPipTransitionController.ifPresent(c -> c.maybeUpdateParentInWct(wct, mPipTransitionState.getPipTaskInfo().lastParentTaskIdBeforePip)); return wct; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandler.java +55 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.wm.shell.pip2.phone.transition; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.Surface.ROTATION_0; import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getChangeByToken; Loading Loading @@ -191,13 +193,23 @@ public class PipExpandHandler implements Transitions.TransitionHandler { PipExpandAnimator animator = mPipExpandAnimatorSupplier.get(mContext, pipLeash, startTransaction, finishTransaction, endBounds, startBounds, endBounds, sourceRectHint, delta, mPipDesktopState.isPipInDesktopMode()); animator.setAnimationStartCallback(() -> mPipInteractionHandler.begin(pipLeash, PipInteractionHandler.INTERACTION_EXIT_PIP)); animator.setAnimationStartCallback(() -> { mPipInteractionHandler.begin(pipLeash, PipInteractionHandler.INTERACTION_EXIT_PIP); if (parentBeforePip != null) { setupMultiActivityExpandAnimation(info, startTransaction, pipLeash, parentBeforePip); } }); final TransitionInfo.Change finalPipChange = pipChange; animator.setAnimationEndCallback(() -> { if (parentBeforePip != null) { // TODO b/377362511: Animate local leash instead to also handle letterbox case. // For multi-activity, set the crop to be null finishTransaction.setCrop(pipLeash, null); setupMultiActivityAnimationFinalState(finishTransaction, finalPipChange, pipLeash, parentBeforePip); } finishTransition(); mPipInteractionHandler.end(); Loading @@ -207,6 +219,47 @@ public class PipExpandHandler implements Transitions.TransitionHandler { return true; } private void setupMultiActivityExpandAnimation(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl pipLeash, @NonNull TransitionInfo.Change parentBeforePip) { if (!mPipDesktopState.isDesktopWindowingPipEnabled()) { return; } final int rootIndex = info.findRootIndex(mPipDisplayLayoutState.getDisplayId()); final int parentWindowingMode = parentBeforePip.getTaskInfo().getWindowingMode(); if (rootIndex != -1 && parentWindowingMode == WINDOWING_MODE_FREEFORM) { // Reparent PiP activity to the root leash if it's animating to freeform so that it is // not cropped by the parent task. SurfaceControl rootLeash = info.getRoot(rootIndex).getLeash(); startTransaction.reparent(pipLeash, rootLeash); startTransaction.setAlpha(parentBeforePip.getLeash(), 0); } else if (parentWindowingMode == WINDOWING_MODE_FULLSCREEN) { // Don't animate the parent task; show it immediately when the PiP animation finishes parentBeforePip.setStartAbsBounds(parentBeforePip.getEndAbsBounds()); startTransaction.setPosition(parentBeforePip.getLeash(), parentBeforePip.getStartAbsBounds().left, parentBeforePip.getStartAbsBounds().top); startTransaction.setCrop(parentBeforePip.getLeash(), parentBeforePip.getEndAbsBounds()); } } private void setupMultiActivityAnimationFinalState( @NonNull SurfaceControl.Transaction finishTransaction, @NonNull TransitionInfo.Change pipChange, @NonNull SurfaceControl pipLeash, @NonNull TransitionInfo.Change parentBeforePip) { if (!mPipDesktopState.isDesktopWindowingPipEnabled() || parentBeforePip.getTaskInfo().getWindowingMode() != WINDOWING_MODE_FREEFORM) { return; } // Reparent the PiP activity to the parent task and reset its position finishTransaction.reparent(pipLeash, parentBeforePip.getLeash()); finishTransaction.setPosition(pipLeash, pipChange.getEndRelOffset().x, pipChange.getEndRelOffset().y); finishTransaction.setAlpha(parentBeforePip.getLeash(), 1); } private boolean startExpandToSplitAnimation(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDesktopState.kt +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.window.DesktopExperienceFlags import android.window.DesktopModeFlags import com.android.wm.shell.Flags import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.desktopmode.DesktopUserRepositories import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler import java.util.Optional Loading Loading @@ -93,4 +94,7 @@ class PipDesktopState( /** Returns whether there is a drag-to-desktop transition in progress. */ fun isDragToDesktopInProgress(): Boolean = isDesktopWindowingPipEnabled() && dragToDesktopTransitionHandlerOptional.get().inProgress /** Returns the DisplayLayout associated with the display where PiP window is in. */ fun getCurrentDisplayLayout(): DisplayLayout = pipDisplayLayoutState.displayLayout }
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +7 −3 Original line number Diff line number Diff line Loading @@ -153,10 +153,12 @@ public abstract class Pip2Module { @ShellMainThread ShellExecutor mainExecutor, PipTransitionState pipTransitionState, Optional<SplitScreenController> splitScreenControllerOptional, Optional<DesktopPipTransitionController> desktopPipTransitionController, PipDesktopState pipDesktopState, DisplayController displayController) { return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState, splitScreenControllerOptional, pipDesktopState, displayController); splitScreenControllerOptional, desktopPipTransitionController, pipDesktopState, displayController); } @WMSingleton Loading Loading @@ -259,14 +261,16 @@ public abstract class Pip2Module { @WMSingleton @Provides static Optional<DesktopPipTransitionController> provideDesktopPipTransitionController( Context context, Optional<DesktopTasksController> desktopTasksControllerOptional, Context context, ShellTaskOrganizer shellTaskOrganizer, Optional<DesktopTasksController> desktopTasksControllerOptional, Optional<DesktopUserRepositories> desktopUserRepositoriesOptional, PipDesktopState pipDesktopState ) { if (DesktopModeStatus.canEnterDesktopMode(context) && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()) { return Optional.of( new DesktopPipTransitionController(desktopTasksControllerOptional.get(), new DesktopPipTransitionController(shellTaskOrganizer, desktopTasksControllerOptional.get(), desktopUserRepositoriesOptional.get(), pipDesktopState)); } return Optional.empty(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionController.kt +53 −3 Original line number Diff line number Diff line Loading @@ -17,21 +17,71 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager import android.app.ActivityTaskManager import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.graphics.Rect import android.os.IBinder import android.window.DesktopExperienceFlags import android.window.WindowContainerTransaction import com.android.internal.protolog.ProtoLog import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.common.pip.PipDesktopState import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE /** * Controller to perform extra handling to PiP transitions that are entering while in Desktop mode. */ /** Controller to perform extra handling to PiP transitions while in Desktop mode. */ class DesktopPipTransitionController( private val shellTaskOrganizer: ShellTaskOrganizer, private val desktopTasksController: DesktopTasksController, private val desktopUserRepositories: DesktopUserRepositories, private val pipDesktopState: PipDesktopState, ) { /** * This is called by [PipScheduler#getExitPipViaExpandTransaction] before starting a PiP * transition. In the case of multi-activity PiP, we might need to update the parent task's * windowing mode and bounds based on whether we are in Desktop Windowing. * * @param wct WindowContainerTransaction that will apply these changes * @param parentTaskId id taken from TaskInfo#lastParentTaskIdBeforePip */ fun maybeUpdateParentInWct(wct: WindowContainerTransaction, parentTaskId: Int) { if (!pipDesktopState.isDesktopWindowingPipEnabled()) { return } if (parentTaskId == ActivityTaskManager.INVALID_TASK_ID) { logD("maybeUpdateParentInWct: Task is not multi-activity PiP") return } val parentTask = shellTaskOrganizer.getRunningTaskInfo(parentTaskId) if (parentTask == null) { logW( "maybeUpdateParentInWct: Failed to find RunningTaskInfo for parentTaskId %d", parentTaskId, ) return } val defaultFreeformBounds = if (parentTask.lastNonFullscreenBounds.isEmpty) { calculateDefaultDesktopTaskBounds(pipDesktopState.getCurrentDisplayLayout()) } else { parentTask.lastNonFullscreenBounds } val newResolvedWinMode = if (pipDesktopState.isPipInDesktopMode()) WINDOWING_MODE_FREEFORM else WINDOWING_MODE_FULLSCREEN if (newResolvedWinMode != parentTask.windowingMode) { wct.setWindowingMode(parentTask.token, newResolvedWinMode) wct.setBounds( parentTask.token, if (newResolvedWinMode == WINDOWING_MODE_FREEFORM) defaultFreeformBounds else Rect() ) } } /** * This is called by [PipTransition#handleRequest] when a request for entering PiP is received. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +10 −2 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import com.android.wm.shell.common.ScreenshotUtils; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipDesktopState; import com.android.wm.shell.desktopmode.DesktopPipTransitionController; import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; import com.android.wm.shell.pip2.animation.PipAlphaAnimator; Loading Loading @@ -72,6 +73,7 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange private final PipTransitionState mPipTransitionState; private final DisplayController mDisplayController; private final PipDesktopState mPipDesktopState; private final Optional<DesktopPipTransitionController> mDesktopPipTransitionController; private final Optional<SplitScreenController> mSplitScreenControllerOptional; private PipTransitionController mPipTransitionController; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory Loading @@ -89,6 +91,7 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange ShellExecutor mainExecutor, PipTransitionState pipTransitionState, Optional<SplitScreenController> splitScreenControllerOptional, Optional<DesktopPipTransitionController> desktopPipTransitionController, PipDesktopState pipDesktopState, DisplayController displayController) { mContext = context; Loading @@ -97,6 +100,7 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this); mPipDesktopState = pipDesktopState; mDesktopPipTransitionController = desktopPipTransitionController; mSplitScreenControllerOptional = splitScreenControllerOptional; mDisplayController = displayController; mSurfaceControlTransactionFactory = Loading @@ -118,9 +122,13 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange WindowContainerTransaction wct = new WindowContainerTransaction(); // final expanded bounds to be inherited from the parent wct.setBounds(pipTaskToken, null); // if we are hitting a multi-activity case // windowing mode change will reparent to original host task wct.setWindowingMode(pipTaskToken, mPipDesktopState.getOutPipWindowingMode()); // In multi-activity case, windowing mode change will reparent to original host task, so we // have to update the parent windowing mode to what is expected. mDesktopPipTransitionController.ifPresent(c -> c.maybeUpdateParentInWct(wct, mPipTransitionState.getPipTaskInfo().lastParentTaskIdBeforePip)); return wct; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipExpandHandler.java +55 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.wm.shell.pip2.phone.transition; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.Surface.ROTATION_0; import static com.android.wm.shell.pip2.phone.transition.PipTransitionUtils.getChangeByToken; Loading Loading @@ -191,13 +193,23 @@ public class PipExpandHandler implements Transitions.TransitionHandler { PipExpandAnimator animator = mPipExpandAnimatorSupplier.get(mContext, pipLeash, startTransaction, finishTransaction, endBounds, startBounds, endBounds, sourceRectHint, delta, mPipDesktopState.isPipInDesktopMode()); animator.setAnimationStartCallback(() -> mPipInteractionHandler.begin(pipLeash, PipInteractionHandler.INTERACTION_EXIT_PIP)); animator.setAnimationStartCallback(() -> { mPipInteractionHandler.begin(pipLeash, PipInteractionHandler.INTERACTION_EXIT_PIP); if (parentBeforePip != null) { setupMultiActivityExpandAnimation(info, startTransaction, pipLeash, parentBeforePip); } }); final TransitionInfo.Change finalPipChange = pipChange; animator.setAnimationEndCallback(() -> { if (parentBeforePip != null) { // TODO b/377362511: Animate local leash instead to also handle letterbox case. // For multi-activity, set the crop to be null finishTransaction.setCrop(pipLeash, null); setupMultiActivityAnimationFinalState(finishTransaction, finalPipChange, pipLeash, parentBeforePip); } finishTransition(); mPipInteractionHandler.end(); Loading @@ -207,6 +219,47 @@ public class PipExpandHandler implements Transitions.TransitionHandler { return true; } private void setupMultiActivityExpandAnimation(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl pipLeash, @NonNull TransitionInfo.Change parentBeforePip) { if (!mPipDesktopState.isDesktopWindowingPipEnabled()) { return; } final int rootIndex = info.findRootIndex(mPipDisplayLayoutState.getDisplayId()); final int parentWindowingMode = parentBeforePip.getTaskInfo().getWindowingMode(); if (rootIndex != -1 && parentWindowingMode == WINDOWING_MODE_FREEFORM) { // Reparent PiP activity to the root leash if it's animating to freeform so that it is // not cropped by the parent task. SurfaceControl rootLeash = info.getRoot(rootIndex).getLeash(); startTransaction.reparent(pipLeash, rootLeash); startTransaction.setAlpha(parentBeforePip.getLeash(), 0); } else if (parentWindowingMode == WINDOWING_MODE_FULLSCREEN) { // Don't animate the parent task; show it immediately when the PiP animation finishes parentBeforePip.setStartAbsBounds(parentBeforePip.getEndAbsBounds()); startTransaction.setPosition(parentBeforePip.getLeash(), parentBeforePip.getStartAbsBounds().left, parentBeforePip.getStartAbsBounds().top); startTransaction.setCrop(parentBeforePip.getLeash(), parentBeforePip.getEndAbsBounds()); } } private void setupMultiActivityAnimationFinalState( @NonNull SurfaceControl.Transaction finishTransaction, @NonNull TransitionInfo.Change pipChange, @NonNull SurfaceControl pipLeash, @NonNull TransitionInfo.Change parentBeforePip) { if (!mPipDesktopState.isDesktopWindowingPipEnabled() || parentBeforePip.getTaskInfo().getWindowingMode() != WINDOWING_MODE_FREEFORM) { return; } // Reparent the PiP activity to the parent task and reset its position finishTransaction.reparent(pipLeash, parentBeforePip.getLeash()); finishTransaction.setPosition(pipLeash, pipChange.getEndRelOffset().x, pipChange.getEndRelOffset().y); finishTransaction.setAlpha(parentBeforePip.getLeash(), 1); } private boolean startExpandToSplitAnimation(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, Loading