From 262fe527a159eb428a57647eb955758bc918e13a Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Tue, 23 Jan 2024 10:28:24 +0000 Subject: Polish a weird transition that open animation can apply on non-top task. When app relaunch an translucent activity then clear any activities above it, if above activity(ies) was opaque and fill_task, that startActivity transition will also collect any below activity/task due to it become visible. But that visible change can confuse DefaultTransitionHandler because it will create an opening(slide-in) animation for the non-top change. Add the OCCLUDED flag for those changes which belows non-translucent target, so they can be filter out if no animation is requested. Bug: 318877215 Test: repeatly launch OmnientActivity while CCT is above it, verify no strange opening task animation occur. Change-Id: Idce88c839b26db1def7aec0a220bfb8110c54e5c --- .../com/android/wm/shell/transition/Transitions.java | 6 ++++-- .../core/java/com/android/server/wm/Transition.java | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index 6ade81c0f3a1..a85d9d5909ac 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -657,8 +657,10 @@ public class Transitions implements RemoteCallable, } if (change.hasFlags(FLAG_NO_ANIMATION)) { hasNoAnimation = true; - } else { - // at-least one relevant participant *is* animated, so we need to animate. + } else if (!TransitionUtil.isOrderOnly(change) && !change.hasFlags(FLAG_IS_OCCLUDED)) { + // Ignore the order only or occluded changes since they shouldn't be visible during + // animation. For anything else, we need to animate if at-least one relevant + // participant *is* animated, return false; } } diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 218334e9ecae..4e7dbaa7fe0b 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -52,6 +52,7 @@ import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY; import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD; +import static android.window.TransitionInfo.FLAG_IS_OCCLUDED; import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; @@ -2734,6 +2735,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { out.setAnimationOptions(animOptions); } + final ArraySet occludedAtEndContainers = new ArraySet<>(); // Convert all the resolved ChangeInfos into TransactionInfo.Change objects in order. final int count = sortedTargets.size(); for (int i = 0; i < count; ++i) { @@ -2757,6 +2759,22 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { info.mReadyFlags = change.getFlags(); change.setDisplayId(info.mDisplayId, getDisplayId(target)); + // Add FLAGS_IS_OCCLUDED to preventing from visible-translucent change which belows + // the non-translucent change playing unexpected open animation. + if (change.getMode() == TRANSIT_TO_FRONT || change.getMode() == TRANSIT_OPEN) { + for (int occIndex = occludedAtEndContainers.size() - 1; occIndex >= 0; --occIndex) { + if (target.isDescendantOf(occludedAtEndContainers.valueAt(occIndex))) { + change.setFlags(change.getFlags() | FLAG_IS_OCCLUDED); + break; + } + } + } + if (!change.hasFlags(FLAG_TRANSLUCENT) && (change.getMode() == TRANSIT_OPEN + || change.getMode() == TRANSIT_TO_FRONT + || change.getMode() == TRANSIT_CHANGE)) { + occludedAtEndContainers.add(target.getParent()); + } + final Task task = target.asTask(); final TaskFragment taskFragment = target.asTaskFragment(); final ActivityRecord activityRecord = target.asActivityRecord(); -- cgit v1.2.3-59-g8ed1b