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

Commit 2d96d67c authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Add scheme specific part to IntentFilter."

parents 4d244e5f df1c0bf7
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