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

Commit 0983e9b9 authored by Hongwei Wang's avatar Hongwei Wang Committed by Android (Google) Code Review
Browse files

Merge "Add tabletop mode support to PiP2" into main

parents 570a91f0 9c003a1d
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -29,7 +29,9 @@ import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TabletopModeController;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.pip.PhonePipKeepClearAlgorithm;
import com.android.wm.shell.common.pip.PipAppOpsListener;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
@@ -138,6 +140,8 @@ public abstract class Pip2Module {
            PhonePipMenuController pipMenuController,
            PipUiEventLogger pipUiEventLogger,
            PipMediaController pipMediaController,
            TabletopModeController tabletopModeController,
            PhonePipKeepClearAlgorithm pipKeepClearAlgorithm,
            PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
            @ShellMainThread ShellExecutor mainExecutor) {
        if (!PipUtils.isPip2ExperimentEnabled()) {
@@ -148,8 +152,8 @@ public abstract class Pip2Module {
                    displayInsetsController, pipBoundsState, pipBoundsAlgorithm,
                    pipDisplayLayoutState, pipScheduler, taskStackListener, shellTaskOrganizer,
                    pipTransitionState, pipTouchHandler, pipAppOpsListener, pipMenuController,
                    pipUiEventLogger, pipMediaController, pipSurfaceTransactionHelper,
                    mainExecutor));
                    pipUiEventLogger, pipMediaController, tabletopModeController,
                    pipKeepClearAlgorithm, pipSurfaceTransactionHelper, mainExecutor));
        }
    }

+57 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
@@ -56,6 +57,7 @@ import com.android.wm.shell.common.NavigationBarsListener;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SingleInstanceRemoteListener;
import com.android.wm.shell.common.TabletopModeController;
import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.pip.IPip;
@@ -64,6 +66,7 @@ import com.android.wm.shell.common.pip.PipAppOpsListener;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.common.pip.PipKeepClearAlgorithmInterface;
import com.android.wm.shell.common.pip.PipMediaController;
import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.PipUtils;
@@ -108,6 +111,8 @@ public class PipController implements ConfigurationChangeListener,
    private final PipTouchHandler mPipTouchHandler;
    private final PipAppOpsListener mPipAppOpsListener;
    private final PhonePipMenuController mPipMenuController;
    private final TabletopModeController mTabletopModeController;
    private final PipKeepClearAlgorithmInterface mPipKeepClearAlgorithm;
    private final PipUiEventLogger mPipUiEventLogger;
    private final ShellExecutor mMainExecutor;
    private final PipImpl mImpl;
@@ -161,6 +166,8 @@ public class PipController implements ConfigurationChangeListener,
            PhonePipMenuController pipMenuController,
            PipUiEventLogger pipUiEventLogger,
            PipMediaController pipMediaController,
            TabletopModeController tabletopModeController,
            PipKeepClearAlgorithmInterface pipKeepClearAlgorithm,
            PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
            ShellExecutor mainExecutor) {
        mContext = context;
@@ -181,6 +188,8 @@ public class PipController implements ConfigurationChangeListener,
        mPipMenuController = pipMenuController;
        mPipUiEventLogger = pipUiEventLogger;
        mMediaController = pipMediaController;
        mTabletopModeController = tabletopModeController;
        mPipKeepClearAlgorithm = pipKeepClearAlgorithm;
        mPipSurfaceTransactionHelper = pipSurfaceTransactionHelper;
        mMainExecutor = mainExecutor;
        mImpl = new PipImpl();
@@ -211,6 +220,8 @@ public class PipController implements ConfigurationChangeListener,
            PhonePipMenuController pipMenuController,
            PipUiEventLogger pipUiEventLogger,
            PipMediaController pipMediaController,
            TabletopModeController tabletopModeController,
            PipKeepClearAlgorithmInterface pipKeepClearAlgorithm,
            PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
            ShellExecutor mainExecutor) {
        if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
@@ -222,8 +233,8 @@ public class PipController implements ConfigurationChangeListener,
                displayController, displayInsetsController, pipBoundsState, pipBoundsAlgorithm,
                pipDisplayLayoutState, pipScheduler, taskStackListener, shellTaskOrganizer,
                pipTransitionState, pipTouchHandler, pipAppOpsListener, pipMenuController,
                pipUiEventLogger, pipMediaController, pipSurfaceTransactionHelper,
                mainExecutor);
                pipUiEventLogger, pipMediaController, tabletopModeController,
                pipKeepClearAlgorithm, pipSurfaceTransactionHelper, mainExecutor);
    }

    public PipImpl getPipImpl() {
@@ -276,6 +287,50 @@ public class PipController implements ConfigurationChangeListener,
            }
        });

        mTabletopModeController.registerOnTabletopModeChangedListener((isInTabletopMode) -> {
            if (!isInTabletopMode) {
                mPipBoundsState.setNamedUnrestrictedKeepClearArea(
                        PipBoundsState.NAMED_KCA_TABLETOP_MODE, null);
                return;
            }

            // To prepare for the entry bounds.
            final Rect displayBounds = mPipBoundsState.getDisplayBounds();
            if (mTabletopModeController.getPreferredHalfInTabletopMode()
                    == TabletopModeController.PREFERRED_TABLETOP_HALF_TOP) {
                // Prefer top, avoid the bottom half of the display.
                mPipBoundsState.setNamedUnrestrictedKeepClearArea(
                        PipBoundsState.NAMED_KCA_TABLETOP_MODE, new Rect(
                                displayBounds.left, displayBounds.centerY(),
                                displayBounds.right, displayBounds.bottom));
            } else {
                // Prefer bottom, avoid the top half of the display.
                mPipBoundsState.setNamedUnrestrictedKeepClearArea(
                        PipBoundsState.NAMED_KCA_TABLETOP_MODE, new Rect(
                                displayBounds.left, displayBounds.top,
                                displayBounds.right, displayBounds.centerY()));
            }

            // Try to move the PiP window if we have entered PiP mode.
            if (mPipTransitionState.isInPip()) {
                final Rect pipBounds = mPipBoundsState.getBounds();
                final Point edgeInsets = mPipDisplayLayoutState.getScreenEdgeInsets();
                if ((pipBounds.height() + 2 * edgeInsets.y) > (displayBounds.height() / 2)) {
                    // PiP bounds is too big to fit either half, bail early.
                    return;
                }
                Rect destBounds = mPipKeepClearAlgorithm.adjust(mPipBoundsState,
                        mPipBoundsAlgorithm);
                // only move if the bounds are actually different
                if (!destBounds.equals(mPipBoundsState.getBounds())) {
                    ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                            "Move PiP from %s to %s on tabletop mode change",
                            mPipBoundsState.getBounds(), destBounds);
                    mPipTouchHandler.getMotionHelper().moveToBounds(destBounds);
                }
            }
        });

        mPipAppOpsListener.setCallback(mPipTouchHandler.getMotionHelper());
    }