From bbeaa71bb64ebe36ebcf86acb34ff99051295e40 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Wed, 23 Oct 2024 15:46:07 +0800 Subject: [PB] Filter out activity transition under TaskFragment ...from predictive back transition. 1. The opening target in predict_back transition could be multiple because of activity embedded adjacent. 2. To be more accurate to filter out none participant predictive back transition targets, checking the opening type, and prevent the predictive target involved into app transition. Flag: EXEMPT bugfix Bug: 375111994 Test: atest BackAnimationControllerTest Test: Back to activity adjacent, and verify the transition when both commit and cancel gesture can work as expect. Test: tap on the edge of Settings multiple times, verify the activity embedded changes can be filter out from back transition handler, and corresponding handler can play with the transition. Change-Id: I1f527770eaa8b542215a6d679c86f9873f659993 --- .../wm/shell/back/BackAnimationController.java | 86 +++++++++++++++------- .../wm/shell/back/BackAnimationControllerTest.java | 6 +- 2 files changed, 66 insertions(+), 26 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java index e4db7b636ed9..0beda678e79a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java @@ -95,6 +95,7 @@ import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Predicate; @@ -1273,42 +1274,42 @@ public class BackAnimationController implements RemoteCallable targets = new ArrayList<>(); int tmpSize; - int openTaskId = INVALID_TASK_ID; - WindowContainerToken openToken = null; for (int j = init.getChanges().size() - 1; j >= 0; --j) { final TransitionInfo.Change change = init.getChanges().get(j); - if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) { - openComponent = findComponentName(change); - openTaskId = findTaskId(change); - openToken = findToken(change); + if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED) + && TransitionUtil.isOpeningMode(change.getMode())) { + final ComponentName openComponent = findComponentName(change); + final int openTaskId = findTaskId(change); + final WindowContainerToken openToken = findToken(change); + if (openComponent == null && openTaskId == INVALID_TASK_ID + && openToken == null) { + continue; + } + targets.add(new OpenChangeInfo(openComponent, openTaskId, openToken)); if (change.hasFlags(FLAG_SHOW_WALLPAPER)) { openShowWallpaper = true; } - break; } } - if (openComponent == null && openTaskId == INVALID_TASK_ID && openToken == null) { + if (targets.isEmpty()) { // This shouldn't happen, but if that happen, consume the initial transition anyway. Log.e(TAG, "Unable to merge following transition, cannot find the gesture " + "animated target from the open transition=" + mOpenTransitionInfo); mOpenTransitionInfo = null; return; } - // find first non-prepare open target + // Find first non-prepare open target boolean isOpen = false; tmpSize = info.getChanges().size(); for (int j = 0; j < tmpSize; ++j) { final TransitionInfo.Change change = info.getChanges().get(j); - final ComponentName firstNonOpen = findComponentName(change); - final int firstTaskId = findTaskId(change); - if ((firstNonOpen != null && firstNonOpen != openComponent) - || (firstTaskId != INVALID_TASK_ID && firstTaskId != openTaskId)) { - // this is original close target, potential be close, but cannot determine from - // it + if (isOpenChangeMatched(targets, change)) { + // This is original close target, potential be close, but cannot determine + // from it. if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) { isOpen = !TransitionUtil.isClosingMode(change.getMode()); } else { @@ -1317,33 +1318,44 @@ public class BackAnimationController implements RemoteCallable= 0; --j) { final TransitionInfo.Change change = info.getChanges().get(j); - if (isSameChangeTarget(openComponent, openTaskId, openToken, change)) { + if (isOpenChangeMatched(targets, change)) { + if (TransitionUtil.isClosingMode(change.getMode())) { + excludeOpenTarget = true; + } moveToTop = change.hasFlags(FLAG_MOVED_TO_TOP); info.getChanges().remove(j); } else if ((openShowWallpaper && change.hasFlags(FLAG_IS_WALLPAPER)) || !change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) { info.getChanges().remove(j); + } else if (!mergePredictive && TransitionUtil.isClosingMode(change.getMode())) { + mergePredictive = true; } } // Ignore merge if there is no close target - if (!info.getChanges().isEmpty()) { + if (!info.getChanges().isEmpty() && mergePredictive) { tmpSize = init.getChanges().size(); for (int i = 0; i < tmpSize; ++i) { final TransitionInfo.Change change = init.getChanges().get(i); if (change.hasFlags(FLAG_IS_WALLPAPER)) { continue; } - if (moveToTop) { - if (isSameChangeTarget(openComponent, openTaskId, openToken, change)) { + if (isOpenChangeMatched(targets, change)) { + if (excludeOpenTarget) { + // App has triggered another change during predictive back + // transition, filter out predictive back target. + continue; + } + if (moveToTop) { change.setFlags(change.getFlags() | FLAG_MOVED_TO_TOP); } } @@ -1372,7 +1384,7 @@ public class BackAnimationController implements RemoteCallable= 0; --j) { final TransitionInfo.Change change = info.getChanges().get(j); - if (isSameChangeTarget(openComponent, openTaskId, openToken, change)) { + if (isOpenChangeMatched(targets, change)) { info.getChanges().remove(j); } else if ((openShowWallpaper && change.hasFlags(FLAG_IS_WALLPAPER))) { info.getChanges().remove(j); @@ -1655,9 +1667,21 @@ public class BackAnimationController implements RemoteCallable targets, + TransitionInfo.Change change) { + for (int i = targets.size() - 1; i >= 0; --i) { + final OpenChangeInfo next = targets.get(i); + if (isSameChangeTarget(next.mOpenComponent, next.mOpenTaskId, next.mOpenToken, + change)) { + return true; + } + } + return false; } private static boolean canBeTransitionTarget(TransitionInfo.Change change) { @@ -1717,4 +1741,16 @@ public class BackAnimationController implements RemoteCallable