diff options
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java | 42 | ||||
| -rw-r--r-- | libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java | 90 |
2 files changed, 84 insertions, 48 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 9130edfa9f26..74e85f8dd468 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -334,6 +334,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { boolean isDisplayRotationAnimationStarted = false; final boolean isDreamTransition = isDreamTransition(info); final boolean isOnlyTranslucent = isOnlyTranslucent(info); + final boolean isActivityLevel = isActivityLevelOnly(info); for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); @@ -502,8 +503,35 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { : new Rect(change.getEndAbsBounds()); clipRect.offsetTo(0, 0); + final TransitionInfo.Root animRoot = TransitionUtil.getRootFor(change, info); + final Point animRelOffset = new Point( + change.getEndAbsBounds().left - animRoot.getOffset().x, + change.getEndAbsBounds().top - animRoot.getOffset().y); + if (change.getActivityComponent() != null && !isActivityLevel) { + // At this point, this is an independent activity change in a non-activity + // transition. This means that an activity transition got erroneously combined + // with another ongoing transition. This then means that the animation root may + // not tightly fit the activities, so we have to put them in a separate crop. + final int layer = Transitions.calculateAnimLayer(change, i, + info.getChanges().size(), info.getType()); + final SurfaceControl leash = new SurfaceControl.Builder() + .setName("Transition ActivityWrap: " + + change.getActivityComponent().toShortString()) + .setParent(animRoot.getLeash()) + .setContainerLayer().build(); + startTransaction.setCrop(leash, clipRect); + startTransaction.setPosition(leash, animRelOffset.x, animRelOffset.y); + startTransaction.setLayer(leash, layer); + startTransaction.show(leash); + startTransaction.reparent(change.getLeash(), leash); + startTransaction.setPosition(change.getLeash(), 0, 0); + animRelOffset.set(0, 0); + finishTransaction.reparent(leash, null); + leash.release(); + } + buildSurfaceAnimation(animations, a, change.getLeash(), onAnimFinish, - mTransactionPool, mMainExecutor, change.getEndRelOffset(), cornerRadius, + mTransactionPool, mMainExecutor, animRelOffset, cornerRadius, clipRect); if (info.getAnimationOptions() != null) { @@ -612,6 +640,18 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { return (translucentOpen + translucentClose) > 0; } + /** + * Does `info` only contain activity-level changes? This kinda assumes that if so, they are + * all in one task. + */ + private static boolean isActivityLevelOnly(@NonNull TransitionInfo info) { + for (int i = info.getChanges().size() - 1; i >= 0; --i) { + final TransitionInfo.Change change = info.getChanges().get(i); + if (change.getActivityComponent() == null) return false; + } + return true; + } + @Override public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget, 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 b8a0f6703b97..274183dd9e2e 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 @@ -31,7 +31,6 @@ import static android.view.WindowManager.fixScale; import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED; import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW; import static android.window.TransitionInfo.FLAG_IS_OCCLUDED; -import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; import static android.window.TransitionInfo.FLAG_NO_ANIMATION; import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT; @@ -530,6 +529,44 @@ public class Transitions implements RemoteCallable<Transitions>, } } + static int calculateAnimLayer(@NonNull TransitionInfo.Change change, int i, + int numChanges, @WindowManager.TransitionType int transitType) { + // Put animating stuff above this line and put static stuff below it. + final int zSplitLine = numChanges + 1; + final boolean isOpening = isOpeningType(transitType); + final boolean isClosing = isClosingType(transitType); + final int mode = change.getMode(); + // Put all the OPEN/SHOW on top + if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) { + if (isOpening + // This is for when an activity launches while a different transition is + // collecting. + || change.hasFlags(FLAG_MOVED_TO_TOP)) { + // put on top + return zSplitLine + numChanges - i; + } else { + // put on bottom + return zSplitLine - i; + } + } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) { + if (isOpening) { + // put on bottom and leave visible + return zSplitLine - i; + } else { + // put on top + return zSplitLine + numChanges - i; + } + } else { // CHANGE or other + if (isClosing || TransitionUtil.isOrderOnly(change)) { + // Put below CLOSE mode (in the "static" section). + return zSplitLine - i; + } else { + // Put above CLOSE mode. + return zSplitLine + numChanges - i; + } + } + } + /** * Reparents all participants into a shared parent and orders them based on: the global transit * type, their transit mode, and their destination z-order. @@ -537,19 +574,14 @@ public class Transitions implements RemoteCallable<Transitions>, private static void setupAnimHierarchy(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) { final int type = info.getType(); - final boolean isOpening = isOpeningType(type); - final boolean isClosing = isClosingType(type); for (int i = 0; i < info.getRootCount(); ++i) { t.show(info.getRoot(i).getLeash()); } final int numChanges = info.getChanges().size(); - // Put animating stuff above this line and put static stuff below it. - final int zSplitLine = numChanges + 1; // changes should be ordered top-to-bottom in z for (int i = numChanges - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); final SurfaceControl leash = change.getLeash(); - final int mode = change.getMode(); // Don't reparent anything that isn't independent within its parents if (!TransitionInfo.isIndependent(change, info)) { @@ -558,50 +590,14 @@ public class Transitions implements RemoteCallable<Transitions>, boolean hasParent = change.getParent() != null; - final int rootIdx = TransitionUtil.rootIndexFor(change, info); + final TransitionInfo.Root root = TransitionUtil.getRootFor(change, info); if (!hasParent) { - t.reparent(leash, info.getRoot(rootIdx).getLeash()); + t.reparent(leash, root.getLeash()); t.setPosition(leash, - change.getStartAbsBounds().left - info.getRoot(rootIdx).getOffset().x, - change.getStartAbsBounds().top - info.getRoot(rootIdx).getOffset().y); - } - final int layer; - // Put all the OPEN/SHOW on top - if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) { - // Wallpaper is always at the bottom, opening wallpaper on top of closing one. - if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) { - layer = -zSplitLine + numChanges - i; - } else { - layer = -zSplitLine - i; - } - } else if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) { - if (isOpening - // This is for when an activity launches while a different transition is - // collecting. - || change.hasFlags(FLAG_MOVED_TO_TOP)) { - // put on top - layer = zSplitLine + numChanges - i; - } else { - // put on bottom - layer = zSplitLine - i; - } - } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) { - if (isOpening) { - // put on bottom and leave visible - layer = zSplitLine - i; - } else { - // put on top - layer = zSplitLine + numChanges - i; - } - } else { // CHANGE or other - if (isClosing || TransitionUtil.isOrderOnly(change)) { - // Put below CLOSE mode (in the "static" section). - layer = zSplitLine - i; - } else { - // Put above CLOSE mode. - layer = zSplitLine + numChanges - i; - } + change.getStartAbsBounds().left - root.getOffset().x, + change.getStartAbsBounds().top - root.getOffset().y); } + final int layer = calculateAnimLayer(change, i, numChanges, type); t.setLayer(leash, layer); } } |