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

Commit 6d418b62 authored by Todd Kennedy's avatar Todd Kennedy
Browse files

Add component ordering

When multiple activities match the same Intent, allow app developers
to reorder matched results within their own application. This is not
a replacement for priority which reorders matched results between
applications.

Change-Id: I12ee987622e12e40d6b5b48f616cc362d01381de
Fixes: 64582537
Test: atest -it CtsAppSecurityHostTestCases:PackageResolutionHostTest
parent 11817c6b
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1872,9 +1872,10 @@ public class IntentFilter implements Parcelable {
                du.println(sb.toString());
            }
        }
        if (mPriority != 0 || mHasPartialTypes) {
        if (mPriority != 0 || mOrder != 0 || mHasPartialTypes) {
            sb.setLength(0);
            sb.append(prefix); sb.append("mPriority="); sb.append(mPriority);
                    sb.append(", mOrder="); sb.append(mOrder);
                    sb.append(", mHasPartialTypes="); sb.append(mHasPartialTypes);
            du.println(sb.toString());
        }
@@ -1951,6 +1952,7 @@ public class IntentFilter implements Parcelable {
        dest.writeInt(mHasPartialTypes ? 1 : 0);
        dest.writeInt(getAutoVerify() ? 1 : 0);
        dest.writeInt(mInstantAppVisibility);
        dest.writeInt(mOrder);
    }

    /**
@@ -2020,6 +2022,7 @@ public class IntentFilter implements Parcelable {
        mHasPartialTypes = source.readInt() > 0;
        setAutoVerify(source.readInt() > 0);
        setVisibilityToInstantApp(source.readInt());
        mOrder = source.readInt();
    }

    private final boolean findMimeType(String type) {
+28 −1
Original line number Diff line number Diff line
@@ -3638,7 +3638,9 @@ public class PackageParser {
        // getting added to the wrong package.
        final CachedComponentArgs cachedArgs = new CachedComponentArgs();
        int type;

        boolean hasActivityOrder = false;
        boolean hasReceiverOrder = false;
        boolean hasServiceOrder = false;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
@@ -3654,6 +3656,7 @@ public class PackageParser {
                    return false;
                }

                hasActivityOrder |= (a.order != 0);
                owner.activities.add(a);

            } else if (tagName.equals("receiver")) {
@@ -3664,6 +3667,7 @@ public class PackageParser {
                    return false;
                }

                hasReceiverOrder |= (a.order != 0);
                owner.receivers.add(a);

            } else if (tagName.equals("service")) {
@@ -3673,6 +3677,7 @@ public class PackageParser {
                    return false;
                }

                hasServiceOrder |= (s.order != 0);
                owner.services.add(s);

            } else if (tagName.equals("provider")) {
@@ -3691,6 +3696,7 @@ public class PackageParser {
                    return false;
                }

                hasActivityOrder |= (a.order != 0);
                owner.activities.add(a);

            } else if (parser.getName().equals("meta-data")) {
@@ -3824,6 +3830,15 @@ public class PackageParser {
            }
        }

        if (hasActivityOrder) {
            Collections.sort(owner.activities, (a1, a2) -> Integer.compare(a2.order, a1.order));
        }
        if (hasReceiverOrder) {
            Collections.sort(owner.receivers,  (r1, r2) -> Integer.compare(r2.order, r1.order));
        }
        if (hasServiceOrder) {
            Collections.sort(owner.services,  (s1, s2) -> Integer.compare(s2.order, s1.order));
        }
        // 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);
@@ -4365,6 +4380,7 @@ public class PackageParser {
                            + mArchiveSourcePath + " "
                            + parser.getPositionDescription());
                } else {
                    a.order = Math.max(intent.getOrder(), a.order);
                    a.intents.add(intent);
                }
                // adjust activity flags when we implicitly expose it via a browsable filter
@@ -4742,6 +4758,7 @@ public class PackageParser {
                            + mArchiveSourcePath + " "
                            + parser.getPositionDescription());
                } else {
                    a.order = Math.max(intent.getOrder(), a.order);
                    a.intents.add(intent);
                }
                // adjust activity flags when we implicitly expose it via a browsable filter
@@ -4949,6 +4966,7 @@ public class PackageParser {
                    intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
                    outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP;
                }
                outInfo.order = Math.max(intent.getOrder(), outInfo.order);
                outInfo.intents.add(intent);

            } else if (parser.getName().equals("meta-data")) {
@@ -5238,6 +5256,7 @@ public class PackageParser {
                    intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
                    s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP;
                }
                s.order = Math.max(intent.getOrder(), s.order);
                s.intents.add(intent);
            } else if (parser.getName().equals("meta-data")) {
                if ((s.metaData=parseMetaData(res, parser, s.metaData,
@@ -5463,6 +5482,10 @@ public class PackageParser {
                com.android.internal.R.styleable.AndroidManifestIntentFilter_priority, 0);
        outInfo.setPriority(priority);

        int order = sa.getInt(
                com.android.internal.R.styleable.AndroidManifestIntentFilter_order, 0);
        outInfo.setOrder(order);

        TypedValue v = sa.peekValue(
                com.android.internal.R.styleable.AndroidManifestIntentFilter_label);
        if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
@@ -7047,6 +7070,8 @@ public class PackageParser {

        public Bundle metaData;
        public Package owner;
        /** The order of this component in relation to its peers */
        public int order;

        ComponentName componentName;
        String componentShortName;
@@ -7565,6 +7590,7 @@ public class PackageParser {

            for (ActivityIntentInfo aii : intents) {
                aii.activity = this;
                order = Math.max(aii.getOrder(), order);
            }

            if (info.permission != null) {
@@ -7654,6 +7680,7 @@ public class PackageParser {

            for (ServiceIntentInfo aii : intents) {
                aii.service = this;
                order = Math.max(aii.getOrder(), order);
            }

            if (info.permission != null) {
+10 −0
Original line number Diff line number Diff line
@@ -2345,6 +2345,16 @@
        <attr name="logo" />
        <attr name="priority" />
        <attr name="autoVerify" />
        <!-- Within an application, multiple intent filters may match a particular
             intent. This allows the app author to specify the order filters should
             be considered. We don't want to use priority because that is global
             across applications.
             <p>Only use if you really need to forcibly set the order in which
             filters are evaluated. It is preferred to target an activity with a
             directed intent instead.
             <p>The value is a single integer, with higher numbers considered to
             be better. If not specified, the default order is 0. -->
        <attr name="order" />
    </declare-styleable>

    <!-- Attributes that can be supplied in an AndroidManifest.xml