Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f38a646c authored by Merissa Mitchell's avatar Merissa Mitchell Committed by Android (Google) Code Review
Browse files

Merge "[PIP on Desktop] Restore task to freeform bounds when exiting PiP." into main

parents 191db8cd 84627d98
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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) {
@@ -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);
    }

+5 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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) {
@@ -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
+11 −0
Original line number Diff line number Diff line
@@ -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>()

@@ -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)
+6 −0
Original line number Diff line number Diff line
@@ -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)
        }
+43 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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;

@@ -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,
@@ -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;

@@ -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);
@@ -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