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
This commit is contained in:
Tiger Huang
2022-03-10 20:52:54 +08:00
parent a345e5bd49
commit 66bc36a0e7
2 changed files with 39 additions and 95 deletions

View File

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

View File

@@ -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,