diff options
6 files changed, 109 insertions, 11 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index b27600800cc6..e845359a35c4 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -102,6 +102,16 @@ public abstract class DisplayManagerInternal { int displayId, DisplayInfo info); /** + * Get current display info without override from WindowManager. + * Current implementation of LogicalDisplay#getDisplayInfoLocked() always returns display info + * with overrides from WM if set. This method can be used for getting real display size without + * overrides to determine if real changes to display metrics happened. + * @param displayId Id of the target display. + * @param outInfo {@link DisplayInfo} to fill. + */ + public abstract void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo); + + /** * Called by the window manager to perform traversals while holding a * surface flinger transaction. */ diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 5494377ceebd..6dedbde01995 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -50,7 +50,7 @@ import java.util.Arrays; * <li>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}.</li> * </ul> * </p><p> @@ -947,7 +947,7 @@ public final class Display { * The size is adjusted based on the current rotation of the display. * </p><p> * 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). * </p> * * @param outSize Set to the real size of the display. diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index a1a74377cf62..ddd918fdcc5d 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -339,6 +339,18 @@ public final class DisplayManagerService extends SystemService { } } + /** + * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo) + */ + private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) { + synchronized (mSyncRoot) { + final LogicalDisplay display = mLogicalDisplays.get(displayId); + if (display != null) { + display.getNonOverrideDisplayInfoLocked(outInfo); + } + } + } + private void performTraversalInTransactionFromWindowManagerInternal() { synchronized (mSyncRoot) { if (!mPendingTraversal) { @@ -1663,6 +1675,11 @@ public final class DisplayManagerService extends SystemService { } @Override + public void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo) { + getNonOverrideDisplayInfoInternal(displayId, outInfo); + } + + @Override public void performTraversalInTransactionFromWindowManager() { performTraversalInTransactionFromWindowManagerInternal(); } diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index a947b4106794..addad0b413a3 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -17,6 +17,7 @@ package com.android.server.display; import android.graphics.Rect; +import android.hardware.display.DisplayManagerInternal; import android.view.Display; import android.view.DisplayInfo; import android.view.Surface; @@ -62,7 +63,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 @@ -142,6 +154,13 @@ final class LogicalDisplay { } /** + * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo) + */ + void getNonOverrideDisplayInfoLocked(DisplayInfo outInfo) { + outInfo.copyFrom(mBaseDisplayInfo); + } + + /** * Sets overridden logical display information from the window manager. * This method can be used to adjust application insets, rotation, and other * properties that the window manager takes care of. diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 3c68e4ff4e7f..da524c764eba 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -180,11 +180,23 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // Mapping from a token IBinder to a WindowToken object on this display. private final HashMap<IBinder, WindowToken> 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(); @@ -1497,8 +1509,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void updateDisplayInfo() { + // Check if display metrics changed and update base values if needed. + updateBaseDisplayMetricsIfNeeded(); + mDisplay.getDisplayInfo(mDisplayInfo); mDisplay.getMetrics(mDisplayMetrics); + for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) { mTaskStackContainers.get(i).updateDisplayInfo(null); } @@ -1514,10 +1530,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } - mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth; - mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight; - mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi; - mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight); + updateBaseDisplayMetrics(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight, + mDisplayInfo.logicalDensityDpi); + mInitialDisplayWidth = mDisplayInfo.logicalWidth; + mInitialDisplayHeight = mDisplayInfo.logicalHeight; + mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi; } void getLogicalDisplayRect(Rect out) { @@ -1547,6 +1564,42 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } + /** + * If display metrics changed, overrides are not set and it's not just a rotation - update base + * values. + */ + private void updateBaseDisplayMetricsIfNeeded() { + // Get real display metrics without overrides from WM. + mService.mDisplayManagerInternal.getNonOverrideDisplayInfo(mDisplayId, mDisplayInfo); + final int orientation = mDisplayInfo.rotation; + final boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270); + final int newWidth = rotated ? mDisplayInfo.logicalHeight : mDisplayInfo.logicalWidth; + final int newHeight = rotated ? mDisplayInfo.logicalWidth : mDisplayInfo.logicalHeight; + final int newDensity = mDisplayInfo.logicalDensityDpi; + + final boolean displayMetricsChanged = mInitialDisplayWidth != newWidth + || mInitialDisplayHeight != newHeight + || mInitialDisplayDensity != mDisplayInfo.logicalDensityDpi; + + if (displayMetricsChanged) { + // Check if display size or density is forced. + final boolean isDisplaySizeForced = mBaseDisplayWidth != mInitialDisplayWidth + || mBaseDisplayHeight != mInitialDisplayHeight; + final boolean isDisplayDensityForced = mBaseDisplayDensity != mInitialDisplayDensity; + + // If there is an override set for base values - use it, otherwise use new values. + updateBaseDisplayMetrics(isDisplaySizeForced ? mBaseDisplayWidth : newWidth, + isDisplaySizeForced ? mBaseDisplayHeight : newHeight, + isDisplayDensityForced ? mBaseDisplayDensity : newDensity); + + // Real display metrics changed, so we should also update initial values. + mInitialDisplayWidth = newWidth; + mInitialDisplayHeight = newHeight; + mInitialDisplayDensity = newDensity; + mService.reconfigureDisplayLocked(this); + } + } + /** Sets the maximum width the screen resolution can be */ void setMaxUiWidth(int width) { if (DEBUG_DISPLAY) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 95fbbb89a649..1691d1408356 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -5312,8 +5312,8 @@ public class WindowManagerService extends IWindowManager.Stub if (displayContent.mBaseDisplayWidth != width || displayContent.mBaseDisplayHeight != height) { Slog.i(TAG_WM, "FORCED DISPLAY SIZE: " + width + "x" + height); - displayContent.mBaseDisplayWidth = width; - displayContent.mBaseDisplayHeight = height; + displayContent.updateBaseDisplayMetrics(width, height, + displayContent.mBaseDisplayDensity); } } catch (NumberFormatException ex) { } @@ -5338,8 +5338,7 @@ public class WindowManagerService extends IWindowManager.Stub // displayContent must not be null private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) { Slog.i(TAG_WM, "Using new display size: " + width + "x" + height); - displayContent.mBaseDisplayWidth = width; - displayContent.mBaseDisplayHeight = height; + displayContent.updateBaseDisplayMetrics(width, height, displayContent.mBaseDisplayDensity); reconfigureDisplayLocked(displayContent); } |