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

Commit 9c57479a authored by Evan Rosky's avatar Evan Rosky
Browse files

Only wrap leaf tasks when creating legacy remote targets

Legacy animations only know how to deal with leaf tasks,
so don't give them any non-leaf tasks. We were originally trying
to hack around this by rewriting task-ids and such, but that
seemed a bit fragile and there were likely several places where
that change was still missing.

This CL just switches back to all leafs.

Bug: 228883780
Test: use split-screen in shell-transitions.
Change-Id: Ic18412ea9e20e1b2f133a936c63d1a6576ce50a6
parent 1097ed3c
Loading
Loading
Loading
Loading
+19 −59
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.systemui.shared.system;

import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
@@ -32,7 +31,6 @@ import android.app.WindowConfiguration;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.ArrayMap;
import android.util.IntArray;
import android.util.SparseArray;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
@@ -142,21 +140,10 @@ public class RemoteAnimationTargetCompat {
        // changes should be ordered top-to-bottom in z
        final int mode = change.getMode();

        // Don't move anything that isn't independent within its parents
        if (!TransitionInfo.isIndependent(change, info)) {
            if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT || mode == TRANSIT_CHANGE) {
                t.setPosition(leash, change.getEndRelOffset().x, change.getEndRelOffset().y);
            }
            return;
        }

        final boolean hasParent = change.getParent() != null;

        if (!hasParent) {
        t.reparent(leash, info.getRootLeash());
        t.setPosition(leash, change.getStartAbsBounds().left - info.getRootOffset().x,
                change.getStartAbsBounds().top - info.getRootOffset().y);
        }

        // Put all the OPEN/SHOW on top
        if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
            if (isOpening) {
@@ -196,8 +183,7 @@ public class RemoteAnimationTargetCompat {
                .setContainerLayer()
                // Initial the surface visible to respect the visibility of the original surface.
                .setHidden(false)
                .setParent(change.getParent() == null ? info.getRootLeash()
                        : info.getChange(change.getParent()).getLeash())
                .setParent(info.getRootLeash())
                .build();
        // Copied Transitions setup code (which expects bottom-to-top order, so we swap here)
        setupLeash(leashSurface, change, info.getChanges().size() - order, info, t);
@@ -269,58 +255,32 @@ public class RemoteAnimationTargetCompat {
    public static RemoteAnimationTargetCompat[] wrap(TransitionInfo info, boolean wallpapers,
            SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
        final ArrayList<RemoteAnimationTargetCompat> out = new ArrayList<>();
        final SparseArray<RemoteAnimationTargetCompat> childTaskTargets = new SparseArray<>();
        final IntArray excludedParentTaskIds = new IntArray();
        final SparseArray<TransitionInfo.Change> childTaskTargets = new SparseArray<>();
        for (int i = 0; i < info.getChanges().size(); i++) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            final boolean changeIsWallpaper =
                    (change.getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0;
            if (wallpapers != changeIsWallpaper) continue;

            final RemoteAnimationTargetCompat targetCompat =
                    new RemoteAnimationTargetCompat(change, info.getChanges().size() - i, info, t);
            if (leashMap != null) {
                leashMap.put(change.getLeash(), targetCompat.leash);
            }
            if (!wallpapers) {
                final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                // Children always come before parent since changes are in top-to-bottom z-order.
                if (taskInfo != null) {
                // Skip wrapping excluded parent task animate target since it will animate its child
                // tasks instead.
                if (excludedParentTaskIds.binarySearch(taskInfo.taskId) != -1) {
                    if (childTaskTargets.contains(taskInfo.taskId)) {
                        // has children, so not a leaf. Skip.
                        continue;
                    }

                // Check if there's a matching child task target in cache.
                RemoteAnimationTargetCompat childTaskTarget = childTaskTargets.get(taskInfo.taskId);
                if (childTaskTarget != null) {
                    // Launcher monitors leaf task ids to perform animation, override the target
                    // with its child task information so Launcher can animate this parent surface
                    // directly with leaf task information.
                    targetCompat.taskInfo = childTaskTarget.taskInfo;
                    targetCompat.taskId = childTaskTarget.taskId;
                    childTaskTargets.remove(taskInfo.taskId);
                    if (taskInfo.hasParentTask()) {
                        childTaskTargets.put(taskInfo.parentTaskId, change);
                    }

                // Check if it has a parent task, cache its information for later use.
                if (taskInfo.parentTaskId != -1
                        && excludedParentTaskIds.binarySearch(taskInfo.parentTaskId) == -1) {
                    if (!childTaskTargets.contains(taskInfo.parentTaskId)) {
                        // Cache the target amd skip wrapping it info the final animation targets.
                        // Otherwise, the child task might get transformed multiple-times with the
                        // flow like RecentsView#redrawLiveTile.
                        childTaskTargets.put(taskInfo.parentTaskId, targetCompat);
                        continue;
                    }

                    // There is another child task target cached with the same parent task id.
                    // Which means the parent having multiple child tasks in transition. Stop
                    // propagate child task info.
                    childTaskTarget = childTaskTargets.removeReturnOld(taskInfo.parentTaskId);
                    out.add(childTaskTarget);
                    excludedParentTaskIds.add(taskInfo.parentTaskId);
                }
            }

            final RemoteAnimationTargetCompat targetCompat =
                    new RemoteAnimationTargetCompat(change, info.getChanges().size() - i, info, t);
            if (leashMap != null) {
                leashMap.put(change.getLeash(), targetCompat.leash);
            }
            out.add(targetCompat);
        }

+10 −9
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.TransitionFilter.CONTAINER_ORDER_TOP;

import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_RECENTS;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -132,16 +133,17 @@ public class RemoteTransitionCompat implements Parcelable {
                // TODO(b/177438007): Move this set-up logic into launcher's animation impl.
                mToken = transition;
                // This transition is for opening recents, so recents is on-top. We want to draw
                // the current going-away task on top of recents, though, so move it to front
                // the current going-away tasks on top of recents, though, so move them to front.
                // Note that we divide up the "layer space" into 3 regions each the size of
                // the change count. This way we can easily move changes into above/below/between
                // while maintaining their relative ordering.
                final ArrayList<WindowContainerToken> pausingTasks = new ArrayList<>();
                WindowContainerToken pipTask = null;
                WindowContainerToken recentsTask = null;
                for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                    final TransitionInfo.Change change = info.getChanges().get(i);
                    final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                    if (change.getMode() == TRANSIT_CLOSE || change.getMode() == TRANSIT_TO_BACK) {
                        t.setLayer(leashMap.get(change.getLeash()),
                                info.getChanges().size() * 3 - i);
                for (int i = apps.length - 1; i >= 0; --i) {
                    final ActivityManager.RunningTaskInfo taskInfo = apps[i].taskInfo;
                    if (apps[i].mode == MODE_CLOSING) {
                        t.setLayer(apps[i].leash, info.getChanges().size() * 3 - i);
                        if (taskInfo == null) {
                            continue;
                        }
@@ -154,8 +156,7 @@ public class RemoteTransitionCompat implements Parcelable {
                    } else if (taskInfo != null
                            && taskInfo.topActivityType == ACTIVITY_TYPE_RECENTS) {
                        // This task is for recents, keep it on top.
                        t.setLayer(leashMap.get(change.getLeash()),
                                info.getChanges().size() * 3 - i);
                        t.setLayer(apps[i].leash, info.getChanges().size() * 3 - i);
                        recentsTask = taskInfo.token;
                    } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
                        recentsTask = taskInfo.token;