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

Commit 7d18bdd7 authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

[PiP2] Find config-at-end activity in AE case

There are cases where an activity is a leaf
in a chain of containers. So whenever we are
retrieving a delay config-at-end activity, we
should not assume it's the direct child of a PiP task change.

More specifically, here, we are dealing with a case of:

  Pinned Task > TF (fills the task) > Config-at-End Activity

used by apps such as Whatsapp.

Bug: 402045190
Bug: 402270581
Flag: com.android.wm.shell.enable_pip2
Test: atest SecondaryActivityEnterPipTest
Test: direct enter PiP by back gesture from a Whatsapp call
Test: pinch-resize Whatsapp PiP
Change-Id: Ic51cdac72e7c46ba5c01440a0a6f375b37cc8714
parent b08d443d
Loading
Loading
Loading
Loading
+0 −18
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;

import androidx.annotation.NonNull;
@@ -341,23 +340,6 @@ public abstract class PipTransitionController implements Transitions.TransitionH
        return false;
    }

    /**
     * @return a change representing a config-at-end activity for a given parent.
     */
    @Nullable
    public TransitionInfo.Change getDeferConfigActivityChange(TransitionInfo info,
            @android.annotation.NonNull WindowContainerToken parent) {
        for (TransitionInfo.Change change : info.getChanges()) {
            if (change.getTaskInfo() == null
                    && change.hasFlags(TransitionInfo.FLAG_CONFIG_AT_END)
                    && change.getParent() != null && change.getParent().equals(parent)) {
                return change;
            }
        }
        return null;
    }


    /** Whether a particular package is same as current pip package. */
    public boolean isPackageActiveInPip(@Nullable String packageName) {
        // No-op, to be handled differently in PIP1 and PIP2
+7 −6
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
import com.android.wm.shell.pip2.animation.PipEnterAnimator;
import com.android.wm.shell.pip2.phone.transition.PipExpandHandler;
import com.android.wm.shell.pip2.phone.transition.PipTransitionUtils;
import com.android.wm.shell.shared.TransitionUtil;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellInit;
@@ -387,8 +388,8 @@ public class PipTransition extends PipTransitionController implements
        mFinishCallback = finishCallback;
        // We expect the PiP activity as a separate change in a config-at-end transition;
        // only flings are not using config-at-end for resize bounds changes
        TransitionInfo.Change pipActivityChange = getDeferConfigActivityChange(info,
                pipChange.getTaskInfo().getToken());
        TransitionInfo.Change pipActivityChange = PipTransitionUtils.getDeferConfigActivityChange(
                info, pipChange.getTaskInfo().getToken());
        if (pipActivityChange != null) {
            // Transform calculations use PiP params by default, so make sure they are null to
            // default to using bounds for scaling calculations instead.
@@ -427,8 +428,8 @@ public class PipTransition extends PipTransitionController implements
        }

        // We expect the PiP activity as a separate change in a config-at-end transition.
        TransitionInfo.Change pipActivityChange = getDeferConfigActivityChange(info,
                pipChange.getTaskInfo().getToken());
        TransitionInfo.Change pipActivityChange = PipTransitionUtils.getDeferConfigActivityChange(
                info, pipChange.getTaskInfo().getToken());
        if (pipActivityChange == null) {
            return false;
        }
@@ -497,8 +498,8 @@ public class PipTransition extends PipTransitionController implements
        }

        // We expect the PiP activity as a separate change in a config-at-end transition.
        TransitionInfo.Change pipActivityChange = getDeferConfigActivityChange(info,
                pipChange.getTaskInfo().getToken());
        TransitionInfo.Change pipActivityChange = PipTransitionUtils.getDeferConfigActivityChange(
                info, pipChange.getTaskInfo().getToken());
        if (pipActivityChange == null) {
            return false;
        }
+30 −0
Original line number Diff line number Diff line
@@ -66,6 +66,36 @@ public class PipTransitionUtils {
        return null;
    }

    /**
     * @return a change representing a config-at-end activity for ancestor.
     */
    @Nullable
    public static TransitionInfo.Change getDeferConfigActivityChange(TransitionInfo info,
            @NonNull WindowContainerToken ancestor) {
        final TransitionInfo.Change ancestorChange =
                PipTransitionUtils.getChangeByToken(info, ancestor);
        if (ancestorChange == null) return null;

        // Iterate through changes bottom-to-top, going up the parent chain starting with ancestor.
        TransitionInfo.Change lastPipChildChange = ancestorChange;
        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
            TransitionInfo.Change change = info.getChanges().get(i);
            if (change == ancestorChange) continue;

            if (change.getParent() != null
                    && change.getParent().equals(lastPipChildChange.getContainer())) {
                // Found a child of the last cached child along the ancestral chain.
                lastPipChildChange = change;
                if (change.getTaskInfo() == null
                        && change.hasFlags(TransitionInfo.FLAG_CONFIG_AT_END)) {
                    // If this is a config-at-end activity change, then we found the chain leaf.
                    return change;
                }
            }
        }
        return null;
    }

    /**
     * @return the leash to interact with the container this change represents.
     * @throws NullPointerException if the leash is null.
+2 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip2.phone.transition.PipTransitionUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.splitscreen.StageCoordinator;
import com.android.wm.shell.unfold.UnfoldTransitionHandler;
@@ -132,7 +133,7 @@ class DefaultMixedTransition extends DefaultMixedHandler.MixedTransition {

        TransitionInfo.Change pipActivityChange = null;
        if (pipChange != null) {
            pipActivityChange = mPipHandler.getDeferConfigActivityChange(
            pipActivityChange = PipTransitionUtils.getDeferConfigActivityChange(
                    info, pipChange.getContainer());
            everythingElse.getChanges().remove(pipActivityChange);
        }