Extend Intent/Uri conversion for use by Browser

This introduces a new Uri form of Intent with an "intent:" scheme, and a
corresponding update to the parser to handle these, so that the browser
can use this generic facility for starting activities based on the links
that are clicked and allow for web pages to link to arbitrary intents.

There is also a new "package" field on Intent which allows you to limit
the components it finds to a given package.  This replaces the new method
that was added to PackageManger for doing this when resolving activities,
and implements it for all Intent queries against the package manager.
This commit is contained in:
Dianne Hackborn
2009-06-17 18:02:12 -07:00
parent e64bb1dd9e
commit c14b9ccdf1
8 changed files with 380 additions and 131 deletions

View File

@ -30186,7 +30186,7 @@
synchronized="false"
static="true"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<parameter name="uri" type="java.lang.String">
@ -30237,6 +30237,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"
@ -30436,6 +30447,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"
@ -31109,6 +31137,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"
@ -31123,6 +31164,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"
@ -31132,6 +31184,8 @@
deprecated="not deprecated"
visibility="public"
>
<parameter name="flags" type="int">
</parameter>
</method>
<method name="writeToParcel"
return="void"
@ -32500,6 +32554,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"
@ -32709,6 +32774,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"
@ -36910,23 +36986,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"
@ -115702,23 +115761,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"

View File

@ -1519,14 +1519,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;
@ -1773,19 +1775,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) {

View File

@ -2039,11 +2039,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;
@ -2064,6 +2079,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) {
@ -2083,6 +2099,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);
@ -2182,24 +2199,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));
@ -2211,16 +2255,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)) {
@ -2242,15 +2285,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;
@ -2271,6 +2323,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) {
@ -3083,6 +3152,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,
@ -3118,6 +3201,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.
*
@ -4088,6 +4174,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
@ -4199,6 +4306,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
@ -4210,14 +4323,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"}
@ -4233,32 +4347,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;
}
@ -4373,6 +4494,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)) {
@ -4418,6 +4550,9 @@ public class Intent implements Parcelable {
if (mType != null) {
code += mType.hashCode();
}
if (mPackage != null) {
code += mPackage.hashCode();
}
if (mComponent != null) {
code += mComponent.hashCode();
}
@ -4488,6 +4623,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(' ');
@ -4504,28 +4646,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()) {
@ -4567,6 +4768,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) {
@ -4600,6 +4802,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();

View File

@ -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);

View File

@ -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.
*

View File

@ -1269,28 +1269,6 @@ class PackageManagerService extends IPackageManager.Stub {
return chooseBestActivity(intent, resolvedType, flags, query);
}
public ResolveInfo resolveIntentForPackage(Intent intent, String resolvedType,
int flags, String packageName) {
ComponentName comp = intent.getComponent();
if (comp != null) {
// if this is an explicit intent, it must have the same the packageName
if (packageName.equals(comp.getPackageName())) {
return resolveIntent(intent, resolvedType, flags);
}
return null;
} else {
List<ResolveInfo> query = null;
synchronized (mPackages) {
PackageParser.Package pkg = mPackages.get(packageName);
if (pkg != null) {
query = (List<ResolveInfo>) mActivities.
queryIntentForPackage(intent, resolvedType, flags, pkg.activities);
}
}
return chooseBestActivity(intent, resolvedType, flags, query);
}
}
private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
int flags, List<ResolveInfo> query) {
if (query != null) {
@ -1409,8 +1387,17 @@ class PackageManagerService extends IPackageManager.Stub {
}
synchronized (mPackages) {
return (List<ResolveInfo>)mActivities.
queryIntent(intent, resolvedType, flags);
String pkgName = intent.getPackage();
if (pkgName == null) {
return (List<ResolveInfo>)mActivities.queryIntent(intent,
resolvedType, flags);
}
PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return (List<ResolveInfo>) mActivities.queryIntentForPackage(intent,
resolvedType, flags, pkg.activities);
}
return null;
}
}
@ -1577,9 +1564,30 @@ class PackageManagerService extends IPackageManager.Stub {
public List<ResolveInfo> queryIntentReceivers(Intent intent,
String resolvedType, int flags) {
ComponentName comp = intent.getComponent();
if (comp != null) {
List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
ActivityInfo ai = getReceiverInfo(comp, flags);
if (ai != null) {
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
list.add(ri);
}
return list;
}
synchronized (mPackages) {
return (List<ResolveInfo>)mReceivers.
queryIntent(intent, resolvedType, flags);
String pkgName = intent.getPackage();
if (pkgName == null) {
return (List<ResolveInfo>)mReceivers.queryIntent(intent,
resolvedType, flags);
}
PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return (List<ResolveInfo>) mReceivers.queryIntentForPackage(intent,
resolvedType, flags, pkg.receivers);
}
return null;
}
}
@ -1612,7 +1620,17 @@ class PackageManagerService extends IPackageManager.Stub {
}
synchronized (mPackages) {
return (List<ResolveInfo>)mServices.queryIntent(intent, resolvedType, flags);
String pkgName = intent.getPackage();
if (pkgName == null) {
return (List<ResolveInfo>)mServices.queryIntent(intent,
resolvedType, flags);
}
PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return (List<ResolveInfo>)mServices.queryIntentForPackage(intent,
resolvedType, flags, pkg.services);
}
return null;
}
}
@ -3106,6 +3124,27 @@ class PackageManagerService extends IPackageManager.Stub {
(flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
}
public List queryIntentForPackage(Intent intent, String resolvedType, int flags,
ArrayList<PackageParser.Service> packageServices) {
if (packageServices == null) {
return null;
}
mFlags = flags;
final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
int N = packageServices.size();
ArrayList<ArrayList<PackageParser.ServiceIntentInfo>> listCut =
new ArrayList<ArrayList<PackageParser.ServiceIntentInfo>>(N);
ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
for (int i = 0; i < N; ++i) {
intentFilters = packageServices.get(i).intents;
if (intentFilters != null && intentFilters.size() > 0) {
listCut.add(intentFilters);
}
}
return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut);
}
public final void addService(PackageParser.Service s) {
mServices.put(s.component, s);
if (SHOW_INFO || Config.LOGV) Log.v(

View File

@ -7904,7 +7904,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
// is there an Activity in this package that handles ACTION_APP_ERROR?
Intent intent = new Intent(Intent.ACTION_APP_ERROR);
ResolveInfo info = pm.resolveIntentForPackage(intent, null, 0, installerPackageName);
intent.setPackage(installerPackageName);
ResolveInfo info = pm.resolveIntent(intent, null, 0);
if (info == null || info.activityInfo == null) {
return null;
}

View File

@ -62,11 +62,6 @@ public class MockPackageManager extends PackageManager {
throw new UnsupportedOperationException();
}
@Override
public ResolveInfo resolveActivity(Intent intent, int flags, String packageName) {
throw new UnsupportedOperationException();
}
@Override
public int[] getPackageGids(String packageName) throws NameNotFoundException {
throw new UnsupportedOperationException();