Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 66bc36a0 authored by Tiger Huang's avatar Tiger Huang
Browse files

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
parent a345e5bd
Loading
Loading
Loading
Loading
+25 −44
Original line number Diff line number Diff line
@@ -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,15 +4443,6 @@ 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);

@@ -4472,28 +4462,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            setLayoutNeeded();
        }

            // 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");
            }

            // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think it is animating.
        // 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();
            mDisplayPolicy.finishPostLayoutPolicyLw();
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
            if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
                    "after finishPostLayoutPolicyLw", pendingLayoutChanges);
        mInsetsStateController.onPostLayout();
        } while (pendingLayoutChanges != 0);

        mTmpApplySurfaceChangesTransactionState.reset();

+14 −51
Original line number Diff line number Diff line
@@ -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,