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
This commit is contained in:
Tiger Huang
2022-03-28 16:11:02 +08:00
parent 923eb82c53
commit 552e736391
4 changed files with 25 additions and 29 deletions

View File

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

View File

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

View File

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

View File

@@ -177,7 +177,7 @@ class InsetsStateController {
}
}
void onDisplayInfoUpdated(boolean notifyInsetsChange) {
void onDisplayFramesUpdated(boolean notifyInsetsChange) {
final ArrayList<WindowState> insetsChangedWindows = new ArrayList<>();
mDisplayContent.forAllWindows(w -> {
w.mAboveInsetsState.set(mState, displayCutout());