diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index dafa07e5cc606..e7f0e3eb7a76c 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 c8c83a6e34f0c..04e37faf0ee4c 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 e45b28e3f8c49..4d0d3b27ee990 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; }