From eddb7c0985e1fac8bdbeaaed40c678c0dc9da321 Mon Sep 17 00:00:00 2001 From: Andrii Kulian Date: Tue, 21 Mar 2017 10:17:03 -0700 Subject: [PATCH] Update display contents when metrics change There are two separate overrides for display metrics in DisplayManager and WindowManager: - In DM - LogicalDisplay#mOverrideDisplayInfo, in most cases not null. - In WM - DisplayContent#mBaseDisplayWidth/Height/Density, different from #mInitialDisplayWidth/Height/Density values when some metrics are forced. When display was resized its windows weren't updated because of two problems: old LogicaDisplay#mOverrideDisplayInfo was preventing WM from detecting the change and override (base) display metrics were never updated by resize. When display size changes: - Before this CL: DM receives DISPLAY_CHANGED event, it updates internal values. In most cases there is an override obtained from WM and WM doesn't get new values from LogicalDisplay#getDisplayInfoLocked(). - With this CL: DM receives DISPLAY_CHANGED event, it updates internal values and resets the override received from WM. WM will receive updated values and will decide whether to apply them or not: if there is no override in WM - it will apply values from WM, otherwise it will keep the override. In both cases WM will eventually update its own override and will update the override in DM. Bug: 35258051 Bug: 34164473 Test: android.server.cts.ActivityManagerDisplayTests Test: #testDisplayResize Test: #testForceDisplayMetrics Change-Id: I80795434a6a35adb0577fbce334d76fabd2fa03d --- core/java/android/view/Display.java | 4 +- .../server/display/LogicalDisplay.java | 16 ++++- .../com/android/server/wm/DisplayContent.java | 69 +++++++++++++++++-- .../server/wm/WindowManagerService.java | 7 +- 4 files changed, 85 insertions(+), 11 deletions(-) diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 5494377ceebd1..6dedbde01995a 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -50,7 +50,7 @@ import java.util.Arrays; *
  • The real display area specifies the part of the display that contains content * including the system decorations. Even so, the real display area may be smaller than the * physical size of the display if the window manager is emulating a smaller display - * using (adb shell am display-size). Use the following methods to query the + * using (adb shell wm size). Use the following methods to query the * real display area: {@link #getRealSize}, {@link #getRealMetrics}.
  • * *

    @@ -947,7 +947,7 @@ public final class Display { * The size is adjusted based on the current rotation of the display. *

    * The real size may be smaller than the physical size of the screen when the - * window manager is emulating a smaller display (using adb shell am display-size). + * window manager is emulating a smaller display (using adb shell wm size). *

    * * @param outSize Set to the real size of the display. diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index a947b41067941..f9bc12b6d23d0 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -62,7 +62,18 @@ final class LogicalDisplay { private final int mDisplayId; private final int mLayerStack; - private DisplayInfo mOverrideDisplayInfo; // set by the window manager + /** + * Override information set by the window manager. Will be reported instead of {@link #mInfo} + * if not null. + * @see #setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo) + * @see #getDisplayInfoLocked() + */ + private DisplayInfo mOverrideDisplayInfo; + /** + * Current display info. Initialized with {@link #mBaseDisplayInfo}. Set to {@code null} if + * needs to be updated. + * @see #getDisplayInfoLocked() + */ private DisplayInfo mInfo; // The display device that this logical display is based on and which @@ -261,6 +272,9 @@ final class LogicalDisplay { mPrimaryDisplayDeviceInfo = deviceInfo; mInfo = null; + // Make sure that WM will be notified of new changes. It will then decide whether to + // apply them or not and will set the value again. + mOverrideDisplayInfo = null; } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index e5b00f3df79a2..01a992f6bc444 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -179,11 +179,23 @@ class DisplayContent extends WindowContainer mTokenMap = new HashMap(); + // Initial display metrics. int mInitialDisplayWidth = 0; int mInitialDisplayHeight = 0; int mInitialDisplayDensity = 0; + + /** + * Overridden display size. Initialized with {@link #mInitialDisplayWidth} + * and {@link #mInitialDisplayHeight}, but can be set via shell command "adb shell wm size". + * @see WindowManagerService#setForcedDisplaySize(int, int, int) + */ int mBaseDisplayWidth = 0; int mBaseDisplayHeight = 0; + /** + * Overridden display density for current user. Initialized with {@link #mInitialDisplayDensity} + * but can be set from Settings or via shell command "adb shell wm density". + * @see WindowManagerService#setForcedDisplayDensityForUser(int, int, int) + */ int mBaseDisplayDensity = 0; boolean mDisplayScalingDisabled; private final DisplayInfo mDisplayInfo = new DisplayInfo(); @@ -1511,6 +1523,10 @@ class DisplayContent extends WindowContainer= 0; --i) { mTaskStackContainers.get(i).updateDisplayInfo(null); } @@ -1526,10 +1542,11 @@ class DisplayContent extends WindowContainer