diff options
4 files changed, 56 insertions, 26 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index f478e9bee18a..8bfa4269af1c 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -2267,6 +2267,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); @@ -3087,13 +3093,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); @@ -3108,6 +3110,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; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8822193ab522..40b8274d4e51 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -5780,10 +5780,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); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java index fb4f2ee77521..1cec0ef3d5cf 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java @@ -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 diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index f85cdf0b5035..07244a4f2478 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -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.  |