diff options
Diffstat (limited to 'libs')
7 files changed, 56 insertions, 30 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index 2848f3444e21..4ef4d0a5ee90 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -489,10 +489,11 @@ public class PipTransition extends PipTransitionController { // Reparent the pip leash to the root with max layer so that we can animate it outside of // parent crop, and make sure it is not covered by other windows. final SurfaceControl pipLeash = pipChange.getLeash(); - startTransaction.reparent(pipLeash, info.getRootLeash()); + final int rootIdx = TransitionUtil.rootIndexFor(pipChange, info); + startTransaction.reparent(pipLeash, info.getRoot(rootIdx).getLeash()); startTransaction.setLayer(pipLeash, Integer.MAX_VALUE); // Note: because of this, the bounds to animate should be translated to the root coordinate. - final Point offset = info.getRootOffset(); + final Point offset = info.getRoot(rootIdx).getOffset(); final Rect currentBounds = mPipBoundsState.getBounds(); currentBounds.offset(-offset.x, -offset.y); startTransaction.setPosition(pipLeash, currentBounds.left, currentBounds.top); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java index e1c089550c2d..e09c3c9e4d3f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java @@ -37,6 +37,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; +import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; import android.view.SurfaceControl; @@ -128,6 +129,7 @@ class SplitScreenTransitions { final int mode = info.getChanges().get(i).getMode(); if (mode == TRANSIT_CHANGE) { + final int rootIdx = TransitionUtil.rootIndexFor(change, info); if (change.getParent() != null) { // This is probably reparented, so we want the parent to be immediately visible final TransitionInfo.Change parentChange = info.getChange(change.getParent()); @@ -135,7 +137,7 @@ class SplitScreenTransitions { t.setAlpha(parentChange.getLeash(), 1.f); // and then animate this layer outside the parent (since, for example, this is // the home task animating from fullscreen to part-screen). - t.reparent(leash, info.getRootLeash()); + t.reparent(leash, info.getRoot(rootIdx).getLeash()); t.setLayer(leash, info.getChanges().size() - i); // build the finish reparent/reposition mFinishTransaction.reparent(leash, parentChange.getLeash()); @@ -145,8 +147,9 @@ class SplitScreenTransitions { // TODO(shell-transitions): screenshot here final Rect startBounds = new Rect(change.getStartAbsBounds()); final Rect endBounds = new Rect(change.getEndAbsBounds()); - startBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y); - endBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y); + final Point rootOffset = info.getRoot(rootIdx).getOffset(); + startBounds.offset(-rootOffset.x, -rootOffset.y); + endBounds.offset(-rootOffset.x, -rootOffset.y); startExampleResizeAnimation(leash, startBounds, endBounds); } boolean isRootOrSplitSideRoot = change.getParent() == null diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java index 75112b62c1c6..2e864483bf1d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java @@ -179,7 +179,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { out.getChanges().add(info.getChanges().get(i)); } } - out.setRootLeash(info.getRootLeash(), info.getRootOffset().x, info.getRootOffset().y); + for (int i = 0; i < info.getRootCount(); ++i) { + out.addRoot(info.getRoot(i)); + } out.setAnimationOptions(info.getAnimationOptions()); return out; } 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 f66c26bb87e4..63c7969291a0 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 @@ -383,9 +383,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { continue; } // No default animation for this, so just update bounds/position. + final int rootIdx = TransitionUtil.rootIndexFor(change, info); startTransaction.setPosition(change.getLeash(), - change.getEndAbsBounds().left - info.getRootOffset().x, - change.getEndAbsBounds().top - info.getRootOffset().y); + change.getEndAbsBounds().left - info.getRoot(rootIdx).getOffset().x, + change.getEndAbsBounds().top - info.getRoot(rootIdx).getOffset().y); // Seamless display transition doesn't need to animate. if (isSeamlessDisplayChange) continue; if (isTask || (change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY) @@ -474,8 +475,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { } if (backgroundColorForTransition != 0) { - addBackgroundToTransition(info.getRootLeash(), backgroundColorForTransition, - startTransaction, finishTransaction); + for (int i = 0; i < info.getRootCount(); ++i) { + addBackgroundToTransition(info.getRoot(i).getLeash(), backgroundColorForTransition, + startTransaction, finishTransaction); + } } if (postStartTransactionCallbacks.size() > 0) { @@ -520,8 +523,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { private void startRotationAnimation(SurfaceControl.Transaction startTransaction, TransitionInfo.Change change, TransitionInfo info, int animHint, ArrayList<Animator> animations, Runnable onAnimFinish) { + final int rootIdx = TransitionUtil.rootIndexFor(change, info); final ScreenRotationAnimation anim = new ScreenRotationAnimation(mContext, mSurfaceSession, - mTransactionPool, startTransaction, change, info.getRootLeash(), animHint); + mTransactionPool, startTransaction, change, info.getRoot(rootIdx).getLeash(), + animHint); // The rotation animation may consist of 3 animations: fade-out screenshot, fade-in real // content, and background color. The item of "animGroup" will be removed if the sub // animation is finished. Then if the list becomes empty, the rotation animation is done. 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 27b82c08d803..039bde95815e 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 @@ -75,6 +75,7 @@ import com.android.wm.shell.common.annotations.ExternalThread; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; +import com.android.wm.shell.util.TransitionUtil; import java.util.ArrayList; import java.util.Arrays; @@ -415,8 +416,8 @@ public class Transitions implements RemoteCallable<Transitions> { private static void setupAnimHierarchy(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) { boolean isOpening = isOpeningType(info.getType()); - if (info.getRootLeash().isValid()) { - t.show(info.getRootLeash()); + 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. @@ -434,10 +435,12 @@ public class Transitions implements RemoteCallable<Transitions> { boolean hasParent = change.getParent() != null; + final int rootIdx = TransitionUtil.rootIndexFor(change, info); if (!hasParent) { - t.reparent(leash, info.getRootLeash()); - t.setPosition(leash, change.getStartAbsBounds().left - info.getRootOffset().x, - change.getStartAbsBounds().top - info.getRootOffset().y); + t.reparent(leash, info.getRoot(rootIdx).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 @@ -532,12 +535,6 @@ public class Transitions implements RemoteCallable<Transitions> { if (info.getType() == TRANSIT_SLEEP) { if (activeIdx > 0) { - if (!info.getRootLeash().isValid()) { - // Shell has some debug settings which makes calling binders with invalid - // surfaces crash, so replace it with a "real" one. - info.setRootLeash(new SurfaceControl.Builder().setName("Invalid") - .setContainerLayer().build(), 0, 0); - } // Sleep starts a process of forcing all prior transitions to finish immediately finishForSleep(null /* forceFinish */); return; @@ -546,10 +543,10 @@ public class Transitions implements RemoteCallable<Transitions> { // Allow to notify keyguard un-occluding state to KeyguardService, which can happen while // screen-off, so there might no visibility change involved. - if (!info.getRootLeash().isValid() && info.getType() != TRANSIT_KEYGUARD_UNOCCLUDE) { - // Invalid root-leash implies that the transition is empty/no-op, so just do + if (info.getRootCount() == 0 && info.getType() != TRANSIT_KEYGUARD_UNOCCLUDE) { + // No root-leashes implies that the transition is empty/no-op, so just do // housekeeping and return. - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Invalid root leash (%s): %s", + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "No transition roots (%s): %s", transitionToken, info); onAbort(active); return; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java index 8c6e1e7f5f1b..7595c9617709 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java @@ -139,11 +139,12 @@ public class TransitionUtil { // changes should be ordered top-to-bottom in z final int mode = change.getMode(); - t.reparent(leash, info.getRootLeash()); + final int rootIdx = TransitionUtil.rootIndexFor(change, info); + t.reparent(leash, info.getRoot(rootIdx).getLeash()); final Rect absBounds = (mode == TRANSIT_OPEN) ? change.getEndAbsBounds() : change.getStartAbsBounds(); - t.setPosition(leash, absBounds.left - info.getRootOffset().x, - absBounds.top - info.getRootOffset().y); + t.setPosition(leash, absBounds.left - info.getRoot(rootIdx).getOffset().x, + absBounds.top - info.getRoot(rootIdx).getOffset().y); // Put all the OPEN/SHOW on top if (TransitionUtil.isOpeningType(mode)) { @@ -179,12 +180,13 @@ public class TransitionUtil { // making leashes means we have to handle them specially. return change.getLeash(); } + final int rootIdx = TransitionUtil.rootIndexFor(change, info); SurfaceControl leashSurface = new SurfaceControl.Builder() .setName(change.getLeash().toString() + "_transition-leash") .setContainerLayer() // Initial the surface visible to respect the visibility of the original surface. .setHidden(false) - .setParent(info.getRootLeash()) + .setParent(info.getRoot(rootIdx).getLeash()) .build(); // Copied Transitions setup code (which expects bottom-to-top order, so we swap here) setupLeash(leashSurface, change, info.getChanges().size() - order, info, t); @@ -261,4 +263,18 @@ public class TransitionUtil { target.setRotationChange(change.getEndRotation() - change.getStartRotation()); return target; } + + /** + * Finds the "correct" root idx for a change. The change's end display is prioritized, then + * the start display. If there is no display, it will fallback on the 0th root in the + * transition. There MUST be at-least 1 root in the transition (ie. it's not a no-op). + */ + public static int rootIndexFor(@NonNull TransitionInfo.Change change, + @NonNull TransitionInfo info) { + int rootIdx = info.findRootIndex(change.getEndDisplayId()); + if (rootIdx >= 0) return rootIdx; + rootIdx = info.findRootIndex(change.getStartDisplayId()); + if (rootIdx >= 0) return rootIdx; + return 0; + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java index 35c374ddd974..26b787fa836c 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java @@ -30,6 +30,7 @@ import android.window.TransitionInfo; */ public class TransitionInfoBuilder { final TransitionInfo mInfo; + static final int DISPLAY_ID = 0; public TransitionInfoBuilder(@WindowManager.TransitionType int type) { this(type, 0 /* flags */); @@ -38,7 +39,7 @@ public class TransitionInfoBuilder { public TransitionInfoBuilder(@WindowManager.TransitionType int type, @WindowManager.TransitionFlags int flags) { mInfo = new TransitionInfo(type, flags); - mInfo.setRootLeash(createMockSurface(true /* valid */), 0, 0); + mInfo.addRootLeash(DISPLAY_ID, createMockSurface(true /* valid */), 0, 0); } public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode, @@ -61,6 +62,7 @@ public class TransitionInfoBuilder { } public TransitionInfoBuilder addChange(TransitionInfo.Change change) { + change.setDisplayId(DISPLAY_ID, DISPLAY_ID); mInfo.addChange(change); return this; } |