From 9c57479aac853bb628bd7e1068ca018bd6e572d4 Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Mon, 11 Apr 2022 18:05:04 -0700 Subject: [PATCH] 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 --- .../system/RemoteAnimationTargetCompat.java | 78 +++++-------------- .../shared/system/RemoteTransitionCompat.java | 19 ++--- 2 files changed, 29 insertions(+), 68 deletions(-) diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java index 9cf482fdf790d..4ce110bf7c471 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java @@ -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; - } + t.reparent(leash, info.getRootLeash()); + t.setPosition(leash, change.getStartAbsBounds().left - info.getRootOffset().x, + change.getStartAbsBounds().top - info.getRootOffset().y); - 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 leashMap) { final ArrayList out = new ArrayList<>(); - final SparseArray childTaskTargets = new SparseArray<>(); - final IntArray excludedParentTaskIds = new IntArray(); + final SparseArray 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; + 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) { + if (childTaskTargets.contains(taskInfo.taskId)) { + // has children, so not a leaf. Skip. + continue; + } + if (taskInfo.hasParentTask()) { + childTaskTargets.put(taskInfo.parentTaskId, change); + } + } + } + final RemoteAnimationTargetCompat targetCompat = new RemoteAnimationTargetCompat(change, info.getChanges().size() - i, info, t); if (leashMap != null) { leashMap.put(change.getLeash(), targetCompat.leash); } - final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); - if (taskInfo != null) { - // Skip wrapping excluded parent task animate target since it will animate its child - // tasks instead. - if (excludedParentTaskIds.binarySearch(taskInfo.taskId) != -1) { - 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); - } - - // 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); - } - } - out.add(targetCompat); } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java index de35514be2cb7..d7f8235d76a93 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java @@ -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 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;