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

Commit 9e1e1a13 authored by Vania Desmonda's avatar Vania Desmonda
Browse files

Redirect launching app from PiP on another display to PipExpandHandler.

This allows the task that went into PiP to be launched in the default
windowing mode of the other display.

Video: http://recall/-/eJKbR8nWsDdR7iqlcyUtXB/bC6SS5oP2HCertOS940IOr

Flag: com.android.window.flags.enable_cross_displays_pip_task_launch
Fixes: 424569682
Test: atest PipExpandHandlerTest
Test: atest WMShellFlickerServicePipTests:ExitPipToAppViaIntentTest
Change-Id: Iaf0770902e232fb8ccc006f371f4e32e7dcf0f27
parent c99ad1bf
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -288,10 +288,16 @@ public class PipController implements ConfigurationChangeListener,
            public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
                    boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                        "onActivityRestartAttempt: topActivity=%s, wasVisible=%b",
                        task.topActivity, wasVisible);
                        "onActivityRestartAttempt: topActivity=%s, wasVisible=%b, displayId=%s, "
                                + "pipDisplayLayoutState#displayId=%s",
                        task.topActivity, wasVisible, task.displayId,
                        mPipDisplayLayoutState.getDisplayId());
                boolean keepPipFromLockscreen = !wasVisible && !Flags.dismissPipFromLockscreen();
                if (task.getWindowingMode() != WINDOWING_MODE_PINNED || keepPipFromLockscreen) {
                boolean isPipLaunchingOnDifferentDisplay =
                        DesktopExperienceFlags.ENABLE_CROSS_DISPLAYS_PIP_TASK_LAUNCH.isTrue()
                                && task.displayId != mPipDisplayLayoutState.getDisplayId();
                if (task.getWindowingMode() != WINDOWING_MODE_PINNED || keepPipFromLockscreen
                        || isPipLaunchingOnDifferentDisplay) {
                    return;
                }
                mPipScheduler.scheduleExitPipViaExpand(wasVisible);
+20 −0
Original line number Diff line number Diff line
@@ -146,6 +146,26 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange
        return wct;
    }

    /**
     * Returns a wct for exiting PiP and expanding on a different display.
     */
    @Nullable
    public WindowContainerTransaction getExitPipViaExpandIntoDisplayTransaction(int displayId) {
        WindowContainerToken pipToken = mPipTransitionState.getPipTaskToken();
        WindowContainerTransaction wct = getExitPipViaExpandTransaction();
        DisplayAreaInfo displayAreaInfo =
                mPipDesktopState.getRootTaskDisplayAreaOrganizer().getDisplayAreaInfo(
                        displayId);

        if (pipToken == null || wct == null || displayAreaInfo == null) {
            return null;
        }

        wct.reparent(pipToken, displayAreaInfo.token, true);
        wct.setDensityDpi(pipToken, displayAreaInfo.configuration.densityDpi);
        return wct;
    }

    @Nullable
    private WindowContainerTransaction getRemovePipTransaction() {
        WindowContainerToken pipTaskToken = mPipTransitionState.getPipTaskToken();
+9 −1
Original line number Diff line number Diff line
@@ -195,7 +195,7 @@ public class PipTransition extends PipTransitionController implements
        mExpandHandler = new PipExpandHandler(mContext, mPipSurfaceTransactionHelper,
                pipBoundsState, pipBoundsAlgorithm,
                pipTransitionState, pipDisplayLayoutState, pipDesktopState, pipInteractionHandler,
                splitScreenControllerOptional);
                pipScheduler, splitScreenControllerOptional, displayController);
        mContentPipHandler = new ContentPipHandler(mContext, mPipSurfaceTransactionHelper,
                pipTransitionState);
        mPipDisplayChangeObserver = new PipDisplayChangeObserver(pipTransitionState,
@@ -279,6 +279,14 @@ public class PipTransition extends PipTransitionController implements
            );
            return wct;
        }

        final WindowContainerTransaction exitViaExpandWct = mExpandHandler.handleRequest(transition,
                request);
        if (exitViaExpandWct != null) {
            mExitViaExpandTransition = transition;
            return exitViaExpandWct;
        }

        return null;
    }

