From ecdee86b751a34bf24a992224ffb3fea69f22e56 Mon Sep 17 00:00:00 2001 From: Darryl L Johnson Date: Wed, 23 Sep 2020 14:27:04 -0700 Subject: Reapply display settings to DisplayContent when display changes. When the physical display devices that map to a logical display change onDisplayChanged() is called. However, the current logic only reads the display metric overrides supplied from settings on creation of the DisplayContent. This updates the logic to ensure that when a display changes the most up-to-date settings values are read which may be different from the current values if the logical display is mapped to a different physical display. Bug: 168808369 Test: atest:DisplayContentTests#testDisplaySettingsReappliedWhenDisplayChanged Change-Id: Ia3a0d199f81e0e0ebc531d1edee54638946702f2 --- .../java/com/android/server/wm/DisplayContent.java | 38 +++++++++++++++++++--- .../android/server/wm/DisplayWindowSettings.java | 17 ++++++---- .../com/android/server/wm/DisplayContentTests.java | 22 +++++++++++++ 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index dafa07e5cc60..e7f0e3eb7a76 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -253,9 +253,22 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp ActivityTaskManagerService mAtmService; - /** Unique identifier of this display. */ + /** + * Unique logical identifier of this display. + * + * @see DisplayInfo#displayId + */ final int mDisplayId; + /** + * Unique physical identifier of this display. Unlike {@link #mDisplayId} this value can change + * at runtime if the underlying physical display changes. + * + * @see DisplayInfo#uniqueId + */ + @Nullable + String mCurrentUniqueDisplayId; + /** * We organize all top-level Surfaces into the following layer. * It contains a few Surfaces which are always on top of others, and omitted from @@ -916,6 +929,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mAtmService = mWmService.mAtmService; mDisplay = display; mDisplayId = display.getDisplayId(); + mCurrentUniqueDisplayId = display.getUniqueId(); mOffTokenAcquirer = mRootWindowContainer.mDisplayOffTokenAcquirer; mWallpaperController = new WallpaperController(mWmService, this); display.getDisplayInfo(mDisplayInfo); @@ -2417,13 +2431,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp final int newHeight = rotated ? mDisplayInfo.logicalWidth : mDisplayInfo.logicalHeight; final int newDensity = mDisplayInfo.logicalDensityDpi; final DisplayCutout newCutout = mDisplayInfo.displayCutout; + final String newUniqueId = mDisplayInfo.uniqueId; final boolean displayMetricsChanged = mInitialDisplayWidth != newWidth || mInitialDisplayHeight != newHeight || mInitialDisplayDensity != mDisplayInfo.logicalDensityDpi || !Objects.equals(mInitialDisplayCutout, newCutout); + final boolean physicalDisplayChanged = !newUniqueId.equals(mCurrentUniqueDisplayId); + + if (displayMetricsChanged || physicalDisplayChanged) { + if (physicalDisplayChanged) { + // Reapply the window settings as the underlying physical display has changed. + mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this); + } - if (displayMetricsChanged) { // If there is an override set for base values - use it, otherwise use new values. updateBaseDisplayMetrics(mIsSizeForced ? mBaseDisplayWidth : newWidth, mIsSizeForced ? mBaseDisplayHeight : newHeight, @@ -2434,6 +2455,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mInitialDisplayHeight = newHeight; mInitialDisplayDensity = newDensity; mInitialDisplayCutout = newCutout; + mCurrentUniqueDisplayId = newUniqueId; reconfigureDisplayLocked(); } } @@ -2452,6 +2474,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp /** Update base (override) display metrics. */ void updateBaseDisplayMetrics(int baseWidth, int baseHeight, int baseDensity) { + final int originalWidth = mBaseDisplayWidth; + final int originalHeight = mBaseDisplayHeight; + final int originalDensity = mBaseDisplayDensity; + mBaseDisplayWidth = baseWidth; mBaseDisplayHeight = baseHeight; mBaseDisplayDensity = baseDensity; @@ -2466,9 +2492,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } } - mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight); - - updateBounds(); + if (mBaseDisplayWidth != originalWidth || mBaseDisplayHeight != originalHeight + || mBaseDisplayDensity != originalDensity) { + mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight); + updateBounds(); + } } /** diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java index c8c83a6e34f0..04e37faf0ee4 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java +++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java @@ -385,13 +385,16 @@ class DisplayWindowSettings { dc.getDisplayRotation().restoreSettings(entry.mUserRotationMode, entry.mUserRotation, entry.mFixedToUserRotation); - if (entry.mForcedDensity != 0) { - dc.mBaseDisplayDensity = entry.mForcedDensity; - } - if (entry.mForcedWidth != 0 && entry.mForcedHeight != 0) { - dc.updateBaseDisplayMetrics(entry.mForcedWidth, entry.mForcedHeight, - dc.mBaseDisplayDensity); - } + final boolean hasDensityOverride = entry.mForcedDensity != 0; + final boolean hasSizeOverride = entry.mForcedWidth != 0 && entry.mForcedHeight != 0; + dc.mIsDensityForced = hasDensityOverride; + dc.mIsSizeForced = hasSizeOverride; + + final int width = hasSizeOverride ? entry.mForcedWidth : dc.mBaseDisplayWidth; + final int height = hasSizeOverride ? entry.mForcedHeight : dc.mBaseDisplayHeight; + final int density = hasDensityOverride ? entry.mForcedDensity : dc.mBaseDisplayDensity; + dc.updateBaseDisplayMetrics(width, height, density); + dc.mDisplayScalingDisabled = entry.mForcedScalingMode == FORCE_SCALING_MODE_DISABLED; } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index e45b28e3f8c4..4d0d3b27ee99 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1584,6 +1584,28 @@ public class DisplayContentTests extends WindowTestsBase { assertFalse(publicDc.forceDesktopMode()); } + @Test + public void testDisplaySettingsReappliedWhenDisplayChanged() { + final DisplayInfo displayInfo = new DisplayInfo(); + displayInfo.copyFrom(mDisplayInfo); + final DisplayContent dc = createNewDisplay(displayInfo); + + // Generate width/height/density values different from the default of the display. + final int forcedWidth = dc.mBaseDisplayWidth + 1; + final int forcedHeight = dc.mBaseDisplayHeight + 1;; + final int forcedDensity = dc.mBaseDisplayDensity + 1;; + // Update the forced size and density in settings and the unique id to simualate a display + // remap. + dc.mWmService.mDisplayWindowSettings.setForcedSize(dc, forcedWidth, forcedHeight); + dc.mWmService.mDisplayWindowSettings.setForcedDensity(dc, forcedDensity, 0 /* userId */); + dc.mCurrentUniqueDisplayId = mDisplayInfo.uniqueId + "-test"; + // Trigger display changed. + dc.onDisplayChanged(); + // Ensure overridden size and denisty match the most up-to-date values in settings for the + // display. + verifySizes(dc, forcedWidth, forcedHeight, forcedDensity); + } + private boolean isOptionsPanelAtRight(int displayId) { return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT; } -- cgit v1.2.3-59-g8ed1b