From 4fe90c0fe92f97a2ebce90832eb316c76a4b2f0e Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 11 Feb 2021 00:57:34 +0800 Subject: [PATCH] Fix screen size with compatibility override scale The values in dp shouldn't be changed because the density is already scaled. Also add unit tests to ensure that the override scale from CompatModePackages applies to window and surface. Bug: 168419799 Test: atest DisplayContentTeasts#testCompatOverrideScale Change-Id: I4b99b123d4beb33cc3d97eb07e506d8a60fcc5e3 --- .../content/res/CompatibilityInfo.java | 7 +-- .../server/wm/DisplayContentTests.java | 2 +- .../android/server/wm/WindowStateTests.java | 43 +++++++++++++++++++ .../android/server/wm/WindowTestsBase.java | 1 + 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index abf694f9742ef..bbde8b103ef39 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -252,9 +252,10 @@ public class CompatibilityInfo implements Parcelable { } if (overrideScale != 1.0f) { - applicationDensity = DisplayMetrics.DENSITY_DEFAULT; applicationScale = overrideScale; applicationInvertedScale = 1.0f / overrideScale; + applicationDensity = (int) ((DisplayMetrics.DENSITY_DEVICE_STABLE + * applicationInvertedScale) + .5f); compatFlags |= HAS_OVERRIDE_SCALING; } else if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { applicationDensity = DisplayMetrics.DENSITY_DEVICE; @@ -519,10 +520,6 @@ public class CompatibilityInfo implements Parcelable { if (isScalingRequired()) { float invertedRatio = applicationInvertedScale; inoutConfig.densityDpi = (int)((inoutConfig.densityDpi * invertedRatio) + .5f); - inoutConfig.screenWidthDp = (int) ((inoutConfig.screenWidthDp * invertedRatio) + .5f); - inoutConfig.screenHeightDp = (int) ((inoutConfig.screenHeightDp * invertedRatio) + .5f); - inoutConfig.smallestScreenWidthDp = - (int) ((inoutConfig.smallestScreenWidthDp * invertedRatio) + .5f); inoutConfig.windowConfiguration.getMaxBounds().scale(invertedRatio); inoutConfig.windowConfiguration.getBounds().scale(invertedRatio); final Rect appBounds = inoutConfig.windowConfiguration.getAppBounds(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index b4fd3024a6348..781cfec77f081 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -1834,7 +1834,7 @@ public class DisplayContentTests extends WindowTestsBase { mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /* updateInputWindows */); } - private void performLayout(DisplayContent dc) { + static void performLayout(DisplayContent dc) { dc.setLayoutNeeded(); dc.performLayout(true /* initial */, false /* updateImeWindows */); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 3231f8b6551ab..896969548af3e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -67,11 +67,14 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.when; +import android.content.res.CompatibilityInfo; +import android.content.res.Configuration; import android.graphics.Matrix; import android.graphics.Rect; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; +import android.view.Gravity; import android.view.InputWindowHandle; import android.view.InsetsState; import android.view.SurfaceControl; @@ -559,6 +562,46 @@ public class WindowStateTests extends WindowTestsBase { assertTrue(window.isVisibleByPolicy()); } + @Test + public void testCompatOverrideScale() { + final float overrideScale = 2; // 0.5x on client side. + final CompatModePackages cmp = mWm.mAtmService.mCompatModePackages; + spyOn(cmp); + doReturn(overrideScale).when(cmp).getCompatScale(anyString(), anyInt()); + final WindowState w = createWindow(null, TYPE_APPLICATION_OVERLAY, "win"); + makeWindowVisible(w); + w.setRequestedSize(100, 200); + w.mAttrs.width = w.mAttrs.height = WindowManager.LayoutParams.WRAP_CONTENT; + w.mAttrs.gravity = Gravity.TOP | Gravity.LEFT; + DisplayContentTests.performLayout(mDisplayContent); + + // Frame on screen = 100x200. Compat frame on client = 50x100. + final Rect unscaledCompatFrame = new Rect(w.getWindowFrames().mCompatFrame); + unscaledCompatFrame.scale(overrideScale); + assertEquals(w.getWindowFrames().mFrame, unscaledCompatFrame); + + // Surface should apply the scale. + w.prepareSurfaces(); + verify(w.getPendingTransaction()).setMatrix(w.getSurfaceControl(), + overrideScale, 0, 0, overrideScale); + + // According to "dp * density / 160 = px", density is scaled and the size in dp is the same. + final CompatibilityInfo compatInfo = cmp.compatibilityInfoForPackageLocked( + mContext.getApplicationInfo()); + final Configuration winConfig = w.getConfiguration(); + final Configuration clientConfig = new Configuration(w.getConfiguration()); + compatInfo.applyToConfiguration(clientConfig.densityDpi, clientConfig); + + assertEquals(winConfig.screenWidthDp, clientConfig.screenWidthDp); + assertEquals(winConfig.screenHeightDp, clientConfig.screenHeightDp); + assertEquals(winConfig.smallestScreenWidthDp, clientConfig.smallestScreenWidthDp); + assertEquals(winConfig.densityDpi, (int) (clientConfig.densityDpi * overrideScale)); + + final Rect unscaledClientBounds = new Rect(clientConfig.windowConfiguration.getBounds()); + unscaledClientBounds.scale(overrideScale); + assertEquals(w.getWindowConfiguration().getBounds(), unscaledClientBounds); + } + @UseTestDisplay(addWindows = { W_ABOVE_ACTIVITY, W_NOTIFICATION_SHADE }) @Test public void testRequestDrawIfNeeded() { 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 eb6c6ed349de9..83b30a9747d74 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -337,6 +337,7 @@ class WindowTestsBase extends SystemServiceTestsBase { final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type); attrs.setTitle(name); + attrs.packageName = "test"; final WindowState w = new WindowState(service, session, iWindow, token, parent, OP_NONE, attrs, VISIBLE, ownerId, userId,