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

Commit abb01dba authored by Dianne Hackborn's avatar Dianne Hackborn Committed by The Android Open Source Project
Browse files

am c14b9ccd: Extend Intent/Uri conversion for use by Browser

Merge commit 'c14b9ccd'

* commit 'c14b9ccd':
  Extend Intent/Uri conversion for use by Browser
parents cc4b106f c14b9ccd
Loading
Loading
Loading
Loading
+77 −35
Original line number Diff line number Diff line
@@ -33439,7 +33439,7 @@
 synchronized="false"
 static="true"
 final="false"
 deprecated="not deprecated"
 deprecated="deprecated"
 visibility="public"
>
<parameter name="uri" type="java.lang.String">
@@ -33490,6 +33490,17 @@
<parameter name="defaultValue" type="long">
</parameter>
</method>
<method name="getPackage"
 return="java.lang.String"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getParcelableArrayExtra"
 return="android.os.Parcelable[]"
 abstract="false"
@@ -33689,6 +33700,23 @@
<exception name="XmlPullParserException" type="org.xmlpull.v1.XmlPullParserException">
</exception>
</method>
<method name="parseUri"
 return="android.content.Intent"
 abstract="false"
 native="false"
 synchronized="false"
 static="true"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="uri" type="java.lang.String">
</parameter>
<parameter name="flags" type="int">
</parameter>
<exception name="URISyntaxException" type="java.net.URISyntaxException">
</exception>
</method>
<method name="putExtra"
 return="android.content.Intent"
 abstract="false"
@@ -34362,6 +34390,19 @@
<parameter name="flags" type="int">
</parameter>
</method>
<method name="setPackage"
 return="android.content.Intent"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="packageName" type="java.lang.String">
</parameter>
</method>
<method name="setType"
 return="android.content.Intent"
 abstract="false"
@@ -34376,6 +34417,17 @@
</parameter>
</method>
<method name="toURI"
 return="java.lang.String"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="deprecated"
 visibility="public"
>
</method>
<method name="toUri"
 return="java.lang.String"
 abstract="false"
 native="false"
@@ -34385,6 +34437,8 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="flags" type="int">
</parameter>
</method>
<method name="writeToParcel"
 return="void"
@@ -35775,6 +35829,17 @@
 visibility="public"
>
</field>
<field name="FILL_IN_PACKAGE"
 type="int"
 transient="false"
 volatile="false"
 value="16"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="FLAG_ACTIVITY_BROUGHT_TO_FRONT"
 type="int"
 transient="false"
@@ -35984,6 +36049,17 @@
 visibility="public"
>
</field>
<field name="URI_INTENT_SCHEME"
 type="int"
 transient="false"
 volatile="false"
 value="1"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
</class>
<class name="Intent.FilterComparison"
 extends="java.lang.Object"
@@ -40288,23 +40364,6 @@
<parameter name="flags" type="int">
</parameter>
</method>
<method name="resolveActivity"
 return="android.content.pm.ResolveInfo"
 abstract="true"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="intent" type="android.content.Intent">
</parameter>
<parameter name="flags" type="int">
</parameter>
<parameter name="packageName" type="java.lang.String">
</parameter>
</method>
<method name="resolveContentProvider"
 return="android.content.pm.ProviderInfo"
 abstract="true"
@@ -119235,23 +119294,6 @@
</parameter>
<parameter name="flags" type="int">
</parameter>
<parameter name="packageName" type="java.lang.String">
</parameter>
</method>
<method name="resolveActivity"
 return="android.content.pm.ResolveInfo"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="intent" type="android.content.Intent">
</parameter>
<parameter name="flags" type="int">
</parameter>
</method>
<method name="resolveContentProvider"
 return="android.content.pm.ProviderInfo"
