Merge "Implement per-app window resizing override." into sc-dev
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
@@ -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) {
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
@@ -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.
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1682,7 +1692,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
|
||||
void prelayout() {
|
||||
if (inSizeCompatMode()) {
|
||||
mGlobalScale = mToken.getSizeCompatScale();
|
||||
if (mOverrideScale != 1f) {
|
||||
mGlobalScale = mToken.hasSizeCompatBounds()
|
||||
? mToken.getSizeCompatScale() * mOverrideScale
|
||||
: mOverrideScale;
|
||||
} else {
|
||||
mGlobalScale = mToken.getSizeCompatScale();
|
||||
}
|
||||
mInvGlobalScale = 1 / mGlobalScale;
|
||||
} else {
|
||||
mGlobalScale = mInvGlobalScale = 1;
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user