Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 917791e1 authored by Adrian Roos's avatar Adrian Roos
Browse files

Add minAspectRatio

Adds logic to enforce a minimum aspect ratio and a new manifest
attribute for requesting a minimum aspect ratio.

Bug: 120129697
Test: atest AspectRatioTests
Change-Id: Ie714541241dcdfae2bdf3bfd969a4e26829fbb4b
parent bb28a036
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+15 −0
Original line number Diff line number Diff line
@@ -235,6 +235,15 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
     */
    public float maxAspectRatio;

    /**
     * Value indicating the minimum aspect ratio the activity supports.
     * <p>
     * 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();
    }

    /**
+9 −0
Original line number Diff line number Diff line
@@ -712,6 +712,15 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
     */
    public float maxAspectRatio;

    /**
     * Value indicating the minimum aspect ratio the application supports.
     * <p>
     * 0 means unset.
     * @see {@link android.R.attr#minAspectRatio}.
     * @hide
     */
    public float minAspectRatio;

    /** @removed */
    @Deprecated
    public String volumeUuid;
+64 −0
Original line number Diff line number Diff line
@@ -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;
+16 −0
Original line number Diff line number Diff line
@@ -1294,6 +1294,20 @@
         supports any size. -->
    <attr name="maxAspectRatio" format="float" />

    <!-- This value indicates the minimum aspect ratio the activity supports. If the app runs on a
         device with a narrower aspect ratio, the system automatically letterboxes the app, leaving
         portions of the screen unused so the app can run at its specified minimum aspect ratio.
         <p>
         Minimum aspect ratio, expressed as (longer dimension / shorter dimension) in decimal
         form. For example, if the minimum aspect ratio is 4:3, set value to 1.33.
         <p>
         Value needs to be greater or equal to 1.0, otherwise it is ignored.
         <p>
         NOTE: This attribute is ignored if the activity has
         {@link android.R.attr#resizeableActivity} set to true, since that means your activity
         supports any size. -->
    <attr name="minAspectRatio" format="float" />

    <!-- This value indicates how tasks rooted at this activity will behave in lockTask mode.
         While in lockTask mode the system will not launch non-permitted tasks until
         lockTask mode is disabled.
@@ -1571,6 +1585,7 @@
        <attr name="directBootAware" />
        <attr name="resizeableActivity" />
        <attr name="maxAspectRatio" />
        <attr name="minAspectRatio" />
        <attr name="networkSecurityConfig" />
        <!-- Declare the category of this app. Categories are used to cluster multiple apps
             together into meaningful groups, such as when summarizing battery, network, or
@@ -2386,6 +2401,7 @@
        <attr name="resizeableActivity" />
        <attr name="supportsPictureInPicture" />
        <attr name="maxAspectRatio" />
        <attr name="minAspectRatio" />
        <attr name="lockTaskMode" />
        <attr name="showForAllUsers" />

Loading