Calculate the correct surface layers for finishTransaction

We normally prevent assignLayers from touching surface z-order
during transition animations. However, this causes a problem
when multiple transitions happen in quick succession (eg. during
CTS tests) because final surface z-order may not be updated.

To fix this, allow assignLayers to set layers into the
finishTransaction. This is applied by shell and is expected
to represent the "z-order at the end of animation", so we
obviously should allow it to get the fully calculated layers.

Bug: 237545923
Test: atest PinnedStackTests
Change-Id: Ifb8c339fcd9fce7d3457dae806b6d3b186ea5d5c
This commit is contained in:
Evan Rosky
2022-07-11 16:45:48 -07:00
parent ca9df1de5b
commit 06972aef44
3 changed files with 26 additions and 4 deletions

View File

@@ -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);

View File

@@ -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();

View File

@@ -2473,7 +2473,7 @@ class WindowContainer<E extends 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);