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

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

Implement manually entering PiP flow

It is possible for the client to request
enter PiP directly outside of lifecycle callbacks
(such as onUserLeaveHint). When this direct request comes in
we should run BOUNDS animation instead of ALPHA irrespective of
auto-enter flag value.

We are resolving the type of the animation on the Shell side
by looking at the TransitionInfo before playing the animation.

Bug: 317269218
Test: request enterPictureInPictureMode() directly from client
Change-Id: Ibc3645b5a1ed949bcfaa716f8555cc5179e6b291
parent 95807be5
Loading
Loading
Loading
Loading
+27 −20
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.wm.shell.pip2.phone;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_PIP;
import static android.view.WindowManager.TRANSIT_TO_FRONT;

import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;

@@ -54,6 +55,8 @@ public class PipTransition extends PipTransitionController {
    @Nullable
    private WindowContainerToken mPipTaskToken;
    @Nullable
    private IBinder mEnterTransition;
    @Nullable
    private IBinder mAutoEnterButtonNavTransition;
    @Nullable
    private IBinder mExitViaExpandTransition;
@@ -98,11 +101,8 @@ public class PipTransition extends PipTransitionController {
    @Override
    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request) {
        if (isAutoEnterInButtonNavigation(request)) {
            mAutoEnterButtonNavTransition = transition;
            return getEnterPipTransaction(transition, request);
        } else if (isLegacyEnter(request)) {
            mLegacyEnterTransition = transition;
        if (isAutoEnterInButtonNavigation(request) || isEnterPictureInPictureModeRequest(request)) {
            mEnterTransition = transition;
            return getEnterPipTransaction(transition, request);
        }
        return null;
@@ -111,12 +111,9 @@ public class PipTransition extends PipTransitionController {
    @Override
    public void augmentRequest(@NonNull IBinder transition, @NonNull TransitionRequestInfo request,
            @NonNull WindowContainerTransaction outWct) {
        if (isAutoEnterInButtonNavigation(request)) {
        if (isAutoEnterInButtonNavigation(request) || isEnterPictureInPictureModeRequest(request)) {
            outWct.merge(getEnterPipTransaction(transition, request), true /* transfer */);
            mAutoEnterButtonNavTransition = transition;
        } else if (isLegacyEnter(request)) {
            outWct.merge(getEnterPipTransaction(transition, request), true /* transfer */);
            mLegacyEnterTransition = transition;
            mEnterTransition = transition;
        }
    }

@@ -162,7 +159,7 @@ public class PipTransition extends PipTransitionController {
                && pipTask.pictureInPictureParams.isAutoEnterEnabled();
    }

    private boolean isLegacyEnter(@NonNull TransitionRequestInfo requestInfo) {
    private boolean isEnterPictureInPictureModeRequest(@NonNull TransitionRequestInfo requestInfo) {
        return requestInfo.getType() == TRANSIT_PIP;
    }

@@ -172,13 +169,15 @@ public class PipTransition extends PipTransitionController {
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback) {
        if (transition == mAutoEnterButtonNavTransition) {
            mAutoEnterButtonNavTransition = null;
            return startAutoEnterButtonNavAnimation(info, startTransaction, finishTransaction,
        if (transition == mEnterTransition) {
            mEnterTransition = null;
            if (isLegacyEnter(info)) {
                // If this is a legacy-enter-pip (auto-enter is off and PiP activity went to pause),
                // then we should run an ALPHA type (cross-fade) animation.
                return startAlphaTypeEnterAnimation(info, startTransaction, finishTransaction,
                        finishCallback);
        } else if (transition == mLegacyEnterTransition) {
            mLegacyEnterTransition = null;
            return startLegacyEnterAnimation(info, startTransaction, finishTransaction,
            }
            return startBoundsTypeEnterAnimation(info, startTransaction, finishTransaction,
                    finishCallback);
        } else if (transition == mExitViaExpandTransition) {
            mExitViaExpandTransition = null;
@@ -187,7 +186,15 @@ public class PipTransition extends PipTransitionController {
        return false;
    }

    private boolean startAutoEnterButtonNavAnimation(@NonNull TransitionInfo info,
    private boolean isLegacyEnter(@NonNull TransitionInfo info) {
        TransitionInfo.Change pipChange = getPipChange(info);
        // If the only change in the changes list is a TO_FRONT mode PiP task,
        // then this is legacy-enter PiP.
        return pipChange != null && pipChange.getMode() == TRANSIT_TO_FRONT
                && info.getChanges().size() == 1;
    }

    private boolean startBoundsTypeEnterAnimation(@NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback) {
@@ -205,7 +212,7 @@ public class PipTransition extends PipTransitionController {
        return true;
    }

    private boolean startLegacyEnterAnimation(@NonNull TransitionInfo info,
    private boolean startAlphaTypeEnterAnimation(@NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+12 −12
Original line number Diff line number Diff line
@@ -3689,19 +3689,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            return false;
        }

        // If the app is using legacy-entry (not auto-enter), then we will get a client-request
        // that was actually a server-request (via pause(userLeaving=true)). This happens when
        // the app is PAUSING, so detect that case here.
        boolean originallyFromClient = fromClient
                && (!r.isState(PAUSING) || params.isAutoEnterEnabled());

        // If PiP2 flag is on and client-request to enter PiP came via onUserLeaveHint(),
        // we request a direct transition from Shell to TRANSIT_PIP_LEGACY to get the startWct
        // with the right entry bounds.
        if (isPip2ExperimentEnabled() && !originallyFromClient && !params.isAutoEnterEnabled()) {
        // If PiP2 flag is on and client-request to enter PiP comes in,
        // we request a direct transition from Shell to TRANSIT_PIP to get the startWct
        // with the right entry bounds. So PiP activity isn't moved to a pinned task until after
        // Shell calls back into Core with the entry bounds passed through.
        if (isPip2ExperimentEnabled()) {
            final Transition legacyEnterPipTransition = new Transition(TRANSIT_PIP,
                    0 /* flags */, getTransitionController(),
                    mWindowManager.mSyncEngine);
                    0 /* flags */, getTransitionController(), mWindowManager.mSyncEngine);
            legacyEnterPipTransition.setPipActivity(r);
            getTransitionController().startCollectOrQueue(legacyEnterPipTransition, (deferred) -> {
                getTransitionController().requestStartTransition(legacyEnterPipTransition,
@@ -3710,6 +3704,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            return true;
        }

        // If the app is using legacy-entry (not auto-enter), then we will get a client-request
        // that was actually a server-request (via pause(userLeaving=true)). This happens when
        // the app is PAUSING, so detect that case here.
        boolean originallyFromClient = fromClient
                && (!r.isState(PAUSING) || params.isAutoEnterEnabled());

        // Create a transition only for this pip entry if it is coming from the app without the
        // system requesting that the app enter-pip. If the system requested it, that means it
        // should be part of that transition if possible.