Merge "Cap resolution for pre-S apps on TV at 1080p" into sc-dev

This commit is contained in:
Sergey Nikolaienkov
2021-03-09 09:25:29 +00:00
committed by Android (Google) Code Review
3 changed files with 68 additions and 54 deletions

View File

@@ -110,6 +110,7 @@ public class CompatibilityInfo implements Parcelable {
public final float applicationInvertedScale; public final float applicationInvertedScale;
@UnsupportedAppUsage @UnsupportedAppUsage
@Deprecated
public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw, public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw,
boolean forceCompat) { boolean forceCompat) {
this(appInfo, screenLayout, sw, forceCompat, 1f); this(appInfo, screenLayout, sw, forceCompat, 1f);

View File

@@ -27,16 +27,20 @@ import android.app.AppGlobals;
import android.app.compat.CompatChanges; import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId; import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled; import android.compat.annotation.Disabled;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.Overridable;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager; import android.content.pm.IPackageManager;
import android.content.res.CompatibilityInfo; import android.content.res.CompatibilityInfo;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.AtomicFile; import android.util.AtomicFile;
import android.util.DisplayMetrics;
import android.util.Slog; import android.util.Slog;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.TypedXmlPullParser; import android.util.TypedXmlPullParser;
@@ -119,6 +123,17 @@ public final class CompatModePackages {
@Disabled @Disabled
private static final long DOWNSCALE_50 = 176926741L; 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 final HashMap<String, Integer> mPackages = new HashMap<String, Integer>();
private static final int MSG_WRITE = 300; private static final int MSG_WRITE = 300;
@@ -138,7 +153,7 @@ public final class CompatModePackages {
break; break;
} }
} }
}; }
public CompatModePackages(ActivityTaskManagerService service, File systemDir, Handler handler) { public CompatModePackages(ActivityTaskManagerService service, File systemDir, Handler handler) {
mService = service; mService = service;
@@ -247,55 +262,53 @@ public final class CompatModePackages {
mHandler.sendMessageDelayed(msg, 10000); 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) { float getCompatScale(String packageName, int uid) {
if (!CompatChanges.isChangeEnabled( final UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
DOWNSCALED, packageName, UserHandle.getUserHandleForUid(uid))) { if (CompatChanges.isChangeEnabled(DOWNSCALED, packageName, userHandle)) {
return 1f; 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_87_5, packageName, UserHandle.getUserHandleForUid(uid))) { if (mService.mHasLeanbackFeature) {
// 8/7 == (1 / 0.875) ~= 1.14285714286 final Configuration config = mService.getGlobalConfiguration();
return 8f / 7f; final float density = config.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
} final int smallestScreenWidthPx = (int) (config.smallestScreenWidthDp * density + .5f);
if (CompatChanges.isChangeEnabled( if (smallestScreenWidthPx > 1080 && !CompatChanges.isChangeEnabled(
DOWNSCALE_75, packageName, UserHandle.getUserHandleForUid(uid))) { DO_NOT_DOWNSCALE_TO_1080P_ON_TV, packageName, userHandle)) {
// 4/3 == (1 / 0.75) ~= 1.333333333 return smallestScreenWidthPx / 1080f;
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; 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;
}
public int computeCompatModeLocked(ApplicationInfo ai) { public int computeCompatModeLocked(ApplicationInfo ai) {
final boolean enabled = (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0; final CompatibilityInfo info = compatibilityInfoForPackageLocked(ai);
final Configuration globalConfig = mService.getGlobalConfiguration();
final CompatibilityInfo info = new CompatibilityInfo(ai, globalConfig.screenLayout,
globalConfig.smallestScreenWidthDp, enabled);
if (info.alwaysSupportsScreen()) { if (info.alwaysSupportsScreen()) {
return ActivityManager.COMPAT_MODE_NEVER; return ActivityManager.COMPAT_MODE_NEVER;
} }
if (info.neverSupportsScreen()) { if (info.neverSupportsScreen()) {
return ActivityManager.COMPAT_MODE_ALWAYS; return ActivityManager.COMPAT_MODE_ALWAYS;
} }
return enabled ? ActivityManager.COMPAT_MODE_ENABLED return getPackageCompatModeEnabledLocked(ai) ? ActivityManager.COMPAT_MODE_ENABLED
: ActivityManager.COMPAT_MODE_DISABLED; : ActivityManager.COMPAT_MODE_DISABLED;
} }
@@ -307,6 +320,10 @@ public final class CompatModePackages {
setPackageFlagLocked(packageName, COMPAT_FLAG_DONT_ASK, ask); 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) { private void setPackageFlagLocked(String packageName, int flag, boolean set) {
final int curFlags = getPackageFlags(packageName); final int curFlags = getPackageFlags(packageName);
final int newFlags = set ? (curFlags & ~flag) : (curFlags | flag); final int newFlags = set ? (curFlags & ~flag) : (curFlags | flag);
@@ -443,9 +460,6 @@ public final class CompatModePackages {
out.startTag(null, "compat-packages"); out.startTag(null, "compat-packages");
final IPackageManager pm = AppGlobals.getPackageManager(); 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(); final Iterator<Map.Entry<String, Integer>> it = pkgs.entrySet().iterator();
while (it.hasNext()) { while (it.hasNext()) {
Map.Entry<String, Integer> entry = it.next(); Map.Entry<String, Integer> entry = it.next();
@@ -462,8 +476,7 @@ public final class CompatModePackages {
if (ai == null) { if (ai == null) {
continue; continue;
} }
CompatibilityInfo info = new CompatibilityInfo(ai, screenLayout, final CompatibilityInfo info = compatibilityInfoForPackageLocked(ai);
smallestScreenWidthDp, false);
if (info.alwaysSupportsScreen()) { if (info.alwaysSupportsScreen()) {
continue; continue;
} }

View File

@@ -19,23 +19,23 @@ package com.google.android.test.dpi;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityThread; import android.app.ActivityThread;
import android.app.Application; 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.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo; 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.DisplayMetrics;
import android.util.Log; 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 class DpiTestActivity extends Activity {
public DpiTestActivity() { public DpiTestActivity() {
@@ -64,7 +64,7 @@ public class DpiTestActivity extends Activity {
| ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES; | ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
app.getResources().setCompatibilityInfo(new CompatibilityInfo(ai, app.getResources().setCompatibilityInfo(new CompatibilityInfo(ai,
getResources().getConfiguration().screenLayout, getResources().getConfiguration().screenLayout,
getResources().getConfiguration().smallestScreenWidthDp, false)); getResources().getConfiguration().smallestScreenWidthDp, false, 1f));
} }
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("ouch", e); throw new RuntimeException("ouch", e);