From a0530caa331d7bdeedda65190fbff3cf1ca43ded Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 29 Aug 2022 18:33:29 -0600 Subject: [PATCH] Apply override scale from entry points on client This provides a sandbox-like scaled environment on client side. - This prevents the metrics and config from being scaled multiple times because the entry points are only called from server side, there won't have reentrancy for applying the scale. - App's configuration callback method can get scaled config. - If override scale is enabled, the legacy compat mode will be skipped. That avoids mixing different approaches of scaling. - Legacy compat mode is to simulate a 320dp x 480dp screen size with density 160 (the surface scale and config scale are different). - Override scale is to downscale the app for better performance (the surface scale and config scale are the same). Bug: 238416387 Bug: 240335717 Test: atest ActivityThreadTest#testOverrideScale Test: atest CtsWindowManagerDeviceTestCases:CompatScaleTests Test: am compat enable DOWNSCALED $pkg am compat enable DOWNSCALE_50 $pkg Change-Id: I0ddf333996f229063511273f8aeb3867c9ba8bda --- core/java/android/app/ActivityThread.java | 8 ++ .../java/android/app/WindowConfiguration.java | 23 +++- .../ActivityConfigurationChangeItem.java | 2 + .../ActivityRelaunchItem.java | 2 + .../ConfigurationChangeItem.java | 2 + .../servertransaction/LaunchActivityItem.java | 3 + .../servertransaction/MoveToDisplayItem.java | 2 + .../content/res/CompatibilityInfo.java | 105 +++++++++++++++--- core/java/android/view/DisplayInfo.java | 6 +- core/java/android/view/ViewRootImpl.java | 2 + .../android/window/WindowTokenClient.java | 2 + .../app/activity/ActivityThreadTest.java | 97 ++++++++++++++-- .../android/server/wm/WindowStateTests.java | 4 +- 13 files changed, 222 insertions(+), 36 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index db7681640c678..16de734bf3f52 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1177,9 +1177,16 @@ public final class ActivityThread extends ClientTransactionHandler data.mSerializedSystemFontMap = serializedSystemFontMap; data.startRequestedElapsedTime = startRequestedElapsedTime; data.startRequestedUptime = startRequestedUptime; + updateCompatOverrideScale(compatInfo); + CompatibilityInfo.applyOverrideScaleIfNeeded(config); sendMessage(H.BIND_APPLICATION, data); } + private void updateCompatOverrideScale(CompatibilityInfo info) { + CompatibilityInfo.setOverrideInvertedScale( + info.hasOverrideScaling() ? info.applicationInvertedScale : 1f); + } + public final void runIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) { SomeArgs args = SomeArgs.obtain(); args.arg1 = entryPoint; @@ -1756,6 +1763,7 @@ public final class ActivityThread extends ClientTransactionHandler UpdateCompatibilityData ucd = new UpdateCompatibilityData(); ucd.pkg = pkg; ucd.info = info; + updateCompatOverrideScale(info); sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd); } diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java index 397c8e010bad3..39d77c49eea95 100644 --- a/core/java/android/app/WindowConfiguration.java +++ b/core/java/android/app/WindowConfiguration.java @@ -462,13 +462,30 @@ public class WindowConfiguration implements Parcelable, Comparable restoreConfig(activityThread, originalAppConfig)); + } + assertScreenScale(originalScale, app, originalAppConfig, originalAppMetrics); + } + + private static void assertScreenScale(float scale, Context context, + Configuration origConfig, DisplayMetrics origMetrics) { + final int expectedDpi = (int) (origConfig.densityDpi * scale + .5f); + final float expectedDensity = origMetrics.density * scale; + final int expectedWidthPixels = (int) (origMetrics.widthPixels * scale + .5f); + final int expectedHeightPixels = (int) (origMetrics.heightPixels * scale + .5f); + final Configuration expectedConfig = new Configuration(origConfig); + CompatibilityInfo.scaleConfiguration(scale, expectedConfig); + final Rect expectedBounds = expectedConfig.windowConfiguration.getBounds(); + final Rect expectedAppBounds = expectedConfig.windowConfiguration.getAppBounds(); + final Rect expectedMaxBounds = expectedConfig.windowConfiguration.getMaxBounds(); + + final Configuration currentConfig = context.getResources().getConfiguration(); + final DisplayMetrics currentMetrics = context.getResources().getDisplayMetrics(); + assertEquals(expectedDpi, currentConfig.densityDpi); + assertEquals(expectedDpi, currentMetrics.densityDpi); + assertEquals(expectedDensity, currentMetrics.density, 0.001f); + assertEquals(expectedWidthPixels, currentMetrics.widthPixels); + assertEquals(expectedHeightPixels, currentMetrics.heightPixels); + assertEquals(expectedBounds, currentConfig.windowConfiguration.getBounds()); + assertEquals(expectedAppBounds, currentConfig.windowConfiguration.getAppBounds()); + assertEquals(expectedMaxBounds, currentConfig.windowConfiguration.getMaxBounds()); + } + @Test public void testHandleActivityConfigurationChanged() { final TestActivity activity = mActivityTestRule.launchActivity(new Intent()); @@ -459,19 +540,17 @@ public class ActivityThreadTest { } finally { // Make sure to reset the process config to prevent side effects to other // tests. - Configuration activityThreadConfig = activityThread.getConfiguration(); - activityThreadConfig.seq = originalAppConfig.seq - 1; - - Configuration resourceManagerConfig = ResourcesManager.getInstance() - .getConfiguration(); - resourceManagerConfig.seq = originalAppConfig.seq - 1; - - activityThread.updatePendingConfiguration(originalAppConfig); - activityThread.handleConfigurationChanged(originalAppConfig); + restoreConfig(activityThread, originalAppConfig); } }); } + private static void restoreConfig(ActivityThread thread, Configuration originalConfig) { + thread.getConfiguration().seq = originalConfig.seq - 1; + ResourcesManager.getInstance().getConfiguration().seq = originalConfig.seq - 1; + thread.handleConfigurationChanged(originalConfig); + } + @Test public void testActivityOrientationChanged_DoesntOverrideVirtualDisplayOrientation() { final TestActivity activity = mActivityTestRule.launchActivity(new Intent()); 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 5c7b882f8dabd..e8c805450091b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -671,11 +671,9 @@ public class WindowStateTests extends WindowTestsBase { verify(t, never()).setMatrix(any(), anyInt(), anyInt(), anyInt(), anyInt()); // 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); + CompatibilityInfo.scaleConfiguration(w.mInvGlobalScale, clientConfig); assertEquals(winConfig.screenWidthDp, clientConfig.screenWidthDp); assertEquals(winConfig.screenHeightDp, clientConfig.screenHeightDp);