Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java +6 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.wm.shell.dagger.pip; import android.content.Context; import android.os.Handler; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; Loading @@ -41,6 +42,7 @@ import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.common.pip.SizeSpecSource; import com.android.wm.shell.dagger.WMShellBaseModule; import com.android.wm.shell.dagger.WMSingleton; import com.android.wm.shell.desktopmode.DesktopRepository; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.pip.PipAnimationController; import com.android.wm.shell.pip.PipParamsChangedForwarder; Loading Loading @@ -169,6 +171,8 @@ public abstract class Pip1Module { PipParamsChangedForwarder pipParamsChangedForwarder, Optional<SplitScreenController> splitScreenControllerOptional, Optional<PipPerfHintController> pipPerfHintControllerOptional, Optional<DesktopRepository> desktopRepositoryOptional, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, DisplayController displayController, PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer, @ShellMainThread ShellExecutor mainExecutor) { Loading @@ -176,7 +180,8 @@ public abstract class Pip1Module { syncTransactionQueue, pipTransitionState, pipBoundsState, pipDisplayLayoutState, pipBoundsAlgorithm, menuPhoneController, pipAnimationController, pipSurfaceTransactionHelper, pipTransitionController, pipParamsChangedForwarder, splitScreenControllerOptional, pipPerfHintControllerOptional, displayController, splitScreenControllerOptional, pipPerfHintControllerOptional, desktopRepositoryOptional, rootTaskDisplayAreaOrganizer, displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java +5 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.os.SystemClock; import androidx.annotation.NonNull; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; Loading Loading @@ -214,6 +215,7 @@ public abstract class TvPipModule { PipSurfaceTransactionHelper pipSurfaceTransactionHelper, Optional<SplitScreenController> splitScreenControllerOptional, Optional<PipPerfHintController> pipPerfHintControllerOptional, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, DisplayController displayController, PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer, @ShellMainThread ShellExecutor mainExecutor) { Loading @@ -221,8 +223,9 @@ public abstract class TvPipModule { syncTransactionQueue, pipTransitionState, tvPipBoundsState, pipDisplayLayoutState, tvPipBoundsAlgorithm, tvPipMenuController, pipAnimationController, pipSurfaceTransactionHelper, tvPipTransition, pipParamsChangedForwarder, splitScreenControllerOptional, pipPerfHintControllerOptional, displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor); splitScreenControllerOptional, pipPerfHintControllerOptional, rootTaskDisplayAreaOrganizer, displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor); } @WMSingleton Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +11 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,9 @@ class DesktopRepository ( /* Tracks last bounds of task before toggled to stable bounds. */ private val boundsBeforeMaximizeByTaskId = SparseArray<Rect>() /* Tracks last bounds of task before it is minimized. */ private val boundsBeforeMinimizeByTaskId = SparseArray<Rect>() /* Tracks last bounds of task before toggled to immersive state. */ private val boundsBeforeFullImmersiveByTaskId = SparseArray<Rect>() Loading Loading @@ -462,6 +465,14 @@ class DesktopRepository ( fun saveBoundsBeforeMaximize(taskId: Int, bounds: Rect) = boundsBeforeMaximizeByTaskId.set(taskId, Rect(bounds)) /** Removes and returns the bounds saved before minimizing the given task. */ fun removeBoundsBeforeMinimize(taskId: Int): Rect? = boundsBeforeMinimizeByTaskId.removeReturnOld(taskId) /** Saves the bounds of the given task before minimizing. */ fun saveBoundsBeforeMinimize(taskId: Int, bounds: Rect?) = boundsBeforeMinimizeByTaskId.set(taskId, Rect(bounds)) /** Removes and returns the bounds saved before entering immersive with the given task. */ fun removeBoundsBeforeFullImmersive(taskId: Int): Rect? = boundsBeforeFullImmersiveByTaskId.removeReturnOld(taskId) Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt +6 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,12 @@ class DesktopTasksLimiter ( } taskToMinimize.transitionInfo = info activeTransitionTokensAndTasks[transition] = taskToMinimize // Save current bounds before minimizing in case we need to restore to it later. val boundsBeforeMinimize = info.changes.find { change -> change.taskInfo?.taskId == taskToMinimize.taskId }?.startAbsBounds taskRepository.saveBoundsBeforeMinimize(taskToMinimize.taskId, boundsBeforeMinimize) this@DesktopTasksLimiter.minimizeTask( taskToMinimize.displayId, taskToMinimize.taskId) } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +43 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.pip; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; Loading Loading @@ -67,6 +68,7 @@ import android.view.Choreographer; import android.view.Display; import android.view.Surface; import android.view.SurfaceControl; import android.window.DisplayAreaInfo; import android.window.TaskOrganizer; import android.window.TaskSnapshot; import android.window.WindowContainerToken; Loading @@ -74,7 +76,9 @@ import android.window.WindowContainerTransaction; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.window.flags.Flags; import com.android.wm.shell.R; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.ScreenshotUtils; Loading @@ -87,6 +91,7 @@ import com.android.wm.shell.common.pip.PipMenuController; import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.desktopmode.DesktopRepository; import com.android.wm.shell.pip.phone.PipMotionHelper; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.shared.animation.Interpolators; Loading Loading @@ -145,6 +150,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; private final Optional<SplitScreenController> mSplitScreenOptional; @Nullable private final PipPerfHintController mPipPerfHintController; private final Optional<DesktopRepository> mDesktopRepositoryOptional; private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; protected final ShellTaskOrganizer mTaskOrganizer; protected final ShellExecutor mMainExecutor; Loading Loading @@ -388,6 +395,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, @NonNull PipParamsChangedForwarder pipParamsChangedForwarder, Optional<SplitScreenController> splitScreenOptional, Optional<PipPerfHintController> pipPerfHintControllerOptional, Optional<DesktopRepository> desktopRepositoryOptional, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, @NonNull DisplayController displayController, @NonNull PipUiEventLogger pipUiEventLogger, @NonNull ShellTaskOrganizer shellTaskOrganizer, Loading @@ -414,6 +423,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); mSplitScreenOptional = splitScreenOptional; mPipPerfHintController = pipPerfHintControllerOptional.orElse(null); mDesktopRepositoryOptional = desktopRepositoryOptional; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mTaskOrganizer = shellTaskOrganizer; mMainExecutor = mainExecutor; Loading Loading @@ -741,10 +752,23 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } /** Returns the bounds to restore to when exiting PIP mode. */ // TODO(b/377581840): Instead of manually tracking bounds, use bounds from Core. public Rect getExitDestinationBounds() { if (isPipLaunchedInDesktopMode()) { final Rect freeformBounds = mDesktopRepositoryOptional.get().removeBoundsBeforeMinimize( mTaskInfo.taskId); return Objects.requireNonNullElseGet(freeformBounds, mPipBoundsState::getDisplayBounds); } return mPipBoundsState.getDisplayBounds(); } /** Returns whether PiP was launched while in desktop mode. */ // TODO(377581840): Update this check to include non-minimized cases, e.g. split to PiP etc. private boolean isPipLaunchedInDesktopMode() { return Flags.enableDesktopWindowingPip() && mDesktopRepositoryOptional.isPresent() && mDesktopRepositoryOptional.get().isMinimizedTask(mTaskInfo.taskId); } private void exitLaunchIntoPipTask(WindowContainerTransaction wct) { wct.startTask(mTaskInfo.launchIntoPipHostTaskId, null /* ActivityOptions */); mTaskOrganizer.applyTransaction(wct); Loading Loading @@ -1808,7 +1832,25 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, * and can be overridden to restore to an alternate windowing mode. */ public int getOutPipWindowingMode() { // By default, simply reset the windowing mode to undefined. final DisplayAreaInfo tdaInfo = mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo( mTaskInfo.displayId); // If PiP was launched while in desktop mode (we should return the task to freeform // windowing mode): // 1) If the display windowing mode is freeform, set windowing mode to undefined so it will // resolve the windowing mode to the display's windowing mode. // 2) If the display windowing mode is not freeform, set windowing mode to freeform. if (tdaInfo != null && isPipLaunchedInDesktopMode()) { final int displayWindowingMode = tdaInfo.configuration.windowConfiguration.getWindowingMode(); if (displayWindowingMode == WINDOWING_MODE_FREEFORM) { return WINDOWING_MODE_UNDEFINED; } else { return WINDOWING_MODE_FREEFORM; } } // By default, or if the task is going to fullscreen, reset the windowing mode to undefined. return WINDOWING_MODE_UNDEFINED; } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java +6 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.wm.shell.dagger.pip; import android.content.Context; import android.os.Handler; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; Loading @@ -41,6 +42,7 @@ import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.common.pip.SizeSpecSource; import com.android.wm.shell.dagger.WMShellBaseModule; import com.android.wm.shell.dagger.WMSingleton; import com.android.wm.shell.desktopmode.DesktopRepository; import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.pip.PipAnimationController; import com.android.wm.shell.pip.PipParamsChangedForwarder; Loading Loading @@ -169,6 +171,8 @@ public abstract class Pip1Module { PipParamsChangedForwarder pipParamsChangedForwarder, Optional<SplitScreenController> splitScreenControllerOptional, Optional<PipPerfHintController> pipPerfHintControllerOptional, Optional<DesktopRepository> desktopRepositoryOptional, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, DisplayController displayController, PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer, @ShellMainThread ShellExecutor mainExecutor) { Loading @@ -176,7 +180,8 @@ public abstract class Pip1Module { syncTransactionQueue, pipTransitionState, pipBoundsState, pipDisplayLayoutState, pipBoundsAlgorithm, menuPhoneController, pipAnimationController, pipSurfaceTransactionHelper, pipTransitionController, pipParamsChangedForwarder, splitScreenControllerOptional, pipPerfHintControllerOptional, displayController, splitScreenControllerOptional, pipPerfHintControllerOptional, desktopRepositoryOptional, rootTaskDisplayAreaOrganizer, displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/TvPipModule.java +5 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.os.SystemClock; import androidx.annotation.NonNull; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; Loading Loading @@ -214,6 +215,7 @@ public abstract class TvPipModule { PipSurfaceTransactionHelper pipSurfaceTransactionHelper, Optional<SplitScreenController> splitScreenControllerOptional, Optional<PipPerfHintController> pipPerfHintControllerOptional, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, DisplayController displayController, PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer, @ShellMainThread ShellExecutor mainExecutor) { Loading @@ -221,8 +223,9 @@ public abstract class TvPipModule { syncTransactionQueue, pipTransitionState, tvPipBoundsState, pipDisplayLayoutState, tvPipBoundsAlgorithm, tvPipMenuController, pipAnimationController, pipSurfaceTransactionHelper, tvPipTransition, pipParamsChangedForwarder, splitScreenControllerOptional, pipPerfHintControllerOptional, displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor); splitScreenControllerOptional, pipPerfHintControllerOptional, rootTaskDisplayAreaOrganizer, displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor); } @WMSingleton Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +11 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,9 @@ class DesktopRepository ( /* Tracks last bounds of task before toggled to stable bounds. */ private val boundsBeforeMaximizeByTaskId = SparseArray<Rect>() /* Tracks last bounds of task before it is minimized. */ private val boundsBeforeMinimizeByTaskId = SparseArray<Rect>() /* Tracks last bounds of task before toggled to immersive state. */ private val boundsBeforeFullImmersiveByTaskId = SparseArray<Rect>() Loading Loading @@ -462,6 +465,14 @@ class DesktopRepository ( fun saveBoundsBeforeMaximize(taskId: Int, bounds: Rect) = boundsBeforeMaximizeByTaskId.set(taskId, Rect(bounds)) /** Removes and returns the bounds saved before minimizing the given task. */ fun removeBoundsBeforeMinimize(taskId: Int): Rect? = boundsBeforeMinimizeByTaskId.removeReturnOld(taskId) /** Saves the bounds of the given task before minimizing. */ fun saveBoundsBeforeMinimize(taskId: Int, bounds: Rect?) = boundsBeforeMinimizeByTaskId.set(taskId, Rect(bounds)) /** Removes and returns the bounds saved before entering immersive with the given task. */ fun removeBoundsBeforeFullImmersive(taskId: Int): Rect? = boundsBeforeFullImmersiveByTaskId.removeReturnOld(taskId) Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt +6 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,12 @@ class DesktopTasksLimiter ( } taskToMinimize.transitionInfo = info activeTransitionTokensAndTasks[transition] = taskToMinimize // Save current bounds before minimizing in case we need to restore to it later. val boundsBeforeMinimize = info.changes.find { change -> change.taskInfo?.taskId == taskToMinimize.taskId }?.startAbsBounds taskRepository.saveBoundsBeforeMinimize(taskToMinimize.taskId, boundsBeforeMinimize) this@DesktopTasksLimiter.minimizeTask( taskToMinimize.displayId, taskToMinimize.taskId) } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +43 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.pip; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; Loading Loading @@ -67,6 +68,7 @@ import android.view.Choreographer; import android.view.Display; import android.view.Surface; import android.view.SurfaceControl; import android.window.DisplayAreaInfo; import android.window.TaskOrganizer; import android.window.TaskSnapshot; import android.window.WindowContainerToken; Loading @@ -74,7 +76,9 @@ import android.window.WindowContainerTransaction; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.window.flags.Flags; import com.android.wm.shell.R; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.ScreenshotUtils; Loading @@ -87,6 +91,7 @@ import com.android.wm.shell.common.pip.PipMenuController; import com.android.wm.shell.common.pip.PipPerfHintController; import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.desktopmode.DesktopRepository; import com.android.wm.shell.pip.phone.PipMotionHelper; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.shared.animation.Interpolators; Loading Loading @@ -145,6 +150,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; private final Optional<SplitScreenController> mSplitScreenOptional; @Nullable private final PipPerfHintController mPipPerfHintController; private final Optional<DesktopRepository> mDesktopRepositoryOptional; private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; protected final ShellTaskOrganizer mTaskOrganizer; protected final ShellExecutor mMainExecutor; Loading Loading @@ -388,6 +395,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, @NonNull PipParamsChangedForwarder pipParamsChangedForwarder, Optional<SplitScreenController> splitScreenOptional, Optional<PipPerfHintController> pipPerfHintControllerOptional, Optional<DesktopRepository> desktopRepositoryOptional, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, @NonNull DisplayController displayController, @NonNull PipUiEventLogger pipUiEventLogger, @NonNull ShellTaskOrganizer shellTaskOrganizer, Loading @@ -414,6 +423,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); mSplitScreenOptional = splitScreenOptional; mPipPerfHintController = pipPerfHintControllerOptional.orElse(null); mDesktopRepositoryOptional = desktopRepositoryOptional; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mTaskOrganizer = shellTaskOrganizer; mMainExecutor = mainExecutor; Loading Loading @@ -741,10 +752,23 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } /** Returns the bounds to restore to when exiting PIP mode. */ // TODO(b/377581840): Instead of manually tracking bounds, use bounds from Core. public Rect getExitDestinationBounds() { if (isPipLaunchedInDesktopMode()) { final Rect freeformBounds = mDesktopRepositoryOptional.get().removeBoundsBeforeMinimize( mTaskInfo.taskId); return Objects.requireNonNullElseGet(freeformBounds, mPipBoundsState::getDisplayBounds); } return mPipBoundsState.getDisplayBounds(); } /** Returns whether PiP was launched while in desktop mode. */ // TODO(377581840): Update this check to include non-minimized cases, e.g. split to PiP etc. private boolean isPipLaunchedInDesktopMode() { return Flags.enableDesktopWindowingPip() && mDesktopRepositoryOptional.isPresent() && mDesktopRepositoryOptional.get().isMinimizedTask(mTaskInfo.taskId); } private void exitLaunchIntoPipTask(WindowContainerTransaction wct) { wct.startTask(mTaskInfo.launchIntoPipHostTaskId, null /* ActivityOptions */); mTaskOrganizer.applyTransaction(wct); Loading Loading @@ -1808,7 +1832,25 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, * and can be overridden to restore to an alternate windowing mode. */ public int getOutPipWindowingMode() { // By default, simply reset the windowing mode to undefined. final DisplayAreaInfo tdaInfo = mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo( mTaskInfo.displayId); // If PiP was launched while in desktop mode (we should return the task to freeform // windowing mode): // 1) If the display windowing mode is freeform, set windowing mode to undefined so it will // resolve the windowing mode to the display's windowing mode. // 2) If the display windowing mode is not freeform, set windowing mode to freeform. if (tdaInfo != null && isPipLaunchedInDesktopMode()) { final int displayWindowingMode = tdaInfo.configuration.windowConfiguration.getWindowingMode(); if (displayWindowingMode == WINDOWING_MODE_FREEFORM) { return WINDOWING_MODE_UNDEFINED; } else { return WINDOWING_MODE_FREEFORM; } } // By default, or if the task is going to fullscreen, reset the windowing mode to undefined. return WINDOWING_MODE_UNDEFINED; } Loading