diff --git a/api/current.txt b/api/current.txt index 620aef4855f86..63bbad29cc0ab 100644 --- a/api/current.txt +++ b/api/current.txt @@ -940,6 +940,7 @@ package android { field public static final int menuCategory = 16843230; // 0x10101de field public static final int mimeType = 16842790; // 0x1010026 field public static final int min = 16844089; // 0x1010539 + field public static final int minAspectRatio = 16844193; // 0x10105a1 field public static final int minDate = 16843583; // 0x101033f field public static final int minEms = 16843098; // 0x101015a field public static final int minHeight = 16843072; // 0x1010140 diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 0a4f4eb8506ca..0edb36c5daff8 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -235,6 +235,15 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { */ public float maxAspectRatio; + /** + * Value indicating the minimum aspect ratio the activity supports. + *
+ * 0 means unset. + * @See {@link android.R.attr#minAspectRatio}. + * @hide + */ + public float minAspectRatio; + /** * Name of the VrListenerService component to run for this activity. * @see android.R.attr#enableVrMode @@ -979,6 +988,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { rotationAnimation = orig.rotationAnimation; colorMode = orig.colorMode; maxAspectRatio = orig.maxAspectRatio; + minAspectRatio = orig.minAspectRatio; } /** @@ -1142,6 +1152,9 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { if (maxAspectRatio != 0) { pw.println(prefix + "maxAspectRatio=" + maxAspectRatio); } + if (minAspectRatio != 0) { + pw.println(prefix + "minAspectRatio=" + minAspectRatio); + } super.dumpBack(pw, prefix, dumpFlags); } @@ -1190,6 +1203,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { dest.writeInt(rotationAnimation); dest.writeInt(colorMode); dest.writeFloat(maxAspectRatio); + dest.writeFloat(minAspectRatio); } /** @@ -1309,6 +1323,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { rotationAnimation = source.readInt(); colorMode = source.readInt(); maxAspectRatio = source.readFloat(); + minAspectRatio = source.readFloat(); } /** diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index c361ac12667ed..0c438afd7a83d 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -712,6 +712,15 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public float maxAspectRatio; + /** + * Value indicating the minimum aspect ratio the application supports. + *
+ * 0 means unset.
+ * @see {@link android.R.attr#minAspectRatio}.
+ * @hide
+ */
+ public float minAspectRatio;
+
/** @removed */
@Deprecated
public String volumeUuid;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 61a74ded02d07..e38b294b44850 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -30,6 +30,7 @@ import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
+import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
@@ -162,6 +163,8 @@ public class PackageParser {
SystemProperties.getBoolean(PROPERTY_CHILD_PACKAGES_ENABLED, false);
private static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f;
+ private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO = 1.333f;
+ private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH = 1f;
// TODO: switch outError users to PackageParserException
// TODO: refactor "codePath" to "apkPath"
@@ -3673,6 +3676,7 @@ public class PackageParser {
}
ai.maxAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, 0);
+ ai.minAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_minAspectRatio, 0);
ai.networkSecurityConfigRes = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestApplication_networkSecurityConfig,
@@ -3995,6 +3999,7 @@ public class PackageParser {
// Must be ran after the entire {@link ApplicationInfo} has been fully processed and after
// every activity info has had a chance to set it from its attributes.
setMaxAspectRatio(owner);
+ setMinAspectRatio(owner);
PackageBackwardCompatibility.modifySharedLibraries(owner);
@@ -4492,6 +4497,13 @@ public class PackageParser {
0 /*default*/));
}
+ if (sa.hasValue(R.styleable.AndroidManifestActivity_minAspectRatio)
+ && sa.getType(R.styleable.AndroidManifestActivity_minAspectRatio)
+ == TypedValue.TYPE_FLOAT) {
+ a.setMinAspectRatio(sa.getFloat(R.styleable.AndroidManifestActivity_minAspectRatio,
+ 0 /*default*/));
+ }
+
a.info.lockTaskLaunchMode =
sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
@@ -4750,6 +4762,34 @@ public class PackageParser {
}
}
+ /**
+ * Sets every the max aspect ratio of every child activity that doesn't already have an aspect
+ * ratio set.
+ */
+ private void setMinAspectRatio(Package owner) {
+ final float minAspectRatio;
+ if (owner.applicationInfo.minAspectRatio != 0) {
+ // Use the application max aspect ration as default if set.
+ minAspectRatio = owner.applicationInfo.minAspectRatio;
+ } else {
+ // Default to (1.33) 4:3 aspect ratio for pre-Q apps and unset for Q and greater.
+ // NOTE: 4:3 was the min aspect ratio Android devices can support pre-Q per the CDD,
+ // except for watches which always supported 1:1.
+ minAspectRatio = owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q
+ ? 0
+ : mCallback.hasFeature(FEATURE_WATCH)
+ ? DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH
+ : DEFAULT_PRE_Q_MIN_ASPECT_RATIO;
+ }
+
+ for (Activity activity : owner.activities) {
+ if (activity.hasMinAspectRatio()) {
+ continue;
+ }
+ activity.setMinAspectRatio(minAspectRatio);
+ }
+ }
+
/**
* @param configChanges The bit mask of configChanges fetched from AndroidManifest.xml.
* @param recreateOnConfigChanges The bit mask recreateOnConfigChanges fetched from
@@ -4888,6 +4928,7 @@ public class PackageParser {
info.windowLayout = target.info.windowLayout;
info.resizeMode = target.info.resizeMode;
info.maxAspectRatio = target.info.maxAspectRatio;
+ info.minAspectRatio = target.info.minAspectRatio;
info.requestedVrComponent = target.info.requestedVrComponent;
info.encryptionAware = info.directBootAware = target.info.directBootAware;
@@ -7773,11 +7814,16 @@ public class PackageParser {
@UnsupportedAppUsage
public final ActivityInfo info;
private boolean mHasMaxAspectRatio;
+ private boolean mHasMinAspectRatio;
private boolean hasMaxAspectRatio() {
return mHasMaxAspectRatio;
}
+ private boolean hasMinAspectRatio() {
+ return mHasMinAspectRatio;
+ }
+
// To construct custom activity which does not exist in manifest
Activity(final Package owner, final String className, final ActivityInfo info) {
super(owner, new ArrayList<>(0), className);
@@ -7813,6 +7859,22 @@ public class PackageParser {
mHasMaxAspectRatio = true;
}
+ private void setMinAspectRatio(float minAspectRatio) {
+ if (info.resizeMode == RESIZE_MODE_RESIZEABLE
+ || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
+ // Resizeable activities can be put in any aspect ratio.
+ return;
+ }
+
+ if (minAspectRatio < 1.0f && minAspectRatio != 0) {
+ // Ignore any value lesser than 1.0.
+ return;
+ }
+
+ info.minAspectRatio = minAspectRatio;
+ mHasMinAspectRatio = true;
+ }
+
public String toString() {
StringBuilder sb = new StringBuilder(128);
sb.append("Activity{");
@@ -7833,12 +7895,14 @@ public class PackageParser {
super.writeToParcel(dest, flags);
dest.writeParcelable(info, flags | Parcelable.PARCELABLE_ELIDE_DUPLICATES);
dest.writeBoolean(mHasMaxAspectRatio);
+ dest.writeBoolean(mHasMinAspectRatio);
}
private Activity(Parcel in) {
super(in);
info = in.readParcelable(Object.class.getClassLoader());
mHasMaxAspectRatio = in.readBoolean();
+ mHasMinAspectRatio = in.readBoolean();
for (ActivityIntentInfo aii : intents) {
aii.activity = this;
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 35263a3fa8919..dd51cb615d8a5 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1294,6 +1294,20 @@
supports any size. -->