From 66bc36a0e7a7d3de2fd02400949e779dd6a6656f Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Thu, 10 Mar 2022 20:52:54 +0800 Subject: [PATCH] Don't perform another layout after finishPostLayoutPolicyLw If the visibility of any insets is changed, InsetsSourceProvider will post LAYOUT_AND_ASSIGN_WINDOW_LAYERS_IF_NEEDED, and we will perform layout there. The logic in finishPostLayoutPolicyLw only checks the visibility change of status bar, which doesn't cover all insets. We rely on LAYOUT_AND_ASSIGN_WINDOW_LAYERS_IF_NEEDED instead. This CL also moves the logic about topAppHidesStatusBar to updateSystemBarsLw, after updating mForceShowSystemBars, because it affects topAppHidesStatusBar. This is a step to move the window layout to the client side. Bug: 161810301 Test: Rotate Camera and see if it can play ROTATION_ANIMATION_SEAMLESS. Rotate Camera with notification shade expended and see if it can play ROTATION_ANIMATION_ROTATE. Change-Id: I94e06a99757fa97376d5644865728aa28c1d6883 --- .../com/android/server/wm/DisplayContent.java | 69 +++++++------------ .../com/android/server/wm/DisplayPolicy.java | 65 ++++------------- 2 files changed, 39 insertions(+), 95 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 718a28de6af93..d8823a263d8b9 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -144,7 +144,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.REPORT_HARD_KEYBOARD_STATUS_CHANGE; import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT; -import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_ASSIGN_LAYERS; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; @@ -4444,56 +4443,38 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mTmpUpdateAllDrawn.clear(); - int repeats = 0; - do { - repeats++; - if (repeats > 6) { - Slog.w(TAG, "Animation repeat aborted after too many iterations"); - clearLayoutNeeded(); - break; - } + if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("On entry to LockedInner", + pendingLayoutChanges); - if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("On entry to LockedInner", - pendingLayoutChanges); + if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) { + mWallpaperController.adjustWallpaperWindows(); + } - if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) { - mWallpaperController.adjustWallpaperWindows(); - } - - if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) { - if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout"); - if (updateOrientation()) { - setLayoutNeeded(); - sendNewConfiguration(); - } - } - - if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) { + if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) { + if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout"); + if (updateOrientation()) { setLayoutNeeded(); + sendNewConfiguration(); } + } - // FIRST LOOP: Perform a layout, if needed. - if (repeats < LAYOUT_REPEAT_THRESHOLD) { - performLayout(repeats == 1, false /* updateInputWindows */); - } else { - Slog.w(TAG, "Layout repeat skipped after too many iterations"); - } + if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) { + setLayoutNeeded(); + } - // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think it is animating. - pendingLayoutChanges = 0; + // Perform a layout, if needed. + performLayout(true /* initial */, false /* updateInputWindows */); + pendingLayoutChanges = 0; - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy"); - try { - mDisplayPolicy.beginPostLayoutPolicyLw(); - forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */); - pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw(); - } finally { - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - } - if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats( - "after finishPostLayoutPolicyLw", pendingLayoutChanges); - mInsetsStateController.onPostLayout(); - } while (pendingLayoutChanges != 0); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy"); + try { + mDisplayPolicy.beginPostLayoutPolicyLw(); + forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */); + mDisplayPolicy.finishPostLayoutPolicyLw(); + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + mInsetsStateController.onPostLayout(); mTmpApplySurfaceChangesTransactionState.reset(); diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 4641bb14c958f..7da59b9092a85 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -45,7 +45,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACK import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; -import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; @@ -78,7 +77,6 @@ import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SCREEN_ON; import static com.android.server.policy.PhoneWindowManager.TOAST_WINDOW_TIMEOUT; -import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; import static com.android.server.policy.WindowManagerPolicy.TRANSIT_ENTER; import static com.android.server.policy.WindowManagerPolicy.TRANSIT_EXIT; import static com.android.server.policy.WindowManagerPolicy.TRANSIT_HIDE; @@ -1704,21 +1702,9 @@ public class DisplayPolicy { } /** - * Called following layout of all windows and after policy has been applied - * to each window. If in this function you do - * something that may have modified the animation state of another window, - * be sure to return non-zero in order to perform another pass through layout. - * - * @return Return any bit set of - * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_LAYOUT}, - * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_CONFIG}, - * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_WALLPAPER}, or - * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_ANIM}. + * Called following layout of all windows and after policy has been applied to each window. */ - public int finishPostLayoutPolicyLw() { - int changes = 0; - boolean topIsFullscreen = false; - + public void finishPostLayoutPolicyLw() { // If we are not currently showing a dream then remember the current // lockscreen state. We will use this to determine whether the dream // started while the lockscreen was showing and remember this state @@ -1727,40 +1713,6 @@ public class DisplayPolicy { mDreamingLockscreen = mService.mPolicy.isKeyguardShowingAndNotOccluded(); } - if (getStatusBar() != null) { - if (DEBUG_LAYOUT) Slog.i(TAG, " top=" + mTopFullscreenOpaqueWindowState); - final boolean forceShowStatusBar = (getStatusBar().getAttrs().privateFlags - & PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR) != 0; - - boolean topAppHidesStatusBar = topAppHidesStatusBar(); - if (forceShowStatusBar) { - if (DEBUG_LAYOUT) Slog.v(TAG, "Showing status bar: forced"); - // Maintain fullscreen layout until incoming animation is complete. - topIsFullscreen = mTopIsFullscreen && mStatusBar.isAnimatingLw(); - } else if (mTopFullscreenOpaqueWindowState != null) { - topIsFullscreen = topAppHidesStatusBar; - // The subtle difference between the window for mTopFullscreenOpaqueWindowState - // and mTopIsFullscreen is that mTopIsFullscreen is set only if the window - // requests to hide the status bar. Not sure if there is another way that to be the - // case though. - if (!topIsFullscreen) { - topAppHidesStatusBar = false; - } - } - StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); - if (statusBar != null) { - statusBar.setTopAppHidesStatusBar(topAppHidesStatusBar); - } - } - - if (mTopIsFullscreen != topIsFullscreen) { - if (!topIsFullscreen) { - // Force another layout when status bar becomes fully shown. - changes |= FINISH_LAYOUT_REDO_LAYOUT; - } - mTopIsFullscreen = topIsFullscreen; - } - updateSystemBarAttributes(); if (mShowingDream != mLastShowingDream) { @@ -1770,7 +1722,6 @@ public class DisplayPolicy { } mService.mPolicy.setAllowLockscreenWhenOn(getDisplayId(), mAllowLockscreenWhenOn); - return changes; } /** @@ -2434,6 +2385,18 @@ public class DisplayPolicy { mForceShowSystemBars = multiWindowTaskVisible || freeformRootTaskVisible; mDisplayContent.getInsetsPolicy().updateBarControlTarget(win); + final boolean topAppHidesStatusBar = topAppHidesStatusBar(); + if (getStatusBar() != null) { + final StatusBarManagerInternal statusBar = getStatusBarManagerInternal(); + if (statusBar != null) { + statusBar.setTopAppHidesStatusBar(topAppHidesStatusBar); + } + } + + // If the top app is not fullscreen, only the default rotation animation is allowed. + mTopIsFullscreen = topAppHidesStatusBar + && (mNotificationShade == null || !mNotificationShade.isVisible()); + int appearance = APPEARANCE_OPAQUE_NAVIGATION_BARS | APPEARANCE_OPAQUE_STATUS_BARS; appearance = configureStatusBarOpacity(appearance); appearance = configureNavBarOpacity(appearance, multiWindowTaskVisible,