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

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

[PiP2] Generalize legacy-enter filter

We need to make isLegacyEnter check more
generic and accurte to allow for legacy-enter cases
that can have other changes collected into the TRANSIT_PIP
transition as well, such as trampoline activity launch case
reported in the bug below.

Also adding a wtf log for cases where enter PiP was scheduled
one way or another but PipTransition.startAnimation is about to
be skipped as a playing handler.

Bug: 403637164
Flag: com.android.wm.shell.enable_pip2
Test: manually repro the steps in b/403637164#comment8
Test: legacy-enter PiP from a Whatsapp call (with a task filling TF)
Change-Id: I16139501d5126192cf51a79e21522a48df8cd644
parent f4ae3169
Loading
Loading
Loading
Loading
+25 −20
Original line number Diff line number Diff line
@@ -50,7 +50,9 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
import android.util.Log;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.TransitionInfo;
@@ -300,6 +302,20 @@ public class PipTransition extends PipTransitionController implements
                return startAlphaTypeEnterAnimation(info, startTransaction, finishTransaction,
                        finishCallback);
            }

            TransitionInfo.Change pipActivityChange = PipTransitionUtils
                    .getDeferConfigActivityChange(info, pipChange.getTaskInfo().getToken());
            if (pipActivityChange == null) {
                // Legacy-enter and swipe-pip-to-home filters did not resolve a scheduled PiP entry.
                // Bounds-type enter animation is the last resort, and it requires a config-at-end
                // activity amongst the list of changes. If no such change, something went wrong.
                Log.wtf(TAG, String.format("""
                        PipTransition.startAnimation didn't handle a scheduled PiP entry
                        transitionInfo=%s,
                        callers=%s""", info, Debug.getCallers(4)));
                return false;
            }

            return startBoundsTypeEnterAnimation(info, startTransaction, finishTransaction,
                    finishCallback);
        } else if (transition == mExitViaExpandTransition) {
@@ -824,26 +840,15 @@ public class PipTransition extends PipTransitionController implements
                return true;
            }

            // Sometimes root PiP task can have TF children. These child containers can be collected
            // even if they can promote to their parents: e.g. if they are marked as "organized".
            // So we count the chain of containers under PiP task as one "real" changing target;
            // iterate through changes bottom-to-top to properly identify parents.
            int expectedTargetCount = 1;
            WindowContainerToken lastPipChildToken = pipChange.getContainer();
            for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                TransitionInfo.Change change = info.getChanges().get(i);
                if (change == pipChange || change.getContainer() == null) continue;
                if (change.getParent() != null && change.getParent().equals(lastPipChildToken)) {
                    // Allow an extra change since our pinned root task has a child.
                    ++expectedTargetCount;
                    lastPipChildToken = change.getContainer();
                }
            }

            // If the only root task change in the changes list is a opening type PiP task,
            // then this is legacy-enter PiP.
            return info.getChanges().size() == expectedTargetCount
                    && TransitionUtil.isOpeningMode(pipChange.getMode());
            // #getEnterPipTransaction() always attempts to mark PiP activity as config-at-end one.
            // However, the activity will only actually be marked config-at-end by Core if it is
            // both isVisible and isVisibleRequested, which is when we can't run bounds animation.
            //
            // So we can use the absence of a config-at-end activity as a signal that we should run
            // a legacy-enter PiP animation instead.
            return TransitionUtil.isOpeningMode(pipChange.getMode())
                    && PipTransitionUtils.getDeferConfigActivityChange(
                            info, pipChange.getContainer()) == null;
        }
        return false;
    }