From 552e7363915e9fd1e45e159c24198277826b1b72 Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Mon, 28 Mar 2022 16:11:02 +0800 Subject: [PATCH] Send up-to-date InsetsState to the client after rotation When LOCAL_LAYOUT is enabled, clients compute the window frames on their own. However, for windows which provide insets, the server computes the window frames for updating the InsetsState. In this way, all the clients can receive the up-to-date InsetsState after rotation before the clients of insets source windows report their frames. Before LOCAL_LAYOUT is enabled, the server would layout all the windows after rotation. So the clients receive the up-to-date InsetsStates as well. The logic remains the same in this CL. Bug: 161810301 Bug: 175861127 Test: Perform fixed rotation, seamless rotation, and regular rotation. See if there is anything unexpected. Change-Id: I23246f363d5d9ef974a4f7a64041bc9d56042ade --- .../com/android/server/wm/DisplayContent.java | 35 +++++++++---------- .../com/android/server/wm/DisplayFrames.java | 13 +++---- .../com/android/server/wm/DisplayPolicy.java | 4 --- .../server/wm/InsetsStateController.java | 2 +- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 8eb0046ff9237..3b16fe4ee7362 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -53,6 +53,7 @@ import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static android.view.View.GONE; +import static android.view.ViewRootImpl.LOCAL_LAYOUT; import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.systemBars; @@ -2647,29 +2648,27 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mCurrentPrivacyIndicatorBounds = mCurrentPrivacyIndicatorBounds.updateStaticBounds(staticBounds); if (!Objects.equals(oldBounds, mCurrentPrivacyIndicatorBounds)) { - final DisplayInfo info = mDisplayInfo; - if (mDisplayFrames.onDisplayInfoUpdated(info, - calculateDisplayCutoutForRotation(info.rotation), - calculateRoundedCornersForRotation(info.rotation), - calculatePrivacyIndicatorBoundsForRotation(info.rotation))) { - mInsetsStateController.onDisplayInfoUpdated(true); - } + updateDisplayFrames(false /* insetsSourceMayChange */, true /* notifyInsetsChange */); } } void onDisplayInfoChanged() { - final DisplayInfo info = mDisplayInfo; - if (mDisplayFrames.onDisplayInfoUpdated(info, - calculateDisplayCutoutForRotation(info.rotation), - calculateRoundedCornersForRotation(info.rotation), - calculatePrivacyIndicatorBoundsForRotation(info.rotation))) { - // TODO(b/161810301): Set notifyInsetsChange to true while the server no longer performs - // layout. - mInsetsStateController.onDisplayInfoUpdated(false /* notifyInsetsChanged */); - } + updateDisplayFrames(LOCAL_LAYOUT, LOCAL_LAYOUT); mMinSizeOfResizeableTaskDp = getMinimalTaskSizeDp(); - mInputMonitor.layoutInputConsumers(info.logicalWidth, info.logicalHeight); - mDisplayPolicy.onDisplayInfoChanged(info); + mInputMonitor.layoutInputConsumers(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); + mDisplayPolicy.onDisplayInfoChanged(mDisplayInfo); + } + + private void updateDisplayFrames(boolean insetsSourceMayChange, boolean notifyInsetsChange) { + if (mDisplayFrames.update(mDisplayInfo, + calculateDisplayCutoutForRotation(mDisplayInfo.rotation), + calculateRoundedCornersForRotation(mDisplayInfo.rotation), + calculatePrivacyIndicatorBoundsForRotation(mDisplayInfo.rotation))) { + if (insetsSourceMayChange) { + mDisplayPolicy.updateInsetsSourceFramesExceptIme(mDisplayFrames); + } + mInsetsStateController.onDisplayFramesUpdated(notifyInsetsChange); + } } @Override diff --git a/services/core/java/com/android/server/wm/DisplayFrames.java b/services/core/java/com/android/server/wm/DisplayFrames.java index 45d7141fd5563..76aa7f963aa6a 100644 --- a/services/core/java/com/android/server/wm/DisplayFrames.java +++ b/services/core/java/com/android/server/wm/DisplayFrames.java @@ -64,26 +64,26 @@ public class DisplayFrames { PrivacyIndicatorBounds indicatorBounds) { mDisplayId = displayId; mInsetsState = insetsState; - onDisplayInfoUpdated(info, displayCutout, roundedCorners, indicatorBounds); + update(info, displayCutout, roundedCorners, indicatorBounds); } /** - * Update {@link DisplayFrames} when {@link DisplayInfo} is updated. + * This is called when {@link DisplayInfo} or {@link PrivacyIndicatorBounds} is updated. * * @param info the updated {@link DisplayInfo}. * @param displayCutout the updated {@link DisplayCutout}. * @param roundedCorners the updated {@link RoundedCorners}. - * @return {@code true} if the insets state has been changed; {@code false} otherwise. + * @param indicatorBounds the updated {@link PrivacyIndicatorBounds}. + * @return {@code true} if anything has been changed; {@code false} otherwise. */ - public boolean onDisplayInfoUpdated(DisplayInfo info, @NonNull WmDisplayCutout displayCutout, + public boolean update(DisplayInfo info, @NonNull WmDisplayCutout displayCutout, @NonNull RoundedCorners roundedCorners, @NonNull PrivacyIndicatorBounds indicatorBounds) { - mRotation = info.rotation; - final InsetsState state = mInsetsState; final Rect safe = mDisplayCutoutSafe; final DisplayCutout cutout = displayCutout.getDisplayCutout(); if (mDisplayWidth == info.logicalWidth && mDisplayHeight == info.logicalHeight + && mRotation != info.rotation && state.getDisplayCutout().equals(cutout) && state.getRoundedCorners().equals(roundedCorners) && state.getPrivacyIndicatorBounds().equals(indicatorBounds)) { @@ -91,6 +91,7 @@ public class DisplayFrames { } mDisplayWidth = info.logicalWidth; mDisplayHeight = info.logicalHeight; + mRotation = info.rotation; final Rect unrestricted = mUnrestricted; unrestricted.set(0, 0, mDisplayWidth, mDisplayHeight); state.setDisplayFrame(unrestricted); diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 4573ede13f7f5..3d826bf99df0f 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -1498,10 +1498,6 @@ public class DisplayPolicy { } } - // TODO(b/161810301): No one is calling this since we haven't moved window layout to the client. - // When that happens, this should be called when the display rotation is - // changed, so that we can dispatch the correct insets to all the clients - // before the insets source windows report their frames to the server. void updateInsetsSourceFramesExceptIme(DisplayFrames displayFrames) { for (int i = mInsetsSourceWindowsExceptIme.size() - 1; i >= 0; i--) { final WindowState win = mInsetsSourceWindowsExceptIme.valueAt(i); diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index a19d72e37124a..ed771c202c04e 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -177,7 +177,7 @@ class InsetsStateController { } } - void onDisplayInfoUpdated(boolean notifyInsetsChange) { + void onDisplayFramesUpdated(boolean notifyInsetsChange) { final ArrayList insetsChangedWindows = new ArrayList<>(); mDisplayContent.forAllWindows(w -> { w.mAboveInsetsState.set(mState, displayCutout());