+1 −1
Original line number Diff line number Diff line
@@ -381,7 +381,7 @@ public class PipTransitionState {
                ? new SurfaceControl(leash, "PipTransitionState") : null;
    }

    @Nullable TaskInfo getPipTaskInfo() {
    @Nullable public TaskInfo getPipTaskInfo() {
        return mPipTaskInfo;
    }

+48 −2
Original line number Diff line number Diff line
@@ -33,12 +33,14 @@ import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP_TO_SP
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.PictureInPictureParams;
import android.content.Context;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.Surface;
import android.view.SurfaceControl;
import android.window.DesktopExperienceFlags;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerToken;
@@ -46,6 +48,7 @@ import android.window.WindowContainerTransaction;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipDesktopState;
@@ -53,8 +56,10 @@ import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip2.animation.PipExpandAnimator;
import com.android.wm.shell.pip2.phone.PipInteractionHandler;
import com.android.wm.shell.pip2.phone.PipScheduler;
import com.android.wm.shell.pip2.phone.PipTransitionState;
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.transition.Transitions;

@@ -68,13 +73,21 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
    private final PipDisplayLayoutState mPipDisplayLayoutState;
    private final PipDesktopState mPipDesktopState;
    private final PipInteractionHandler mPipInteractionHandler;
    private final PipScheduler mPipScheduler;
    private final Optional<SplitScreenController> mSplitScreenControllerOptional;
    private final DisplayController mDisplayController;

    @Nullable
    private Transitions.TransitionFinishCallback mFinishCallback;
    @Nullable
    private ValueAnimator mTransitionAnimator;

    //
    // Transition caches
    //
    @Nullable
    @VisibleForTesting IBinder mExitViaExpandTransition;

    private PipExpandAnimatorSupplier mPipExpandAnimatorSupplier;
    private final @NonNull PipSurfaceTransactionHelper mSurfaceTransactionHelper;

@@ -86,7 +99,9 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
            PipDisplayLayoutState pipDisplayLayoutState,
            PipDesktopState pipDesktopState,
            PipInteractionHandler pipInteractionHandler,
            Optional<SplitScreenController> splitScreenControllerOptional) {
            PipScheduler pipScheduler,
            Optional<SplitScreenController> splitScreenControllerOptional,
            DisplayController displayController) {
        mContext = context;
        mPipBoundsState = pipBoundsState;
        mPipBoundsAlgorithm = pipBoundsAlgorithm;
@@ -94,8 +109,10 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
        mPipDisplayLayoutState = pipDisplayLayoutState;
        mPipDesktopState = pipDesktopState;
        mPipInteractionHandler = pipInteractionHandler;
        mPipScheduler = pipScheduler;
        mSplitScreenControllerOptional = splitScreenControllerOptional;
        mSurfaceTransactionHelper = pipSurfaceTransactionHelper;
        mDisplayController = displayController;

        mPipExpandAnimatorSupplier = PipExpandAnimator::new;
    }
@@ -108,10 +125,34 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
    @Override
    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request) {
        // All Exit-via-Expand from PiP transitions are Shell initiated.
        ActivityManager.RunningTaskInfo taskInfo = request.getTriggerTask();
        if (taskInfo == null) {
            return null;
        }

        // Launching the task while it's in PiP on another display
        if (isLaunchingPipActivityFromDifferentDisplay(request, taskInfo)) {
            mExitViaExpandTransition = transition;
            return mPipScheduler.getExitPipViaExpandIntoDisplayTransaction(taskInfo.displayId);
        }
        return null;
    }

    /** Whether the task that's currently in PiP is being launched on another display. */
    private boolean isLaunchingPipActivityFromDifferentDisplay(
            @NonNull TransitionRequestInfo request, ActivityManager.RunningTaskInfo taskInfo) {
        if (mPipTransitionState.getPipTaskInfo() == null) {
            return false;
        }

        return DesktopExperienceFlags.ENABLE_CROSS_DISPLAYS_PIP_TASK_LAUNCH.isTrue()
                && TransitionUtil.isOpeningType(request.getType())
                && mPipTransitionState.getPipTaskInfo().taskId == taskInfo.taskId
                && mPipTransitionState.getPipTaskInfo().topActivity != null
                && mPipTransitionState.getPipTaskInfo().topActivity.equals(taskInfo.topActivity)
                && taskInfo.displayId != mPipDisplayLayoutState.getDisplayId();
    }

    @Override
    public boolean startAnimation(@NonNull IBinder transition,
            @NonNull TransitionInfo info,
@@ -126,6 +167,11 @@ public class PipExpandHandler implements Transitions.TransitionHandler {
                return startExpandToSplitAnimation(info, startTransaction, finishTransaction,
                        finishCallback);
        }

        if (transition == mExitViaExpandTransition) {
            mExitViaExpandTransition = null;
            return startExpandAnimation(info, startTransaction, finishTransaction, finishCallback);
        }
        return false;
    }

Loading