diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 09f6110b517ff..c455ac1dd3706 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -533,9 +533,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } // Need to update layers on involved displays since they were all paused while // the animation played. This puts the layers back into the correct order. - for (int i = displays.size() - 1; i >= 0; --i) { - if (displays.valueAt(i) == null) continue; - displays.valueAt(i).assignChildLayers(t); + mController.mBuildingFinishLayers = true; + try { + for (int i = displays.size() - 1; i >= 0; --i) { + if (displays.valueAt(i) == null) continue; + displays.valueAt(i).assignChildLayers(t); + } + } finally { + mController.mBuildingFinishLayers = false; } if (rootLeash.isValid()) { t.reparent(rootLeash, null); diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index dbc2c5fb0ce30..88572a937156e 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -100,6 +100,14 @@ class TransitionController { // TODO(b/188595497): remove when not needed. final StatusBarManagerInternal mStatusBar; + /** + * `true` when building surface layer order for the finish transaction. We want to prevent + * wm from touching z-order of surfaces during transitions, but we still need to be able to + * calculate the layers for the finishTransaction. So, when assigning layers into the finish + * transaction, set this to true so that the {@link canAssignLayers} will allow it. + */ + boolean mBuildingFinishLayers = false; + TransitionController(ActivityTaskManagerService atm, TaskSnapshotController taskSnapshotController, TransitionTracer transitionTracer) { @@ -309,6 +317,15 @@ class TransitionController { return false; } + /** + * Whether WM can assign layers to window surfaces at this time. This is usually false while + * playing, but can be "opened-up" for certain transition operations like calculating layers + * for finishTransaction. + */ + boolean canAssignLayers() { + return mBuildingFinishLayers || !isPlaying(); + } + @WindowConfiguration.WindowingMode int getWindowingModeAtStart(@NonNull WindowContainer wc) { if (mCollectingTransition == null) return wc.getWindowingMode(); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 19b3384ee4042..8a32df63076b5 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -2473,7 +2473,7 @@ class WindowContainer extends ConfigurationContainer< void assignLayer(Transaction t, int layer) { // Don't assign layers while a transition animation is playing // TODO(b/173528115): establish robust best-practices around z-order fighting. - if (mTransitionController.isPlaying()) return; + if (!mTransitionController.canAssignLayers()) return; final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null; if (mSurfaceControl != null && changed) { setLayer(t, layer);