Disables display content scaling for foldables

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
This commit is contained in:
Sam Lin
2019-02-18 04:50:26 -08:00
committed by Charles Chen
parent aa7b682699
commit 4c3ac2ba26
4 changed files with 61 additions and 1 deletions

View File

@@ -170,6 +170,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.
*

View 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) {
@@ -2358,6 +2374,11 @@ public final class DisplayManagerService extends SystemService {
setDisplayOffsetsInternal(displayId, x, y);
}
@Override
public void setDisplayScalingDisabled(int displayId, boolean disableScaling) {
setDisplayScalingDisabledInternal(displayId, disableScaling);
}
@Override
public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) {
setDisplayAccessUIDsInternal(newDisplayAccessUIDs);

View 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);

View 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);
}