From bb750d8ad3d5e330341e5bd2c67a929a99b7e30f Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Thu, 10 Mar 2022 08:43:19 +0000 Subject: [PATCH] Integrate recent animation of single-root split with shell transition Stop propergating child task information up if the parent task having multiple child task changes in the same transition. And skip wrapping it into the final remote animation targets so its child tasks won't get transfered multiple-times in such transition. Bug: 207185041 Bug: 206487881 Test: enabled shell-transition and triggered split screen, observed the recent animation works properly Change-Id: I8d2c62df99ccb88303aa2b06dd18f2f4edb330f2 --- core/java/android/window/TransitionInfo.java | 2 +- .../system/RemoteAnimationTargetCompat.java | 40 ++++++++++++++----- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index 7718a3b7fc672..51da61ffb9c98 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -344,7 +344,7 @@ public final class TransitionInfo implements Parcelable { if (parentChg.getMode() != TRANSIT_CHANGE) return false; // If there are no more parents left, then all the parents, so far, have not been - // visibility changes which means this change is indpendent. + // visibility changes which means this change is independent. if (parentChg.getParent() == null) return true; parentChg = info.getChange(parentChg.getParent()); 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 c9a659a649d5d..9cf482fdf790d 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 @@ -32,6 +32,7 @@ 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; @@ -269,6 +270,7 @@ public class RemoteAnimationTargetCompat { SurfaceControl.Transaction t, ArrayMap leashMap) { final ArrayList out = new ArrayList<>(); final SparseArray childTaskTargets = new SparseArray<>(); + final IntArray excludedParentTaskIds = new IntArray(); for (int i = 0; i < info.getChanges().size(); i++) { final TransitionInfo.Change change = info.getChanges().get(i); final boolean changeIsWallpaper = @@ -282,22 +284,40 @@ public class RemoteAnimationTargetCompat { } final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); if (taskInfo != null) { - if (taskInfo.parentTaskId != -1) { - // Cache child task targets to override its parent target later and exclude - // child task while wrapping up animate targets. Otherwise the child task might - // get transformed twice with the flow like RecentsView#redrawLiveTile. - childTaskTargets.put(taskInfo.parentTaskId, targetCompat); + // Skip wrapping excluded parent task animate target since it will animate its child + // tasks instead. + if (excludedParentTaskIds.binarySearch(taskInfo.taskId) != -1) { continue; } - final RemoteAnimationTargetCompat childTaskTarget = - childTaskTargets.get(taskInfo.taskId); + // Check if there's a matching child task target in cache. + RemoteAnimationTargetCompat childTaskTarget = childTaskTargets.get(taskInfo.taskId); if (childTaskTarget != null) { - // Launcher monitors leaf tasks to perform animation, hence override the parent - // task target with child task info so Launcher can locate and animate root - // surface directly with leaf task information. + // 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); } }