+4 −15
Original line number Diff line number Diff line
@@ -1535,14 +1535,16 @@ class ApplicationContext extends Context {
            // overall package (such as if it has multiple launcher entries).
            Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
            intentToResolve.addCategory(Intent.CATEGORY_INFO);
            ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0, packageName);
            intentToResolve.setPackage(packageName);
            ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);

            // Otherwise, try to find a main launcher activity.
            if (resolveInfo == null) {
                // reuse the intent instance
                intentToResolve.removeCategory(Intent.CATEGORY_INFO);
                intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
                resolveInfo = resolveActivity(intentToResolve, 0, packageName);
                intentToResolve.setPackage(packageName);
                resolveInfo = resolveActivity(intentToResolve, 0);
            }
            if (resolveInfo == null) {
                return null;
@@ -1789,19 +1791,6 @@ class ApplicationContext extends Context {
            }
        }

        @Override
        public ResolveInfo resolveActivity(Intent intent, int flags, String packageName) {
            try {
                return mPM.resolveIntentForPackage(
                    intent,
                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                    flags,
                    packageName);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }

        @Override
        public List<ResolveInfo> queryIntentActivities(Intent intent,
                int flags) {
+231 −28
Original line number Diff line number Diff line
@@ -2062,11 +2062,26 @@ public class Intent implements Parcelable {
     */
    public static final int FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT = 0x20000000;

    // ---------------------------------------------------------------------
    // ---------------------------------------------------------------------
    // toUri() and parseUri() options.

    /**
     * Flag for use with {@link #toUri} and {@link #parseUri}: the URI string
     * always has the "intent:" scheme.  This syntax can be used when you want
     * to later disambiguate between URIs that are intended to describe an
     * Intent vs. all others that should be treated as raw URIs.  When used
     * with {@link #parseUri}, any other scheme will result in a generic
     * VIEW action for that raw URI.
     */
    public static final int URI_INTENT_SCHEME = 1<<0;
    
    // ---------------------------------------------------------------------

    private String mAction;
    private Uri mData;
    private String mType;
    private String mPackage;
    private ComponentName mComponent;
    private int mFlags;
    private HashSet<String> mCategories;
@@ -2087,6 +2102,7 @@ public class Intent implements Parcelable {
        this.mAction = o.mAction;
        this.mData = o.mData;
        this.mType = o.mType;
        this.mPackage = o.mPackage;
        this.mComponent = o.mComponent;
        this.mFlags = o.mFlags;
        if (o.mCategories != null) {
@@ -2106,6 +2122,7 @@ public class Intent implements Parcelable {
        this.mAction = o.mAction;
        this.mData = o.mData;
        this.mType = o.mType;
        this.mPackage = o.mPackage;
        this.mComponent = o.mComponent;
        if (o.mCategories != null) {
            this.mCategories = new HashSet<String>(o.mCategories);
@@ -2205,24 +2222,51 @@ public class Intent implements Parcelable {
        mComponent = new ComponentName(packageContext, cls);
    }

    /**
     * Call {@link #parseUri} with 0 flags.
     * @deprecated Use {@link #parseUri} instead.
     */
    @Deprecated
    public static Intent getIntent(String uri) throws URISyntaxException {
        return parseUri(uri, 0);
    }
    
    /**
     * Create an intent from a URI.  This URI may encode the action,
     * category, and other intent fields, if it was returned by toURI().  If
     * the Intent was not generate by toURI(), its data will be the entire URI
     * and its action will be ACTION_VIEW.
     * category, and other intent fields, if it was returned by
     * {@link #toUri}..  If the Intent was not generate by toUri(), its data
     * will be the entire URI and its action will be ACTION_VIEW.
     *
     * <p>The URI given here must not be relative -- that is, it must include
     * the scheme and full path.
     *
     * @param uri The URI to turn into an Intent.
     * @param flags Additional processing flags.  Either 0 or
     *
     * @return Intent The newly created Intent object.
     *
     * @see #toURI
     * @throws URISyntaxException Throws URISyntaxError if the basic URI syntax
     * it bad (as parsed by the Uri class) or the Intent data within the
     * URI is invalid.
     * 
     * @see #toUri
     */
    public static Intent getIntent(String uri) throws URISyntaxException {
    public static Intent parseUri(String uri, int flags) throws URISyntaxException {
        int i = 0;
        try {
            // Validate intent scheme for if requested.
            if ((flags&URI_INTENT_SCHEME) != 0) {
                if (!uri.startsWith("intent:")) {
                    Intent intent = new Intent(ACTION_VIEW);
                    try {
                        intent.setData(Uri.parse(uri));
                    } catch (IllegalArgumentException e) {
                        throw new URISyntaxException(uri, e.getMessage());
                    }
                    return intent;
                }
            }
            
            // simple case
            i = uri.lastIndexOf("#");
            if (i == -1) return new Intent(ACTION_VIEW, Uri.parse(uri));
@@ -2234,16 +2278,15 @@ public class Intent implements Parcelable {
            Intent intent = new Intent(ACTION_VIEW);

            // fetch data part, if present
            if (i > 0) {
                intent.mData = Uri.parse(uri.substring(0, i));
            }
            String data = i >= 0 ? uri.substring(0, i) : null;
            String scheme = null;
            i += "#Intent;".length();

            // loop over contents of Intent, all name=value;
            while (!uri.startsWith("end", i)) {
                int eq = uri.indexOf('=', i);
                int semi = uri.indexOf(';', eq);
                String value = uri.substring(eq + 1, semi);
                String value = Uri.decode(uri.substring(eq + 1, semi));

                // action
                if (uri.startsWith("action=", i)) {
@@ -2265,15 +2308,24 @@ public class Intent implements Parcelable {
                    intent.mFlags = Integer.decode(value).intValue();
                }

                // package
                else if (uri.startsWith("package=", i)) {
                    intent.mPackage = value;
                }

                // component
                else if (uri.startsWith("component=", i)) {
                    intent.mComponent = ComponentName.unflattenFromString(value);
                }

                // scheme
                else if (uri.startsWith("scheme=", i)) {
                    scheme = value;
                }

                // extra
                else {
                    String key = Uri.decode(uri.substring(i + 2, eq));
                    value = Uri.decode(value);
                    // create Bundle if it doesn't already exist
                    if (intent.mExtras == null) intent.mExtras = new Bundle();
                    Bundle b = intent.mExtras;
@@ -2294,6 +2346,23 @@ public class Intent implements Parcelable {
                i = semi + 1;
            }

            if (data != null) {
                if (data.startsWith("intent:")) {
                    data = data.substring(7);
                    if (scheme != null) {
                        data = scheme + ':' + data;
                    }
                }
                
                if (data.length() > 0) {
                    try {
                        intent.mData = Uri.parse(data);
                    } catch (IllegalArgumentException e) {
                        throw new URISyntaxException(uri, e.getMessage());
                    }
                }
            }
            
            return intent;

        } catch (IndexOutOfBoundsException e) {
@@ -3106,6 +3175,20 @@ public class Intent implements Parcelable {
        return mFlags;
    }

    /**
     * Retrieve the application package name this Intent is limited to.  When
     * resolving an Intent, if non-null this limits the resolution to only
     * components in the given application package.
     *
     * @return The name of the application package for the Intent.
     *
     * @see #resolveActivity
     * @see #setPackage
     */
    public String getPackage() {
        return mPackage;
    }

    /**
     * Retrieve the concrete component associated with the intent.  When receiving
     * an intent, this is the component that was found to best handle it (that is,
@@ -3141,6 +3224,9 @@ public class Intent implements Parcelable {
     * <p>If {@link #addCategory} has added any categories, the activity must
     * handle ALL of the categories specified.
     *
     * <p>If {@link #getPackage} is non-NULL, only activity components in
     * that application package will be considered.
     *
     * <p>If there are no activities that satisfy all of these conditions, a
     * null string is returned.
     *
@@ -4111,6 +4197,27 @@ public class Intent implements Parcelable {
        return this;
    }

    /**
     * (Usually optional) Set an explicit application package name that limits
     * the components this Intent will resolve to.  If left to the default
     * value of null, all components in all applications will considered.
     * If non-null, the Intent can only match the components in the given
     * application package.
     *
     * @param packageName The name of the application package to handle the
     * intent, or null to allow any application package.
     *
     * @return Returns the same Intent object, for chaining multiple calls
     * into a single statement.
     *
     * @see #getPackage
     * @see #resolveActivity
     */
    public Intent setPackage(String packageName) {
        mPackage = packageName;
        return this;
    }

    /**
     * (Usually optional) Explicitly set the component to handle the intent.
     * If left with the default value of null, the system will determine the
@@ -4222,6 +4329,12 @@ public class Intent implements Parcelable {
     */
    public static final int FILL_IN_COMPONENT = 1<<3;

    /**
     * Use with {@link #fillIn} to allow the current package value to be
     * overwritten, even if it is already set.
     */
    public static final int FILL_IN_PACKAGE = 1<<4;

    /**
     * Copy the contents of <var>other</var> in to this object, but only
     * where fields are not defined by this object.  For purposes of a field
@@ -4233,14 +4346,15 @@ public class Intent implements Parcelable {
     * <li> data URI and MIME type, as set by {@link #setData(Uri)},
     * {@link #setType(String)}, or {@link #setDataAndType(Uri, String)}.
     * <li> categories, as set by {@link #addCategory}.
     * <li> package, as set by {@link #setPackage}.
     * <li> component, as set by {@link #setComponent(ComponentName)} or
     * related methods.
     * <li> each top-level name in the associated extras.
     * </ul>
     *
     * <p>In addition, you can use the {@link #FILL_IN_ACTION},
     * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, and
     * {@link #FILL_IN_COMPONENT} to override the restriction where the
     * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, {@link #FILL_IN_PACKAGE},
     * and {@link #FILL_IN_COMPONENT} to override the restriction where the
     * corresponding field will not be replaced if it is already set.
     *
     * <p>For example, consider Intent A with {data="foo", categories="bar"}
@@ -4256,32 +4370,39 @@ public class Intent implements Parcelable {
     * @param flags Options to control which fields can be filled in.
     *
     * @return Returns a bit mask of {@link #FILL_IN_ACTION},
     * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, and
     * {@link #FILL_IN_COMPONENT} indicating which fields were changed.
     * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, {@link #FILL_IN_PACKAGE},
     * and {@link #FILL_IN_COMPONENT} indicating which fields were changed.
     */
    public int fillIn(Intent other, int flags) {
        int changes = 0;
        if ((mAction == null && other.mAction == null)
                || (flags&FILL_IN_ACTION) != 0) {
        if (other.mAction != null
                && (mAction == null || (flags&FILL_IN_ACTION) != 0)) {
            mAction = other.mAction;
            changes |= FILL_IN_ACTION;
        }
        if ((mData == null && mType == null &&
                (other.mData != null || other.mType != null))
                || (flags&FILL_IN_DATA) != 0) {
        if ((other.mData != null || other.mType != null)
                && ((mData == null && mType == null)
                        || (flags&FILL_IN_DATA) != 0)) {
            mData = other.mData;
            mType = other.mType;
            changes |= FILL_IN_DATA;
        }
        if ((mCategories == null && other.mCategories == null)
                || (flags&FILL_IN_CATEGORIES) != 0) {
        if (other.mCategories != null
                && (mCategories == null || (flags&FILL_IN_CATEGORIES) != 0)) {
            if (other.mCategories != null) {
                mCategories = new HashSet<String>(other.mCategories);
            }
            changes |= FILL_IN_CATEGORIES;
        }
        if ((mComponent == null && other.mComponent == null)
                || (flags&FILL_IN_COMPONENT) != 0) {
        if (other.mPackage != null
                && (mPackage == null || (flags&FILL_IN_PACKAGE) != 0)) {
            mPackage = other.mPackage;
            changes |= FILL_IN_PACKAGE;
        }
        // Component is special: it can -only- be set if explicitly allowed,
        // since otherwise the sender could force the intent somewhere the
        // originator didn't intend.
        if (other.mComponent != null && (flags&FILL_IN_COMPONENT) != 0) {
            mComponent = other.mComponent;
            changes |= FILL_IN_COMPONENT;
        }
@@ -4396,6 +4517,17 @@ public class Intent implements Parcelable {
                }
            }
        }
        if (mPackage != other.mPackage) {
            if (mPackage != null) {
                if (!mPackage.equals(other.mPackage)) {
                    return false;
                }
            } else {
                if (!other.mPackage.equals(mPackage)) {
                    return false;
                }
            }
        }
        if (mComponent != other.mComponent) {
            if (mComponent != null) {
                if (!mComponent.equals(other.mComponent)) {
@@ -4441,6 +4573,9 @@ public class Intent implements Parcelable {
        if (mType != null) {
            code += mType.hashCode();
        }
        if (mPackage != null) {
            code += mPackage.hashCode();
        }
        if (mComponent != null) {
            code += mComponent.hashCode();
        }
@@ -4511,6 +4646,13 @@ public class Intent implements Parcelable {
            first = false;
            b.append("flg=0x").append(Integer.toHexString(mFlags));
        }
        if (mPackage != null) {
            if (!first) {
                b.append(' ');
            }
            first = false;
            b.append("pkg=").append(mPackage);
        }
        if (comp && mComponent != null) {
            if (!first) {
                b.append(' ');
@@ -4527,28 +4669,87 @@ public class Intent implements Parcelable {
        }
    }

    /**
     * Call {@link #toUri} with 0 flags.
     * @deprecated Use {@link #toUri} instead.
     */
    @Deprecated
    public String toURI() {
        return toUri(0);
    }

    /**
     * Convert this Intent into a String holding a URI representation of it.
     * The returned URI string has been properly URI encoded, so it can be
     * used with {@link Uri#parse Uri.parse(String)}.  The URI contains the
     * Intent's data as the base URI, with an additional fragment describing
     * the action, categories, type, flags, package, component, and extras.
     * 
     * <p>You can convert the returned string back to an Intent with
     * {@link #getIntent}.
     * 
     * @param flags Additional operating flags.  Either 0 or
     * {@link #URI_INTENT_SCHEME}.
     * 
     * @return Returns a URI encoding URI string describing the entire contents
     * of the Intent.
     */
    public String toUri(int flags) {
        StringBuilder uri = new StringBuilder(128);
        if (mData != null) uri.append(mData.toString());
        String scheme = null;
        if (mData != null) {
            String data = mData.toString();
            if ((flags&URI_INTENT_SCHEME) != 0) {
                final int N = data.length();
                for (int i=0; i<N; i++) {
                    char c = data.charAt(i);
                    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
                            || c == '.' || c == '-') {
                        continue;
                    }
                    if (c == ':' && i > 0) {
                        // Valid scheme.
                        scheme = data.substring(0, i);
                        uri.append("intent:");
                        data = data.substring(i+1);
                        break;
                    }
                    
                    // No scheme.
                    break;
                }
            }
            uri.append(data);
            
        } else if ((flags&URI_INTENT_SCHEME) != 0) {
            uri.append("intent:");
        }

        uri.append("#Intent;");

        if (scheme != null) {
            uri.append("scheme=").append(scheme).append(';');
        }
        if (mAction != null) {
            uri.append("action=").append(mAction).append(';');
            uri.append("action=").append(Uri.encode(mAction)).append(';');
        }
        if (mCategories != null) {
            for (String category : mCategories) {
                uri.append("category=").append(category).append(';');
                uri.append("category=").append(Uri.encode(category)).append(';');
            }
        }
        if (mType != null) {
            uri.append("type=").append(mType).append(';');
            uri.append("type=").append(Uri.encode(mType, "/")).append(';');
        }
        if (mFlags != 0) {
            uri.append("launchFlags=0x").append(Integer.toHexString(mFlags)).append(';');
        }
        if (mPackage != null) {
            uri.append("package=").append(Uri.encode(mPackage)).append(';');
        }
        if (mComponent != null) {
            uri.append("component=").append(mComponent.flattenToShortString()).append(';');
            uri.append("component=").append(Uri.encode(
                    mComponent.flattenToShortString(), "/")).append(';');
        }
        if (mExtras != null) {
            for (String key : mExtras.keySet()) {
@@ -4590,6 +4791,7 @@ public class Intent implements Parcelable {
        Uri.writeToParcel(out, mData);
        out.writeString(mType);
        out.writeInt(mFlags);
        out.writeString(mPackage);
        ComponentName.writeToParcel(mComponent, out);

        if (mCategories != null) {
@@ -4623,6 +4825,7 @@ public class Intent implements Parcelable {
        mData = Uri.CREATOR.createFromParcel(in);
        mType = in.readString();
        mFlags = in.readInt();
        mPackage = in.readString();
        mComponent = ComponentName.readFromParcel(in);

        int N = in.readInt();
+0 −3
Original line number Diff line number Diff line
@@ -82,9 +82,6 @@ interface IPackageManager {
    
    ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags);

    ResolveInfo resolveIntentForPackage(in Intent intent, String resolvedType, int flags,
            String packageName);

    List<ResolveInfo> queryIntentActivities(in Intent intent, 
            String resolvedType, int flags);

+0 −17
Original line number Diff line number Diff line
@@ -985,23 +985,6 @@ public abstract class PackageManager {
     */
    public abstract ResolveInfo resolveActivity(Intent intent, int flags);

    /**
     * Resolve the intent restricted to a package.
     * {@see #resolveActivity}
     *
     * @param intent An intent containing all of the desired specification
     *               (action, data, type, category, and/or component).
     * @param flags Additional option flags.  The most important is
     *                    MATCH_DEFAULT_ONLY, to limit the resolution to only
     *                    those activities that support the CATEGORY_DEFAULT.
     * @param packageName Restrict the intent resolution to this package.
     *
     * @return Returns a ResolveInfo containing the final activity intent that
     *         was determined to be the best action.  Returns null if no
     *         matching activity was found.
     */
    public abstract ResolveInfo resolveActivity(Intent intent, int flags, String packageName);

    /**
     * Retrieve all activities that can be performed for the given intent.
     *
Loading