Loading core/java/android/content/res/CompatibilityInfo.java +28 −3 Original line number Diff line number Diff line Loading @@ -88,6 +88,11 @@ public class CompatibilityInfo implements Parcelable { */ private static final int NEEDS_COMPAT_RES = 16; /** * Set if the application needs to be forcibly downscaled */ private static final int HAS_OVERRIDE_SCALING = 32; /** * The effective screen density we have selected for this application. */ Loading @@ -107,6 +112,11 @@ public class CompatibilityInfo implements Parcelable { @UnsupportedAppUsage public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw, boolean forceCompat) { this(appInfo, screenLayout, sw, forceCompat, 1f); } public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw, boolean forceCompat, float overrideScale) { int compatFlags = 0; if (appInfo.targetSdkVersion < VERSION_CODES.O) { Loading Loading @@ -241,7 +251,12 @@ public class CompatibilityInfo implements Parcelable { compatFlags |= NEVER_NEEDS_COMPAT; } if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { if (overrideScale != 1.0f) { applicationDensity = DisplayMetrics.DENSITY_DEFAULT; applicationScale = overrideScale; applicationInvertedScale = 1.0f / overrideScale; compatFlags |= HAS_OVERRIDE_SCALING; } else if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { applicationDensity = DisplayMetrics.DENSITY_DEVICE; applicationScale = 1.0f; applicationInvertedScale = 1.0f; Loading Loading @@ -277,7 +292,7 @@ public class CompatibilityInfo implements Parcelable { */ @UnsupportedAppUsage public boolean isScalingRequired() { return (mCompatibilityFlags&SCALING_REQUIRED) != 0; return (mCompatibilityFlags & (SCALING_REQUIRED | HAS_OVERRIDE_SCALING)) != 0; } @UnsupportedAppUsage Loading @@ -303,7 +318,7 @@ public class CompatibilityInfo implements Parcelable { */ @UnsupportedAppUsage public Translator getTranslator() { return isScalingRequired() ? new Translator() : null; return (mCompatibilityFlags & SCALING_REQUIRED) != 0 ? new Translator() : null; } /** Loading Loading @@ -504,6 +519,16 @@ 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(); if (appBounds != null) { appBounds.scale(invertedRatio); } } } Loading services/core/java/com/android/server/wm/CompatModePackages.java +85 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.res.CompatibilityInfo; Loading @@ -32,6 +35,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.UserHandle; import android.util.AtomicFile; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -63,6 +67,58 @@ public final class CompatModePackages { // Compatibility state: compatibility mode is enabled. private static final int COMPAT_FLAG_ENABLED = 1<<1; /** * CompatModePackages#DOWNSCALED is the gatekeeper of all per-app buffer downscaling * changes. Disabling this change will prevent the following scaling factors from working: * CompatModePackages#DOWNSCALE_87_5 * CompatModePackages#DOWNSCALE_75 * CompatModePackages#DOWNSCALE_62_5 * CompatModePackages#DOWNSCALE_50 * * If CompatModePackages#DOWNSCALED is enabled for an app package, then the app will be forcibly * resized to the highest enabled scaling factor e.g. 87.5% if both 87.5% and 75% were * enabled. */ @ChangeId @Disabled private static final long DOWNSCALED = 168419799L; /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_87_5 for a package will force the app to assume it's * running on a display with 87.5% the vertical and horizontal resolution of the real display. */ @ChangeId @Disabled private static final long DOWNSCALE_87_5 = 176926753L; /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_75 for a package will force the app to assume it's * running on a display with 75% the vertical and horizontal resolution of the real display. */ @ChangeId @Disabled private static final long DOWNSCALE_75 = 176926829L; /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_62_5 for a package will force the app to assume it's * running on a display with 62.5% the vertical and horizontal resolution of the real display. */ @ChangeId @Disabled private static final long DOWNSCALE_62_5 = 176926771L; /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_50 for a package will force the app to assume it's * running on a display with 50% vertical and horizontal resolution of the real display. */ @ChangeId @Disabled private static final long DOWNSCALE_50 = 176926741L; private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>(); private static final int MSG_WRITE = 300; Loading Loading @@ -191,11 +247,39 @@ public final class CompatModePackages { mHandler.sendMessageDelayed(msg, 10000); } float getCompatScale(String packageName, int uid) { if (!CompatChanges.isChangeEnabled( DOWNSCALED, packageName, UserHandle.getUserHandleForUid(uid))) { return 1f; } if (CompatChanges.isChangeEnabled( DOWNSCALE_87_5, packageName, UserHandle.getUserHandleForUid(uid))) { // 8/7 == (1 / 0.875) ~= 1.14285714286 return 8f / 7f; } if (CompatChanges.isChangeEnabled( DOWNSCALE_75, packageName, UserHandle.getUserHandleForUid(uid))) { // 4/3 == (1 / 0.75) ~= 1.333333333 return 4f / 3f; } if (CompatChanges.isChangeEnabled( DOWNSCALE_62_5, packageName, UserHandle.getUserHandleForUid(uid))) { // (1 / 0.625) == 1.6 return 1.6f; } if (CompatChanges.isChangeEnabled( DOWNSCALE_50, packageName, UserHandle.getUserHandleForUid(uid))) { return 2f; } return 1f; } public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { final Configuration globalConfig = mService.getGlobalConfiguration(); final float requestedScale = getCompatScale(ai.packageName, ai.uid); CompatibilityInfo ci = new CompatibilityInfo(ai, globalConfig.screenLayout, globalConfig.smallestScreenWidthDp, (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0); (getPackageFlags(ai.packageName) & COMPAT_FLAG_ENABLED) != 0, requestedScale); //Slog.i(TAG, "*********** COMPAT FOR PKG " + ai.packageName + ": " + ci); return ci; } Loading services/core/java/com/android/server/wm/WindowState.java +19 −4 Original line number Diff line number Diff line Loading @@ -441,6 +441,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP float mGlobalScale=1; float mLastGlobalScale=1; float mInvGlobalScale=1; float mOverrideScale = 1; float mHScale=1, mVScale=1; float mLastHScale=1, mLastVScale=1; final Matrix mTmpMatrix = new Matrix(); Loading Loading @@ -1014,6 +1015,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mLastRequestedWidth = 0; mLastRequestedHeight = 0; mLayer = 0; mOverrideScale = mWmService.mAtmService.mCompatModePackages.getCompatScale( mAttrs.packageName, s.mUid); // Make sure we initial all fields before adding to parentWindow, to prevent exception // during onDisplayChanged. Loading Loading @@ -1046,8 +1049,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mSession.windowAddedLocked(mAttrs.packageName); } /** * @return {@code true} if the application runs in size compatibility mode or has an app level * scaling override set. * @see CompatModePackages#getCompatScale * @see android.content.res.CompatibilityInfo#supportsScreen * @see ActivityRecord#inSizeCompatMode() */ boolean inSizeCompatMode() { return inSizeCompatMode(mAttrs, mActivityRecord); return mOverrideScale != 1f || inSizeCompatMode(mAttrs, mActivityRecord); } /** Loading Loading @@ -1682,7 +1692,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void prelayout() { if (inSizeCompatMode()) { if (mOverrideScale != 1f) { mGlobalScale = mToken.hasSizeCompatBounds() ? mToken.getSizeCompatScale() * mOverrideScale : mOverrideScale; } else { mGlobalScale = mToken.getSizeCompatScale(); } mInvGlobalScale = 1 / mGlobalScale; } else { mGlobalScale = mInvGlobalScale = 1; Loading Loading @@ -2640,8 +2656,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // scaling but the existing logic doesn't expect that. The result is that the already- // scaled region ends up getting sent to surfaceflinger which then applies the scale // (again). Until this is resolved, apply an inverse-scale here. if (mActivityRecord != null && mActivityRecord.hasSizeCompatBounds() && mGlobalScale != 1.f) { if (mInvGlobalScale != 1.f) { region.scale(mInvGlobalScale); } Loading Loading
core/java/android/content/res/CompatibilityInfo.java +28 −3 Original line number Diff line number Diff line Loading @@ -88,6 +88,11 @@ public class CompatibilityInfo implements Parcelable { */ private static final int NEEDS_COMPAT_RES = 16; /** * Set if the application needs to be forcibly downscaled */ private static final int HAS_OVERRIDE_SCALING = 32; /** * The effective screen density we have selected for this application. */ Loading @@ -107,6 +112,11 @@ public class CompatibilityInfo implements Parcelable { @UnsupportedAppUsage public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw, boolean forceCompat) { this(appInfo, screenLayout, sw, forceCompat, 1f); } public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw, boolean forceCompat, float overrideScale) { int compatFlags = 0; if (appInfo.targetSdkVersion < VERSION_CODES.O) { Loading Loading @@ -241,7 +251,12 @@ public class CompatibilityInfo implements Parcelable { compatFlags |= NEVER_NEEDS_COMPAT; } if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { if (overrideScale != 1.0f) { applicationDensity = DisplayMetrics.DENSITY_DEFAULT; applicationScale = overrideScale; applicationInvertedScale = 1.0f / overrideScale; compatFlags |= HAS_OVERRIDE_SCALING; } else if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { applicationDensity = DisplayMetrics.DENSITY_DEVICE; applicationScale = 1.0f; applicationInvertedScale = 1.0f; Loading Loading @@ -277,7 +292,7 @@ public class CompatibilityInfo implements Parcelable { */ @UnsupportedAppUsage public boolean isScalingRequired() { return (mCompatibilityFlags&SCALING_REQUIRED) != 0; return (mCompatibilityFlags & (SCALING_REQUIRED | HAS_OVERRIDE_SCALING)) != 0; } @UnsupportedAppUsage Loading @@ -303,7 +318,7 @@ public class CompatibilityInfo implements Parcelable { */ @UnsupportedAppUsage public Translator getTranslator() { return isScalingRequired() ? new Translator() : null; return (mCompatibilityFlags & SCALING_REQUIRED) != 0 ? new Translator() : null; } /** Loading Loading @@ -504,6 +519,16 @@ 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(); if (appBounds != null) { appBounds.scale(invertedRatio); } } } Loading
services/core/java/com/android/server/wm/CompatModePackages.java +85 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.compat.CompatChanges; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.res.CompatibilityInfo; Loading @@ -32,6 +35,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.UserHandle; import android.util.AtomicFile; import android.util.Slog; import android.util.SparseArray; Loading Loading @@ -63,6 +67,58 @@ public final class CompatModePackages { // Compatibility state: compatibility mode is enabled. private static final int COMPAT_FLAG_ENABLED = 1<<1; /** * CompatModePackages#DOWNSCALED is the gatekeeper of all per-app buffer downscaling * changes. Disabling this change will prevent the following scaling factors from working: * CompatModePackages#DOWNSCALE_87_5 * CompatModePackages#DOWNSCALE_75 * CompatModePackages#DOWNSCALE_62_5 * CompatModePackages#DOWNSCALE_50 * * If CompatModePackages#DOWNSCALED is enabled for an app package, then the app will be forcibly * resized to the highest enabled scaling factor e.g. 87.5% if both 87.5% and 75% were * enabled. */ @ChangeId @Disabled private static final long DOWNSCALED = 168419799L; /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_87_5 for a package will force the app to assume it's * running on a display with 87.5% the vertical and horizontal resolution of the real display. */ @ChangeId @Disabled private static final long DOWNSCALE_87_5 = 176926753L; /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_75 for a package will force the app to assume it's * running on a display with 75% the vertical and horizontal resolution of the real display. */ @ChangeId @Disabled private static final long DOWNSCALE_75 = 176926829L; /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_62_5 for a package will force the app to assume it's * running on a display with 62.5% the vertical and horizontal resolution of the real display. */ @ChangeId @Disabled private static final long DOWNSCALE_62_5 = 176926771L; /** * With CompatModePackages#DOWNSCALED enabled, subsequently enabling change-id * CompatModePackages#DOWNSCALE_50 for a package will force the app to assume it's * running on a display with 50% vertical and horizontal resolution of the real display. */ @ChangeId @Disabled private static final long DOWNSCALE_50 = 176926741L; private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>(); private static final int MSG_WRITE = 300; Loading Loading @@ -191,11 +247,39 @@ public final class CompatModePackages { mHandler.sendMessageDelayed(msg, 10000); } float getCompatScale(String packageName, int uid) { if (!CompatChanges.isChangeEnabled( DOWNSCALED, packageName, UserHandle.getUserHandleForUid(uid))) { return 1f; } if (CompatChanges.isChangeEnabled( DOWNSCALE_87_5, packageName, UserHandle.getUserHandleForUid(uid))) { // 8/7 == (1 / 0.875) ~= 1.14285714286 return 8f / 7f; } if (CompatChanges.isChangeEnabled( DOWNSCALE_75, packageName, UserHandle.getUserHandleForUid(uid))) { // 4/3 == (1 / 0.75) ~= 1.333333333 return 4f / 3f; } if (CompatChanges.isChangeEnabled( DOWNSCALE_62_5, packageName, UserHandle.getUserHandleForUid(uid))) { // (1 / 0.625) == 1.6 return 1.6f; } if (CompatChanges.isChangeEnabled( DOWNSCALE_50, packageName, UserHandle.getUserHandleForUid(uid))) { return 2f; } return 1f; } public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { final Configuration globalConfig = mService.getGlobalConfiguration(); final float requestedScale = getCompatScale(ai.packageName, ai.uid); CompatibilityInfo ci = new CompatibilityInfo(ai, globalConfig.screenLayout, globalConfig.smallestScreenWidthDp, (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0); (getPackageFlags(ai.packageName) & COMPAT_FLAG_ENABLED) != 0, requestedScale); //Slog.i(TAG, "*********** COMPAT FOR PKG " + ai.packageName + ": " + ci); return ci; } Loading
services/core/java/com/android/server/wm/WindowState.java +19 −4 Original line number Diff line number Diff line Loading @@ -441,6 +441,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP float mGlobalScale=1; float mLastGlobalScale=1; float mInvGlobalScale=1; float mOverrideScale = 1; float mHScale=1, mVScale=1; float mLastHScale=1, mLastVScale=1; final Matrix mTmpMatrix = new Matrix(); Loading Loading @@ -1014,6 +1015,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mLastRequestedWidth = 0; mLastRequestedHeight = 0; mLayer = 0; mOverrideScale = mWmService.mAtmService.mCompatModePackages.getCompatScale( mAttrs.packageName, s.mUid); // Make sure we initial all fields before adding to parentWindow, to prevent exception // during onDisplayChanged. Loading Loading @@ -1046,8 +1049,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mSession.windowAddedLocked(mAttrs.packageName); } /** * @return {@code true} if the application runs in size compatibility mode or has an app level * scaling override set. * @see CompatModePackages#getCompatScale * @see android.content.res.CompatibilityInfo#supportsScreen * @see ActivityRecord#inSizeCompatMode() */ boolean inSizeCompatMode() { return inSizeCompatMode(mAttrs, mActivityRecord); return mOverrideScale != 1f || inSizeCompatMode(mAttrs, mActivityRecord); } /** Loading Loading @@ -1682,7 +1692,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void prelayout() { if (inSizeCompatMode()) { if (mOverrideScale != 1f) { mGlobalScale = mToken.hasSizeCompatBounds() ? mToken.getSizeCompatScale() * mOverrideScale : mOverrideScale; } else { mGlobalScale = mToken.getSizeCompatScale(); } mInvGlobalScale = 1 / mGlobalScale; } else { mGlobalScale = mInvGlobalScale = 1; Loading Loading @@ -2640,8 +2656,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // scaling but the existing logic doesn't expect that. The result is that the already- // scaled region ends up getting sent to surfaceflinger which then applies the scale // (again). Until this is resolved, apply an inverse-scale here. if (mActivityRecord != null && mActivityRecord.hasSizeCompatBounds() && mGlobalScale != 1.f) { if (mInvGlobalScale != 1.f) { region.scale(mInvGlobalScale); } Loading