OSDN Git Service

Disables display content scaling for foldables
authorSam Lin <samlin@google.com>
Mon, 18 Feb 2019 12:50:26 +0000 (04:50 -0800)
committerCharles Chen <charlesccchen@google.com>
Wed, 20 Feb 2019 12:09:29 +0000 (20:09 +0800)
When setting folded area with changes both in width and height (set
0,0,540,1080 to a 1080x2160 device), the content of display will be
auto-scaled to physical display size. It is not an expected behavior
for foldable devices. Disable auto-scale to fix this issue.

1. LogicalDisplay.configureDisplayLocked() scales the contents according
the DisplayInfo.flags.
2. DisplayInfo.flags should not be overridden by design for a logical
display.
3. Adds disableDisplayScaling() for DisplayFoldController to bypass that.

Bug: 123245311
Test: atest WmTests
Test: adb shell wm folded-area 0,0,840,1260
Change-Id: I9a24c5d56799981b4f2cfe82fdf1898d87193681

core/java/android/hardware/display/DisplayManagerInternal.java
services/core/java/com/android/server/display/DisplayManagerService.java
services/core/java/com/android/server/display/LogicalDisplay.java
services/core/java/com/android/server/policy/DisplayFoldController.java

index 1af9cde..43ea682 100644 (file)
@@ -171,6 +171,15 @@ public abstract class DisplayManagerInternal {
     public abstract void setDisplayOffsets(int displayId, int x, int y);
 
     /**
+     * Disables scaling for a display.
+     *
+     * @param displayId The logical display id to disable scaling for.
+     * @param disableScaling {@code true} to disable scaling,
+     * {@code false} to use the default scaling behavior of the logical display.
+     */
+    public abstract void setDisplayScalingDisabled(int displayId, boolean disableScaling);
+
+    /**
      * Provide a list of UIDs that are present on the display and are allowed to access it.
      *
      * @param displayAccessUIDs Mapping displayId -> int array of UIDs.
index b99ba7e..b2509e9 100644 (file)
@@ -1222,6 +1222,22 @@ public final class DisplayManagerService extends SystemService {
         }
     }
 
+    private void setDisplayScalingDisabledInternal(int displayId, boolean disable) {
+        synchronized (mSyncRoot) {
+            final LogicalDisplay display = mLogicalDisplays.get(displayId);
+            if (display == null) {
+                return;
+            }
+            if (display.isDisplayScalingDisabled() != disable) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Display " + displayId + " content scaling disabled = " + disable);
+                }
+                display.setDisplayScalingDisabledLocked(disable);
+                scheduleTraversalLocked(false);
+            }
+        }
+    }
+
     // Updates the lists of UIDs that are present on displays.
     private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) {
         synchronized (mSyncRoot) {
@@ -2359,6 +2375,11 @@ public final class DisplayManagerService extends SystemService {
         }
 
         @Override
+        public void setDisplayScalingDisabled(int displayId, boolean disableScaling) {
+            setDisplayScalingDisabledInternal(displayId, disableScaling);
+        }
+
+        @Override
         public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) {
             setDisplayAccessUIDsInternal(newDisplayAccessUIDs);
         }
index 7414e55..7ee8422 100644 (file)
@@ -94,6 +94,14 @@ final class LogicalDisplay {
     private int mDisplayOffsetX;
     private int mDisplayOffsetY;
 
+    /**
+     * {@code true} if display scaling is disabled, or {@code false} if the default scaling mode
+     * is used.
+     * @see #isDisplayScalingDisabled()
+     * @see #setDisplayScalingDisabledLocked(boolean)
+     */
+    private boolean mDisplayScalingDisabled;
+
     // Temporary rectangle used when needed.
     private final Rect mTempLayerStackRect = new Rect();
     private final Rect mTempDisplayRect = new Rect();
@@ -397,7 +405,7 @@ final class LogicalDisplay {
         // multiplying the fractions by the product of their denominators before
         // comparing them.
         int displayRectWidth, displayRectHeight;
-        if ((displayInfo.flags & Display.FLAG_SCALING_DISABLED) != 0) {
+        if ((displayInfo.flags & Display.FLAG_SCALING_DISABLED) != 0 || mDisplayScalingDisabled) {
             displayRectWidth = displayInfo.logicalWidth;
             displayRectHeight = displayInfo.logicalHeight;
         } else if (physWidth * displayInfo.logicalHeight
@@ -501,6 +509,24 @@ final class LogicalDisplay {
         mDisplayOffsetY = y;
     }
 
+    /**
+     * @return {@code true} if display scaling is disabled, or {@code false} if the default scaling
+     * mode is used.
+     */
+    public boolean isDisplayScalingDisabled() {
+        return mDisplayScalingDisabled;
+    }
+
+    /**
+     * Disables scaling for a display.
+     *
+     * @param disableScaling {@code true} to disable scaling,
+     * {@code false} to use the default scaling behavior of the logical display.
+     */
+    public void setDisplayScalingDisabledLocked(boolean disableScaling) {
+        mDisplayScalingDisabled = disableScaling;
+    }
+
     public void dumpLocked(PrintWriter pw) {
         pw.println("mDisplayId=" + mDisplayId);
         pw.println("mLayerStack=" + mLayerStack);
@@ -508,6 +534,7 @@ final class LogicalDisplay {
         pw.println("mRequestedMode=" + mRequestedModeId);
         pw.println("mRequestedColorMode=" + mRequestedColorMode);
         pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")");
+        pw.println("mDisplayScalingDisabled=" + mDisplayScalingDisabled);
         pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ?
                 mPrimaryDisplayDevice.getNameLocked() : "null"));
         pw.println("mBaseDisplayInfo=" + mBaseDisplayInfo);
index 0c6b773..cf026e9 100644 (file)
@@ -87,10 +87,13 @@ class DisplayFoldController {
             final int dy = (mNonOverrideDisplayInfo.logicalHeight - foldedArea.height()) / 2
                     - foldedArea.top;
 
+            // Bypass scaling otherwise LogicalDisplay will scale contents by default.
+            mDisplayManagerInternal.setDisplayScalingDisabled(mDisplayId, true);
             mWindowManagerInternal.setForcedDisplaySize(mDisplayId,
                     foldedArea.width(), foldedArea.height());
             mDisplayManagerInternal.setDisplayOffsets(mDisplayId, -dx, -dy);
         } else {
+            mDisplayManagerInternal.setDisplayScalingDisabled(mDisplayId, false);
             mWindowManagerInternal.clearForcedDisplaySize(mDisplayId);
             mDisplayManagerInternal.setDisplayOffsets(mDisplayId, 0, 0);
         }