summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Nikolaienkov <sergeynv@google.com>2021-02-15 09:42:20 +0000
committerSergey Nikolaienkov <sergeynv@google.com>2021-03-09 06:08:44 +0000
commit70c9d936d9599e328ea43d47049a70737b122191 (patch)
tree198e3daa9463fda7700cb29a56b2ef020fa3b960
parent944e6eb7fc659b1ec8d5f4e1fce2a4b34aae2aac (diff)
Cap resolution for pre-S apps on TV at 1080p
On Android TV applications that target pre-S SDK are not expecting to receive a Window larger than 1080p. To avoid this from happening this CL overrides compatibility scaling for applications that target a pre-S SDK on ATV devices that have larger than 1080p screen, so that the applications would still need to draw to a 1080p Surface. Bug: 157629738 Test: atest CtsWindowManagerDeviceTestCases:TvMaxWindowSizeTests Change-Id: I2b240bb5fcae6b165fd17c982cc29c49de348dbf
-rw-r--r--core/java/android/content/res/CompatibilityInfo.java1
-rw-r--r--services/core/java/com/android/server/wm/CompatModePackages.java97
-rw-r--r--tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java24
3 files changed, 68 insertions, 54 deletions
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index bbde8b103ef3..d7225ccd9ca6 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -110,6 +110,7 @@ public class CompatibilityInfo implements Parcelable {
public final float applicationInvertedScale;
@UnsupportedAppUsage
+ @Deprecated
public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw,
boolean forceCompat) {
this(appInfo, screenLayout, sw, forceCompat, 1f);
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index a725dd34fbf6..28a509bc9276 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -27,16 +27,20 @@ import android.app.AppGlobals;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled;
+import android.compat.annotation.EnabledSince;
+import android.compat.annotation.Overridable;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
+import android.os.Build;
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.DisplayMetrics;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TypedXmlPullParser;
@@ -119,6 +123,17 @@ public final class CompatModePackages {
@Disabled
private static final long DOWNSCALE_50 = 176926741L;
+ /**
+ * On Android TV applications that target pre-S are not expecting to receive a Window larger
+ * than 1080p, so if needed we are downscaling their Windows to 1080p.
+ * However, applications that target S and greater release version are expected to be able to
+ * handle any Window size, so we should not downscale their Windows.
+ */
+ @ChangeId
+ @Overridable
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
+ private static final long DO_NOT_DOWNSCALE_TO_1080P_ON_TV = 157629738L; // This is a Bug ID.
+
private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>();
private static final int MSG_WRITE = 300;
@@ -138,7 +153,7 @@ public final class CompatModePackages {
break;
}
}
- };
+ }
public CompatModePackages(ActivityTaskManagerService service, File systemDir, Handler handler) {
mService = service;
@@ -247,55 +262,53 @@ public final class CompatModePackages {
mHandler.sendMessageDelayed(msg, 10000);
}
+ public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
+ final boolean forceCompat = getPackageCompatModeEnabledLocked(ai);
+ final float compatScale = getCompatScale(ai.packageName, ai.uid);
+ final Configuration config = mService.getGlobalConfiguration();
+ return new CompatibilityInfo(ai, config.screenLayout, config.smallestScreenWidthDp,
+ forceCompat, compatScale);
+ }
+
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;
+ final UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
+ if (CompatChanges.isChangeEnabled(DOWNSCALED, packageName, userHandle)) {
+ if (CompatChanges.isChangeEnabled(DOWNSCALE_87_5, packageName, userHandle)) {
+ return 8f / 7f; // 1.14285714286
+ }
+ if (CompatChanges.isChangeEnabled(DOWNSCALE_75, packageName, userHandle)) {
+ return 4f / 3f; // 1.333333333
+ }
+ if (CompatChanges.isChangeEnabled(DOWNSCALE_62_5, packageName, userHandle)) {
+ return /* 1 / 0.625 */ 1.6f;
+ }
+ if (CompatChanges.isChangeEnabled(DOWNSCALE_50, packageName, userHandle)) {
+ return /* 1 / 0.5 */ 2f;
+ }
}
- if (CompatChanges.isChangeEnabled(
- DOWNSCALE_50, packageName, UserHandle.getUserHandleForUid(uid))) {
- return 2f;
+
+ if (mService.mHasLeanbackFeature) {
+ final Configuration config = mService.getGlobalConfiguration();
+ final float density = config.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
+ final int smallestScreenWidthPx = (int) (config.smallestScreenWidthDp * density + .5f);
+ if (smallestScreenWidthPx > 1080 && !CompatChanges.isChangeEnabled(
+ DO_NOT_DOWNSCALE_TO_1080P_ON_TV, packageName, userHandle)) {
+ return smallestScreenWidthPx / 1080f;
+ }
}
- 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, requestedScale);
- //Slog.i(TAG, "*********** COMPAT FOR PKG " + ai.packageName + ": " + ci);
- return ci;
+ return 1f;
}
public int computeCompatModeLocked(ApplicationInfo ai) {
- final boolean enabled = (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0;
- final Configuration globalConfig = mService.getGlobalConfiguration();
- final CompatibilityInfo info = new CompatibilityInfo(ai, globalConfig.screenLayout,
- globalConfig.smallestScreenWidthDp, enabled);
+ final CompatibilityInfo info = compatibilityInfoForPackageLocked(ai);
if (info.alwaysSupportsScreen()) {
return ActivityManager.COMPAT_MODE_NEVER;
}
if (info.neverSupportsScreen()) {
return ActivityManager.COMPAT_MODE_ALWAYS;
}
- return enabled ? ActivityManager.COMPAT_MODE_ENABLED
+ return getPackageCompatModeEnabledLocked(ai) ? ActivityManager.COMPAT_MODE_ENABLED
: ActivityManager.COMPAT_MODE_DISABLED;
}
@@ -307,6 +320,10 @@ public final class CompatModePackages {
setPackageFlagLocked(packageName, COMPAT_FLAG_DONT_ASK, ask);
}
+ private boolean getPackageCompatModeEnabledLocked(ApplicationInfo ai) {
+ return (getPackageFlags(ai.packageName) & COMPAT_FLAG_ENABLED) != 0;
+ }
+
private void setPackageFlagLocked(String packageName, int flag, boolean set) {
final int curFlags = getPackageFlags(packageName);
final int newFlags = set ? (curFlags & ~flag) : (curFlags | flag);
@@ -443,9 +460,6 @@ public final class CompatModePackages {
out.startTag(null, "compat-packages");
final IPackageManager pm = AppGlobals.getPackageManager();
- final Configuration globalConfig = mService.getGlobalConfiguration();
- final int screenLayout = globalConfig.screenLayout;
- final int smallestScreenWidthDp = globalConfig.smallestScreenWidthDp;
final Iterator<Map.Entry<String, Integer>> it = pkgs.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Integer> entry = it.next();
@@ -462,8 +476,7 @@ public final class CompatModePackages {
if (ai == null) {
continue;
}
- CompatibilityInfo info = new CompatibilityInfo(ai, screenLayout,
- smallestScreenWidthDp, false);
+ final CompatibilityInfo info = compatibilityInfoForPackageLocked(ai);
if (info.alwaysSupportsScreen()) {
continue;
}
diff --git a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
index 01c1c70f3f2a..cf501aed1dd5 100644
--- a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
+++ b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
@@ -19,23 +19,23 @@ package com.google.android.test.dpi;
import android.app.Activity;
import android.app.ActivityThread;
import android.app.Application;
-import android.os.Bundle;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.ScrollView;
-import android.view.LayoutInflater;
-import android.view.View;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
public class DpiTestActivity extends Activity {
public DpiTestActivity() {
@@ -64,7 +64,7 @@ public class DpiTestActivity extends Activity {
| ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
app.getResources().setCompatibilityInfo(new CompatibilityInfo(ai,
getResources().getConfiguration().screenLayout,
- getResources().getConfiguration().smallestScreenWidthDp, false));
+ getResources().getConfiguration().smallestScreenWidthDp, false, 1f));
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("ouch", e);