From 20a817a198b1cc9711e0b03b20e8a792f5518c2d Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Tue, 22 Jun 2021 19:22:06 -0700 Subject: [PATCH] Fix rotation shell transition The old freeze/legacy display rotation logic was running with shell transitions enabled. Additionally, WindowState.removeImmediately was removing its child surface in the wrong order causing it to not be removed on the sync transaction and yielding several frames of blackness. Bug: 190002115 Test: enable shell transitions, launch a rotatable app (like messages), rotate device. Observe a jumpcut without black flicker. Change-Id: Ia2ce00b1cf4317c6678e6b5f91407296b23cc87e --- .../core/java/com/android/server/wm/ActivityRecord.java | 4 +++- services/core/java/com/android/server/wm/WindowState.java | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index a16d6fe11902c..6970c63d71354 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -8151,7 +8151,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) { // Aha, the activity isn't handling the change, so DIE DIE DIE. configChangeFlags |= changes; - startFreezingScreenLocked(globalChanges); + if (!mAtmService.getTransitionController().isShellTransitionsEnabled()) { + startFreezingScreenLocked(globalChanges); + } forceNewConfig = false; preserveWindow &= isResizeOnlyChange(changes); final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged()); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 309ceb273907b..10e2486651903 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2390,6 +2390,12 @@ class WindowState extends WindowContainer implements WindowManagerP @Override void removeImmediately() { + if (!mRemoved) { + // Destroy surface before super call. The general pattern is that the children need + // to be removed before the parent (so that the sync-engine tracking works). Since + // WindowStateAnimator is a "virtual" child, we have to do it manually here. + mWinAnimator.destroySurfaceLocked(getSyncTransaction()); + } super.removeImmediately(); if (mRemoved) { @@ -2431,8 +2437,6 @@ class WindowState extends WindowContainer implements WindowManagerP disposeInputChannel(); - mWinAnimator.destroySurfaceLocked(mTmpTransaction); - mTmpTransaction.apply(); mSession.windowRemovedLocked(); try { mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);