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

Commit baadd8b6 authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

[PiP2] Prevent double enter PiP

Prevent PiP entry being scheduled if there
is one scheduled already and it hasn't started playing yet.

Make sure we restore the internal state if a scheduled-enter-pip
transition gets aborted, so that we can re-enter PiP in a follow-up
session.

Also refactored the content-pip filter checks with
a new PipUtils utility.

Bug: 420614827
Flag: com.android.wm.shell.enable_pip2
Test: atest PinnedStackTests
Test: manually enter content PiP in multiple quick successions.
Change-Id: Idaeaf032120df21cee7dab44fd0d4ca2d5dbe8b9
parent bf0fa11b
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.wm.shell.common.pip

import android.app.ActivityTaskManager
import android.app.RemoteAction
import android.app.TaskInfo
import android.app.WindowConfiguration
import android.content.ComponentName
import android.content.Context
@@ -234,6 +235,12 @@ object PipUtils {
        outPos.set(startActPosInTaskEndX, startActPosInTaskEndY)
    }

    @JvmStatic
    fun isContentPip(pipTaskInfo: TaskInfo?): Boolean {
        if (pipTaskInfo == null) return false
        return pipTaskInfo.launchIntoPipHostTaskId != -1
    }

    /**
     * Calculates the transform and crop to apply on a Task surface in order for the config-at-end
     * activity inside it (original-size activity transformed to match it's hint rect to the final
+1 −1
Original line number Diff line number Diff line
@@ -611,7 +611,7 @@ public class PipController implements ConfigurationChangeListener,
                    mPipUiEventLogger.log(
                            PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_AUTO_ENTER);
                    mPipTransitionState.resetSwipePipToHomeState();
                } else if (taskInfo != null && taskInfo.launchIntoPipHostTaskId != -1) {
                } else if (PipUtils.isContentPip(taskInfo)) {
                    mPipUiEventLogger.log(
                            PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER_CONTENT_PIP);
                } else {
+2 −3
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.common.pip.PipPerfHintController;
import com.android.wm.shell.common.pip.PipSnapAlgorithm;
import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip2.animation.PipResizeAnimator;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -361,9 +362,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
        cancelPhysicsAnimation();
        mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);

        boolean isContentPip = mPipTransitionState.getPipTaskInfo() != null
                && mPipTransitionState.getPipTaskInfo().launchIntoPipHostTaskId != -1;
        if (isContentPip) {
        if (PipUtils.isContentPip(mPipTransitionState.getPipTaskInfo())) {
            mPipScheduler.scheduleRemovePip(true /* withFadeout */);
        } else {
            mPipScheduler.scheduleExitPipViaExpand();
+2 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ 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.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.desktopmode.DesktopPipTransitionController;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
@@ -156,7 +157,7 @@ public class PipScheduler implements PipTransitionState.PipTransitionStateChange
        wct.reorder(pipTaskToken, false);

        final TaskInfo pipTaskInfo = mPipTransitionState.getPipTaskInfo();
        if (pipTaskInfo.launchIntoPipHostTaskId != -1) {
        if (PipUtils.isContentPip(pipTaskInfo)) {
            // If the current PiP session was entered through content-PiP,
            // then relaunch the original host task too.
            wct.startTask(pipTaskInfo.launchIntoPipHostTaskId, null /* ActivityOptions */);
+12 −1
Original line number Diff line number Diff line
@@ -255,6 +255,10 @@ public class PipTransition extends PipTransitionController implements
    @Override
    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request) {
        if (mPipTransitionState.getState() == PipTransitionState.SCHEDULED_ENTER_PIP) {
            // An enter PiP transition has already been scheduled and is waiting to be played.
            return null;
        }
        if (isAutoEnterInButtonNavigation(request) || isEnterPictureInPictureModeRequest(request)) {
            mEnterTransition = transition;
            mPipTransitionState.setState(PipTransitionState.SCHEDULED_ENTER_PIP);
@@ -305,7 +309,7 @@ public class PipTransition extends PipTransitionController implements
    @Override
    public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted,
            @Nullable SurfaceControl.Transaction finishT) {
        if (transition == mBoundsChangeTransition && aborted) {
        if ((transition == mBoundsChangeTransition || transition == mEnterTransition) && aborted) {
            onTransitionAborted();
        }
    }
@@ -1112,6 +1116,13 @@ public class PipTransition extends PipTransitionController implements
            case PipTransitionState.SCHEDULED_BOUNDS_CHANGE:
                nextState = PipTransitionState.CHANGED_PIP_BOUNDS;
                break;
            case PipTransitionState.SCHEDULED_ENTER_PIP:
                if (mPipTransitionState.getPipTaskToken() != null) {
                    nextState = PipTransitionState.ENTERED_PIP;
                } else {
                    nextState = PipTransitionState.EXITED_PIP;
                }
                break;
        }

        if (nextState == PipTransitionState.UNDEFINED) {
Loading