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

Commit df1c0bf7 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Add scheme specific part to IntentFilter.

Change-Id: I063d086cdc742800b8e31ddf2942f2e9230e2785
parent 9ddd70b9
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -954,6 +954,9 @@ package android {
    field public static final int spinnersShown = 16843595; // 0x101034b
    field public static final int splitMotionEvents = 16843503; // 0x10102ef
    field public static final int src = 16843033; // 0x1010119
    field public static final int ssp = 16843744; // 0x10103e0
    field public static final int sspPattern = 16843746; // 0x10103e2
    field public static final int sspPrefix = 16843745; // 0x10103e1
    field public static final int stackFromBottom = 16843005; // 0x10100fd
    field public static final int starStyle = 16842882; // 0x1010082
    field public static final int startColor = 16843165; // 0x101019d
@@ -6322,6 +6325,7 @@ package android.content {
    method public final void addDataAuthority(java.lang.String, java.lang.String);
    method public final void addDataPath(java.lang.String, int);
    method public final void addDataScheme(java.lang.String);
    method public final void addDataSchemeSpecificPart(java.lang.String, int);
    method public final void addDataType(java.lang.String) throws android.content.IntentFilter.MalformedMimeTypeException;
    method public final java.util.Iterator<android.content.IntentFilter.AuthorityEntry> authoritiesIterator();
    method public final java.util.Iterator<java.lang.String> categoriesIterator();
@@ -6329,6 +6333,7 @@ package android.content {
    method public final int countCategories();
    method public final int countDataAuthorities();
    method public final int countDataPaths();
    method public final int countDataSchemeSpecificParts();
    method public final int countDataSchemes();
    method public final int countDataTypes();
    method public static android.content.IntentFilter create(java.lang.String, java.lang.String);
@@ -6339,6 +6344,7 @@ package android.content {
    method public final android.content.IntentFilter.AuthorityEntry getDataAuthority(int);
    method public final android.os.PatternMatcher getDataPath(int);
    method public final java.lang.String getDataScheme(int);
    method public final android.os.PatternMatcher getDataSchemeSpecificPart(int);
    method public final java.lang.String getDataType(int);
    method public final int getPriority();
    method public final boolean hasAction(java.lang.String);
@@ -6346,6 +6352,7 @@ package android.content {
    method public final boolean hasDataAuthority(android.net.Uri);
    method public final boolean hasDataPath(java.lang.String);
    method public final boolean hasDataScheme(java.lang.String);
    method public final boolean hasDataSchemeSpecificPart(java.lang.String);
    method public final boolean hasDataType(java.lang.String);
    method public final int match(android.content.ContentResolver, android.content.Intent, boolean, java.lang.String);
    method public final int match(java.lang.String, java.lang.String, java.lang.String, android.net.Uri, java.util.Set<java.lang.String>, java.lang.String);
@@ -6355,6 +6362,7 @@ package android.content {
    method public final int matchDataAuthority(android.net.Uri);
    method public final java.util.Iterator<android.os.PatternMatcher> pathsIterator();
    method public void readFromXml(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
    method public final java.util.Iterator<android.os.PatternMatcher> schemeSpecificPartsIterator();
    method public final java.util.Iterator<java.lang.String> schemesIterator();
    method public final void setPriority(int);
    method public final java.util.Iterator<java.lang.String> typesIterator();
@@ -6369,6 +6377,7 @@ package android.content {
    field public static final int MATCH_CATEGORY_PATH = 5242880; // 0x500000
    field public static final int MATCH_CATEGORY_PORT = 4194304; // 0x400000
    field public static final int MATCH_CATEGORY_SCHEME = 2097152; // 0x200000
    field public static final int MATCH_CATEGORY_SCHEME_SPECIFIC_PART = 5767168; // 0x580000
    field public static final int MATCH_CATEGORY_TYPE = 6291456; // 0x600000
    field public static final int NO_MATCH_ACTION = -3; // 0xfffffffd
    field public static final int NO_MATCH_CATEGORY = -4; // 0xfffffffc
+170 −18
Original line number Diff line number Diff line
@@ -50,8 +50,8 @@ import java.util.Set;
 * <em>action</em>, <em>data</em>, and <em>categories</em>.  For each of these
 * characteristics you can provide
 * multiple possible matching values (via {@link #addAction},
 * {@link #addDataType}, {@link #addDataScheme} {@link #addDataAuthority},
 * {@link #addDataPath}, and {@link #addCategory}, respectively).
 * {@link #addDataType}, {@link #addDataScheme}, {@link #addDataSchemeSpecificPart},
 * {@link #addDataAuthority}, {@link #addDataPath}, and {@link #addCategory}, respectively).
 * For actions, the field
 * will not be tested if no values have been given (treating it as a wildcard);
 * if no data characteristics are specified, however, then the filter will
@@ -106,8 +106,15 @@ import java.util.Set;
 * formal RFC schemes!</em>  You should thus always use lower case letters
 * for your schemes.
 *
 * <p><strong>Data Scheme Specific Part</strong> matches if any of the given values match
 * the Intent's data scheme specific part <em>and</em> one of the data schemes in the filter
 * has matched the Intent, <em>or</em> no scheme specific parts were supplied in the filter.
 * The Intent scheme specific part is determined by calling
 * {@link Intent#getData} and {@link android.net.Uri#getSchemeSpecificPart} on that URI.
 * <em>Note that scheme specific part matching is <b>case sensitive</b>.</em>
 *
 * <p><strong>Data Authority</strong> matches if any of the given values match
 * the Intent's data authority <em>and</em> one of the data scheme's in the filter
 * the Intent's data authority <em>and</em> one of the data schemes in the filter
 * has matched the Intent, <em>or</em> no authories were supplied in the filter.
 * The Intent authority is determined by calling
 * {@link Intent#getData} and {@link android.net.Uri#getAuthority} on that URI.
@@ -135,6 +142,7 @@ public class IntentFilter implements Parcelable {
    private static final String PORT_STR = "port";
    private static final String HOST_STR = "host";
    private static final String AUTH_STR = "auth";
    private static final String SSP_STR = "ssp";
    private static final String SCHEME_STR = "scheme";
    private static final String TYPE_STR = "type";
    private static final String CAT_STR = "cat";
@@ -164,8 +172,8 @@ public class IntentFilter implements Parcelable {
    /**
     * The part of a match constant that describes the category of match
     * that occurred.  May be either {@link #MATCH_CATEGORY_EMPTY},
     * {@link #MATCH_CATEGORY_SCHEME}, {@link #MATCH_CATEGORY_HOST},
     * {@link #MATCH_CATEGORY_PORT},
     * {@link #MATCH_CATEGORY_SCHEME}, {@link #MATCH_CATEGORY_SCHEME_SPECIFIC_PART},
     * {@link #MATCH_CATEGORY_HOST}, {@link #MATCH_CATEGORY_PORT},
     * {@link #MATCH_CATEGORY_PATH}, or {@link #MATCH_CATEGORY_TYPE}.  Higher
     * values indicate a better match.
     */
@@ -209,6 +217,11 @@ public class IntentFilter implements Parcelable {
     * authority, and path.
     */
    public static final int MATCH_CATEGORY_PATH = 0x0500000;
    /**
     * The filter matched an intent with the same data URI scheme and
     * scheme specific part.
     */
    public static final int MATCH_CATEGORY_SCHEME_SPECIFIC_PART = 0x0580000;
    /**
     * The filter matched an intent with the same data MIME type.
     */
@@ -236,6 +249,7 @@ public class IntentFilter implements Parcelable {
    private final ArrayList<String> mActions;
    private ArrayList<String> mCategories = null;
    private ArrayList<String> mDataSchemes = null;
    private ArrayList<PatternMatcher> mDataSchemeSpecificParts = null;
    private ArrayList<AuthorityEntry> mDataAuthorities = null;
    private ArrayList<PatternMatcher> mDataPaths = null;
    private ArrayList<String> mDataTypes = null;
@@ -395,6 +409,9 @@ public class IntentFilter implements Parcelable {
        if (o.mDataSchemes != null) {
            mDataSchemes = new ArrayList<String>(o.mDataSchemes);
        }
        if (o.mDataSchemeSpecificParts != null) {
            mDataSchemeSpecificParts = new ArrayList<PatternMatcher>(o.mDataSchemeSpecificParts);
        }
        if (o.mDataAuthorities != null) {
            mDataAuthorities = new ArrayList<AuthorityEntry>(o.mDataAuthorities);
        }
@@ -698,6 +715,77 @@ public class IntentFilter implements Parcelable {
        }
    };

    /**
     * Add a new Intent data "scheme specific part" to match against.  The filter must
     * include one or more schemes (via {@link #addDataScheme}) for the
     * scheme specific part to be considered.  If any scheme specific parts are
     * included in the filter, then an Intent's data must match one of
     * them.  If no scheme specific parts are included, then only the scheme must match.
     *
     * @param ssp Either a raw string that must exactly match the scheme specific part
     * path, or a simple pattern, depending on <var>type</var>.
     * @param type Determines how <var>ssp</var> will be compared to
     * determine a match: either {@link PatternMatcher#PATTERN_LITERAL},
     * {@link PatternMatcher#PATTERN_PREFIX}, or
     * {@link PatternMatcher#PATTERN_SIMPLE_GLOB}.
     *
     * @see #matchData
     * @see #addDataScheme
     */
    public final void addDataSchemeSpecificPart(String ssp, int type) {
        if (mDataSchemeSpecificParts == null) mDataSchemeSpecificParts =
                new ArrayList<PatternMatcher>();
        mDataSchemeSpecificParts.add(new PatternMatcher(ssp, type));
    }

    /**
     * Return the number of data scheme specific parts in the filter.
     */
    public final int countDataSchemeSpecificParts() {
        return mDataSchemeSpecificParts != null ? mDataSchemeSpecificParts.size() : 0;
    }

    /**
     * Return a data scheme specific part in the filter.
     */
    public final PatternMatcher getDataSchemeSpecificPart(int index) {
        return mDataSchemeSpecificParts.get(index);
    }

    /**
     * Is the given data scheme specific part included in the filter?  Note that if the
     * filter does not include any scheme specific parts, false will <em>always</em> be
     * returned.
     *
     * @param data The scheme specific part that is being looked for.
     *
     * @return Returns true if the data string matches a scheme specific part listed in the
     *         filter.
     */
    public final boolean hasDataSchemeSpecificPart(String data) {
        if (mDataSchemeSpecificParts == null) {
            return false;
        }
        final int numDataSchemeSpecificParts = mDataSchemeSpecificParts.size();
        if (numDataSchemeSpecificParts <= 0) {
            return false;
        }
        for (int i = 0; i < numDataSchemeSpecificParts; i++) {
            final PatternMatcher pe = mDataSchemeSpecificParts.get(i);
            if (pe.match(data)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Return an iterator over the filter's data scheme specific parts.
     */
    public final Iterator<PatternMatcher> schemeSpecificPartsIterator() {
        return mDataSchemeSpecificParts != null ? mDataSchemeSpecificParts.iterator() : null;
    }

    /**
     * Add a new Intent data authority to match against.  The filter must
     * include one or more schemes (via {@link #addDataScheme}) for the
@@ -900,8 +988,6 @@ public class IntentFilter implements Parcelable {
    public final int matchData(String type, String scheme, Uri data) {
        final ArrayList<String> types = mDataTypes;
        final ArrayList<String> schemes = mDataSchemes;
        final ArrayList<AuthorityEntry> authorities = mDataAuthorities;
        final ArrayList<PatternMatcher> paths = mDataPaths;

        int match = MATCH_CATEGORY_EMPTY;

@@ -917,9 +1003,18 @@ public class IntentFilter implements Parcelable {
                return NO_MATCH_DATA;
            }

            final ArrayList<PatternMatcher> schemeSpecificParts = mDataSchemeSpecificParts;
            if (schemeSpecificParts != null) {
                match = hasDataSchemeSpecificPart(data.getSchemeSpecificPart())
                        ? MATCH_CATEGORY_SCHEME_SPECIFIC_PART : NO_MATCH_DATA;
            }
            if (match != MATCH_CATEGORY_SCHEME_SPECIFIC_PART) {
                // If there isn't any matching ssp, we need to match an authority.
                final ArrayList<AuthorityEntry> authorities = mDataAuthorities;
                if (authorities != null) {
                    int authMatch = matchDataAuthority(data);
                    if (authMatch >= 0) {
                        final ArrayList<PatternMatcher> paths = mDataPaths;
                        if (paths == null) {
                            match = authMatch;
                        } else if (hasDataPath(data.getPath())) {
@@ -931,6 +1026,11 @@ public class IntentFilter implements Parcelable {
                        return NO_MATCH_DATA;
                    }
                }
            }
            // If neither an ssp nor an authority matched, we're done.
            if (match == NO_MATCH_DATA) {
                return NO_MATCH_DATA;
            }
        } else {
            // Special case: match either an Intent with no data URI,
            // or with a scheme: URI.  This is to give a convenience for
@@ -1173,6 +1273,23 @@ public class IntentFilter implements Parcelable {
            serializer.attribute(null, NAME_STR, mDataSchemes.get(i));
            serializer.endTag(null, SCHEME_STR);
        }
        N = countDataSchemeSpecificParts();
        for (int i=0; i<N; i++) {
            serializer.startTag(null, SSP_STR);
            PatternMatcher pe = mDataSchemeSpecificParts.get(i);
            switch (pe.getType()) {
                case PatternMatcher.PATTERN_LITERAL:
                    serializer.attribute(null, LITERAL_STR, pe.getPath());
                    break;
                case PatternMatcher.PATTERN_PREFIX:
                    serializer.attribute(null, PREFIX_STR, pe.getPath());
                    break;
                case PatternMatcher.PATTERN_SIMPLE_GLOB:
                    serializer.attribute(null, SGLOB_STR, pe.getPath());
                    break;
            }
            serializer.endTag(null, SSP_STR);
        }
        N = countDataAuthorities();
        for (int i=0; i<N; i++) {
            serializer.startTag(null, AUTH_STR);
@@ -1238,6 +1355,15 @@ public class IntentFilter implements Parcelable {
                if (name != null) {
                    addDataScheme(name);
                }
            } else if (tagName.equals(SSP_STR)) {
                String ssp = parser.getAttributeValue(null, LITERAL_STR);
                if (ssp != null) {
                    addDataSchemeSpecificPart(ssp, PatternMatcher.PATTERN_LITERAL);
                } else if ((ssp=parser.getAttributeValue(null, PREFIX_STR)) != null) {
                    addDataSchemeSpecificPart(ssp, PatternMatcher.PATTERN_PREFIX);
                } else if ((ssp=parser.getAttributeValue(null, SGLOB_STR)) != null) {
                    addDataSchemeSpecificPart(ssp, PatternMatcher.PATTERN_SIMPLE_GLOB);
                }
            } else if (tagName.equals(AUTH_STR)) {
                String host = parser.getAttributeValue(null, HOST_STR);
                String port = parser.getAttributeValue(null, PORT_STR);
@@ -1289,6 +1415,16 @@ public class IntentFilter implements Parcelable {
                du.println(sb.toString());
            }
        }
        if (mDataSchemeSpecificParts != null) {
            Iterator<PatternMatcher> it = mDataSchemeSpecificParts.iterator();
            while (it.hasNext()) {
                PatternMatcher pe = it.next();
                sb.setLength(0);
                sb.append(prefix); sb.append("Ssp: \"");
                        sb.append(pe); sb.append("\"");
                du.println(sb.toString());
            }
        }
        if (mDataAuthorities != null) {
            Iterator<AuthorityEntry> it = mDataAuthorities.iterator();
            while (it.hasNext()) {
@@ -1363,6 +1499,15 @@ public class IntentFilter implements Parcelable {
        } else {
            dest.writeInt(0);
        }
        if (mDataSchemeSpecificParts != null) {
            final int N = mDataSchemeSpecificParts.size();
            dest.writeInt(N);
            for (int i=0; i<N; i++) {
                mDataSchemeSpecificParts.get(i).writeToParcel(dest, 0);
            }
        } else {
            dest.writeInt(0);
        }
        if (mDataAuthorities != null) {
            final int N = mDataAuthorities.size();
            dest.writeInt(N);
@@ -1428,14 +1573,21 @@ public class IntentFilter implements Parcelable {
        }
        int N = source.readInt();
        if (N > 0) {
            mDataAuthorities = new ArrayList<AuthorityEntry>();
            mDataSchemeSpecificParts = new ArrayList<PatternMatcher>(N);
            for (int i=0; i<N; i++) {
                mDataSchemeSpecificParts.add(new PatternMatcher(source));
            }
        }
        N = source.readInt();
        if (N > 0) {
            mDataAuthorities = new ArrayList<AuthorityEntry>(N);
            for (int i=0; i<N; i++) {
                mDataAuthorities.add(new AuthorityEntry(source));
            }
        }
        N = source.readInt();
        if (N > 0) {
            mDataPaths = new ArrayList<PatternMatcher>();
            mDataPaths = new ArrayList<PatternMatcher>(N);
            for (int i=0; i<N; i++) {
                mDataPaths.add(new PatternMatcher(source));
            }
+18 −0
Original line number Diff line number Diff line
@@ -3288,6 +3288,24 @@ public class PackageParser {
                    outInfo.addDataScheme(str);
                }

                str = sa.getNonConfigurationString(
                        com.android.internal.R.styleable.AndroidManifestData_ssp, 0);
                if (str != null) {
                    outInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_LITERAL);
                }

                str = sa.getNonConfigurationString(
                        com.android.internal.R.styleable.AndroidManifestData_sspPrefix, 0);
                if (str != null) {
                    outInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_PREFIX);
                }

                str = sa.getNonConfigurationString(
                        com.android.internal.R.styleable.AndroidManifestData_sspPattern, 0);
                if (str != null) {
                    outInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
                }

                String host = sa.getNonConfigurationString(
                        com.android.internal.R.styleable.AndroidManifestData_host, 0);
                String port = sa.getNonConfigurationString(
+12 −1
Original line number Diff line number Diff line
@@ -327,6 +327,17 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte

                    // Look through the resolved filter to determine which part
                    // of it matched the original Intent.
                    Iterator<PatternMatcher> pIt = ri.filter.schemeSpecificPartsIterator();
                    if (pIt != null) {
                        String ssp = data.getSchemeSpecificPart();
                        while (ssp != null && pIt.hasNext()) {
                            PatternMatcher p = pIt.next();
                            if (p.match(ssp)) {
                                filter.addDataSchemeSpecificPart(p.getPath(), p.getType());
                                break;
                            }
                        }
                    }
                    Iterator<IntentFilter.AuthorityEntry> aIt = ri.filter.authoritiesIterator();
                    if (aIt != null) {
                        while (aIt.hasNext()) {
@@ -339,7 +350,7 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
                            }
                        }
                    }
                    Iterator<PatternMatcher> pIt = ri.filter.pathsIterator();
                    pIt = ri.filter.pathsIterator();
                    if (pIt != null) {
                        String path = data.getPath();
                        while (path != null && pIt.hasNext()) {
+24 −3
Original line number Diff line number Diff line
@@ -1624,6 +1624,27 @@
             case-sensitive, unlike the formal RFC.  As a result,
             schemes here should always use lower case letters.</em></p> -->
        <attr name="scheme" format="string" />
        <!-- Specify a URI scheme specific part that must exactly match, as per
             {@link android.content.IntentFilter#addDataSchemeSpecificPart
             IntentFilter.addDataSchemeSpecificPart()} with
             {@link android.os.PatternMatcher#PATTERN_LITERAL}. -->
        <attr name="ssp" format="string" />
        <!-- Specify a URI scheme specific part that must be a prefix to match, as per
             {@link android.content.IntentFilter#addDataSchemeSpecificPart
             IntentFilter.addDataSchemeSpecificPart()} with
             {@link android.os.PatternMatcher#PATTERN_PREFIX}. -->
        <attr name="sspPrefix" format="string" />
        <!-- Specify a URI scheme specific part that matches a simple pattern, as per
             {@link android.content.IntentFilter#addDataSchemeSpecificPart
             IntentFilter.addDataSchemeSpecificPart()} with
             {@link android.os.PatternMatcher#PATTERN_SIMPLE_GLOB}.
             Note that because '\' is used as an escape character when
             reading the string from XML (before it is parsed as a pattern),
             you will need to double-escape: for example a literal "*" would
             be written as "\\*" and a literal "\" would be written as
             "\\\\".  This is basically the same as what you would need to
             write if constructing the string in Java code. -->
        <attr name="sspPattern" format="string" />
        <!-- Specify a URI authority host that is handled, as per
             {@link android.content.IntentFilter#addDataAuthority
             IntentFilter.addDataAuthority()}.
@@ -1638,17 +1659,17 @@
        <attr name="port" format="string" />
        <!-- Specify a URI path that must exactly match, as per
             {@link android.content.IntentFilter#addDataPath
             IntentFilter.addDataAuthority()} with
             IntentFilter.addDataPath()} with
             {@link android.os.PatternMatcher#PATTERN_LITERAL}. -->
        <attr name="path" />
        <!-- Specify a URI path that must be a prefix to match, as per
             {@link android.content.IntentFilter#addDataPath
             IntentFilter.addDataAuthority()} with
             IntentFilter.addDataPath()} with
             {@link android.os.PatternMatcher#PATTERN_PREFIX}. -->
        <attr name="pathPrefix" />
        <!-- Specify a URI path that matches a simple pattern, as per
             {@link android.content.IntentFilter#addDataPath
             IntentFilter.addDataAuthority()} with
             IntentFilter.addDataPath()} with
             {@link android.os.PatternMatcher#PATTERN_SIMPLE_GLOB}. 
             Note that because '\' is used as an escape character when
             reading the string from XML (before it is parsed as a pattern),
Loading