From ba0c5571561cc1a7ad22bf9577388c32ee3a1567 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 17 Mar 2022 22:24:24 +0800 Subject: [PATCH] Use sync transaction for dim layer and scale Otherwise when performing shell rotation animation, the buffer layers are waiting for start transaction but their parent container layers have applied the change in new rotation. Then before the rotation animation starts, those window may be placed at strange position. Also 1. Skip window animation if display is in transition, because it is usually hard to observe while the whole content of display is changing. Sync transaction cannot help this case because it may be like to delay the leash creation and jump to the end of animation if the sync transaction is applied later. The window level animation in this case may happen on an activity with declaring window exit/enter animation and it doesn't handle config change. So the relaunch adds/removes the window that triggers exit/enter. 2. Fix a missing condition of async rotation that screen decorations draw in new rotation before the rotation animation starts. Bug: 225324120 Test: adb shell setprop persist.wm.debug.shell_transit 1; reboot Start a dialog style activity with FLAG_SHOW_WALLPAPER, screenOrientation="fullSensor", and without configChanges (to trigger relaunch). Rotate the device and check no obvious flickering. Change-Id: Ic4239ca7c7e3cd9e6ecae6f4ec7e823104b638de --- .../android/server/wm/AsyncRotationController.java | 3 ++- .../core/java/com/android/server/wm/DisplayArea.java | 2 +- services/core/java/com/android/server/wm/Task.java | 7 ++++--- .../java/com/android/server/wm/TaskFragment.java | 2 +- .../core/java/com/android/server/wm/WindowState.java | 12 ++++++++---- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java index 220d9ec8febbf..e79e77cee58ba 100644 --- a/services/core/java/com/android/server/wm/AsyncRotationController.java +++ b/services/core/java/com/android/server/wm/AsyncRotationController.java @@ -144,7 +144,8 @@ class AsyncRotationController extends FadeAnimationController implements Consume // Legacy animation doesn't need to wait for the start transaction. if (mTransitionOp == OP_LEGACY) { mIsStartTransactionCommitted = true; - } else if (displayContent.mTransitionController.useShellTransitionsRotation()) { + } else if (displayContent.mTransitionController.useShellTransitionsRotation() + || displayContent.mTransitionController.isCollecting(displayContent)) { keepAppearanceInPreviousRotation(); } } diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index 08681119a3063..dfa3b743292e2 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -662,7 +662,7 @@ public class DisplayArea extends WindowContainer { mDimmer.resetDimStates(); } - if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) { + if (mDimmer.updateDims(getSyncTransaction(), mTmpDimBoundsRect)) { scheduleAnimation(); } } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index f71bd7288532f..709b1c465b91e 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -3297,9 +3297,10 @@ class Task extends TaskFragment { mTmpDimBoundsRect.offsetTo(0, 0); } - updateShadowsRadius(isFocused(), getSyncTransaction()); + final SurfaceControl.Transaction t = getSyncTransaction(); + updateShadowsRadius(isFocused(), t); - if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) { + if (mDimmer.updateDims(t, mTmpDimBoundsRect)) { scheduleAnimation(); } @@ -3309,7 +3310,7 @@ class Task extends TaskFragment { final boolean show = isVisible() || isAnimating(TRANSITION | PARENTS | CHILDREN); if (mSurfaceControl != null) { if (show != mLastSurfaceShowing) { - getSyncTransaction().setVisibility(mSurfaceControl, show); + t.setVisibility(mSurfaceControl, show); } } mLastSurfaceShowing = show; diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index d187bd6f3dfdf..7a5feb9de610c 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -2424,7 +2424,7 @@ class TaskFragment extends WindowContainer { // Bounds need to be relative, as the dim layer is a child. final Rect dimBounds = getBounds(); dimBounds.offsetTo(0 /* newLeft */, 0 /* newTop */); - if (mDimmer.updateDims(getPendingTransaction(), dimBounds)) { + if (mDimmer.updateDims(getSyncTransaction(), dimBounds)) { scheduleAnimation(); } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 60e196c584653..54d1b5a5b864d 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5256,6 +5256,12 @@ class WindowState extends WindowContainer implements WindowManagerP if (mControllableInsetProvider != null) { return; } + if (mDisplayContent.inTransition()) { + // Skip because the animation is usually unnoticeable (e.g. covered by rotation + // animation) and the animation bounds could be inconsistent, such as depending + // on when the window applies its draw transaction with new rotation. + return; + } final DisplayInfo displayInfo = getDisplayInfo(); anim.initialize(mWindowFrames.mFrame.width(), mWindowFrames.mFrame.height(), @@ -5500,10 +5506,8 @@ class WindowState extends WindowContainer implements WindowManagerP } float newHScale = mHScale * mGlobalScale * mWallpaperScale; float newVScale = mVScale * mGlobalScale * mWallpaperScale; - if (mLastHScale != newHScale || - mLastVScale != newVScale ) { - getPendingTransaction().setMatrix(getSurfaceControl(), - newHScale, 0, 0, newVScale); + if (mLastHScale != newHScale || mLastVScale != newVScale) { + getSyncTransaction().setMatrix(mSurfaceControl, newHScale, 0, 0, newVScale); mLastHScale = newHScale; mLastVScale = newVScale; }