Validate forced display size from settings
To avoid unexpected extreme large value that breaks bootup.
e.g. max=2147483647
adb shell settings set global display_size_forced "$max,$max"
adb reboot
Bug: 238420014
Test: atest DisplayWindowSettingsTests# \
testDisplayWindowSettingsAppliedOnDisplayReady
Change-Id: If67f344cf55620b9c2fde2cfdbe20457021ff62e
This commit is contained in:
@@ -2258,6 +2258,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) {
|
||||
return WmDisplayCutout.NO_CUTOUT;
|
||||
}
|
||||
if (displayWidth == displayHeight) {
|
||||
Slog.w(TAG, "Ignore cutout because display size is square: " + displayWidth);
|
||||
// Avoid UnsupportedOperationException because DisplayCutout#computeSafeInsets doesn't
|
||||
// support square size.
|
||||
return WmDisplayCutout.NO_CUTOUT;
|
||||
}
|
||||
if (rotation == ROTATION_0) {
|
||||
return WmDisplayCutout.computeSafeInsets(
|
||||
cutout, displayWidth, displayHeight);
|
||||
@@ -3078,13 +3084,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
|
||||
mIsSizeForced = mInitialDisplayWidth != width || mInitialDisplayHeight != height;
|
||||
if (mIsSizeForced) {
|
||||
// Set some sort of reasonable bounds on the size of the display that we will try
|
||||
// to emulate.
|
||||
final int minSize = 200;
|
||||
final int maxScale = 3;
|
||||
final int maxSize = Math.max(mInitialDisplayWidth, mInitialDisplayHeight) * maxScale;
|
||||
width = Math.min(Math.max(width, minSize), maxSize);
|
||||
height = Math.min(Math.max(height, minSize), maxSize);
|
||||
final Point size = getValidForcedSize(width, height);
|
||||
width = size.x;
|
||||
height = size.y;
|
||||
}
|
||||
|
||||
Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
|
||||
@@ -3099,6 +3101,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
mWmService.mDisplayWindowSettings.setForcedSize(this, width, height);
|
||||
}
|
||||
|
||||
/** Returns a reasonable size for setting forced display size. */
|
||||
Point getValidForcedSize(int w, int h) {
|
||||
final int minSize = 200;
|
||||
final int maxScale = 3;
|
||||
final int maxSize = Math.max(mInitialDisplayWidth, mInitialDisplayHeight) * maxScale;
|
||||
w = Math.min(Math.max(w, minSize), maxSize);
|
||||
h = Math.min(Math.max(h, minSize), maxSize);
|
||||
return new Point(w, h);
|
||||
}
|
||||
|
||||
DisplayCutout loadDisplayCutout(int displayWidth, int displayHeight) {
|
||||
if (mDisplayPolicy == null || mInitialDisplayCutout == null) {
|
||||
return null;
|
||||
|
||||
@@ -5736,10 +5736,12 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
if (sizeStr != null && sizeStr.length() > 0) {
|
||||
final int pos = sizeStr.indexOf(',');
|
||||
if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
|
||||
int width, height;
|
||||
try {
|
||||
width = Integer.parseInt(sizeStr.substring(0, pos));
|
||||
height = Integer.parseInt(sizeStr.substring(pos + 1));
|
||||
final Point size = displayContent.getValidForcedSize(
|
||||
Integer.parseInt(sizeStr.substring(0, pos)),
|
||||
Integer.parseInt(sizeStr.substring(pos + 1)));
|
||||
final int width = size.x;
|
||||
final int height = size.y;
|
||||
if (displayContent.mBaseDisplayWidth != width
|
||||
|| displayContent.mBaseDisplayHeight != height) {
|
||||
ProtoLog.i(WM_ERROR, "FORCED DISPLAY SIZE: %dx%d", width, height);
|
||||
|
||||
@@ -41,8 +41,9 @@ import static org.mockito.Matchers.eq;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.ContentResolver;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Surface;
|
||||
@@ -439,6 +440,7 @@ public class DisplayWindowSettingsTests extends WindowTestsBase {
|
||||
public void testDisplayWindowSettingsAppliedOnDisplayReady() {
|
||||
// Set forced densities for two displays in DisplayWindowSettings
|
||||
final DisplayContent dc = createMockSimulatedDisplay();
|
||||
final ContentResolver contentResolver = useFakeSettingsProvider();
|
||||
mDisplayWindowSettings.setForcedDensity(mPrimaryDisplay.getDisplayInfo(), 123,
|
||||
0 /* userId */);
|
||||
mDisplayWindowSettings.setForcedDensity(dc.getDisplayInfo(), 456, 0 /* userId */);
|
||||
@@ -450,15 +452,21 @@ public class DisplayWindowSettingsTests extends WindowTestsBase {
|
||||
assertFalse(mPrimaryDisplay.mWaitingForConfig);
|
||||
assertFalse(dc.mWaitingForConfig);
|
||||
|
||||
final int invalidW = Integer.MAX_VALUE;
|
||||
final int invalidH = Integer.MAX_VALUE;
|
||||
// Verify that applyForcedPropertiesForDefaultDisplay() handles invalid size request.
|
||||
Settings.Global.putString(contentResolver, Settings.Global.DISPLAY_SIZE_FORCED,
|
||||
invalidW + "," + invalidH);
|
||||
// Notify WM that the displays are ready and check that they are reconfigured.
|
||||
mWm.displayReady();
|
||||
waitUntilHandlersIdle();
|
||||
|
||||
final Configuration config = new Configuration();
|
||||
mPrimaryDisplay.computeScreenConfiguration(config);
|
||||
assertEquals(123, config.densityDpi);
|
||||
dc.computeScreenConfiguration(config);
|
||||
assertEquals(456, config.densityDpi);
|
||||
// Density is set successfully.
|
||||
assertEquals(123, mPrimaryDisplay.getConfiguration().densityDpi);
|
||||
assertEquals(456, dc.getConfiguration().densityDpi);
|
||||
// Invalid size won't be applied.
|
||||
assertNotEquals(invalidW, mPrimaryDisplay.mBaseDisplayWidth);
|
||||
assertNotEquals(invalidH, mPrimaryDisplay.mBaseDisplayHeight);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -66,6 +66,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
@@ -81,6 +82,7 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.voice.IVoiceInteractionSession;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Display;
|
||||
@@ -109,6 +111,7 @@ import android.window.TransitionRequestInfo;
|
||||
|
||||
import com.android.internal.policy.AttributeCache;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.internal.util.test.FakeSettingsProvider;
|
||||
import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -146,6 +149,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
||||
WindowManagerService mWm;
|
||||
private final IWindow mIWindow = new TestIWindow();
|
||||
private Session mMockSession;
|
||||
private boolean mUseFakeSettingsProvider;
|
||||
|
||||
DisplayInfo mDisplayInfo = new DisplayInfo();
|
||||
DisplayContent mDefaultDisplay;
|
||||
@@ -272,16 +276,9 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
// Revert back to device overrides.
|
||||
mAtm.mWindowManager.mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
|
||||
mAtm.mWindowManager.mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
|
||||
mAtm.mWindowManager.mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier();
|
||||
mAtm.mWindowManager.mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled();
|
||||
mAtm.mWindowManager.mLetterboxConfiguration.resetIsVerticalReachabilityEnabled();
|
||||
mAtm.mWindowManager.mLetterboxConfiguration
|
||||
.resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
|
||||
mAtm.mWindowManager.mLetterboxConfiguration
|
||||
.resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox();
|
||||
if (mUseFakeSettingsProvider) {
|
||||
FakeSettingsProvider.clearSettingsProvider();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,6 +425,17 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
||||
// Called before display is created.
|
||||
}
|
||||
|
||||
/** Avoid writing values to real Settings. */
|
||||
ContentResolver useFakeSettingsProvider() {
|
||||
mUseFakeSettingsProvider = true;
|
||||
FakeSettingsProvider.clearSettingsProvider();
|
||||
final FakeSettingsProvider provider = new FakeSettingsProvider();
|
||||
// SystemServicesTestRule#setUpSystemCore has called spyOn for the ContentResolver.
|
||||
final ContentResolver resolver = mContext.getContentResolver();
|
||||
doReturn(provider.getIContentProvider()).when(resolver).acquireProvider(Settings.AUTHORITY);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
private WindowState createCommonWindow(WindowState parent, int type, String name) {
|
||||
final WindowState win = createWindow(parent, type, name);
|
||||
// Prevent common windows from been IME targets.
|
||||
|
||||
Reference in New Issue
Block a user