am eae850ce: Allow intent resolution to be constrained by package name.

Merge commit 'eae850cefe7e149f396c9e8ca1f34ec02b20a3f0'

* commit 'eae850cefe7e149f396c9e8ca1f34ec02b20a3f0':
  Allow intent resolution to be constrained by package name.
This commit is contained in:
Mihai Preda
2009-05-15 07:06:46 -07:00
committed by The Android Open Source Project
7 changed files with 157 additions and 45 deletions

View File

@ -36138,8 +36138,6 @@
>
<parameter name="packageName" type="java.lang.String">
</parameter>
<exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
</exception>
</method>
<method name="getNameForUid"
return="java.lang.String"
@ -36567,6 +36565,23 @@
<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"
@ -114689,8 +114704,6 @@
>
<parameter name="packageName" type="java.lang.String">
</parameter>
<exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
</exception>
</method>
<method name="getNameForUid"
return="java.lang.String"
@ -115100,6 +115113,23 @@
</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

@ -1535,42 +1535,30 @@ class ApplicationContext extends Context {
throw new NameNotFoundException(packageName);
}
public Intent getLaunchIntentForPackage(String packageName)
throws NameNotFoundException {
@Override
public Intent getLaunchIntentForPackage(String packageName) {
// First see if the package has an INFO activity; the existence of
// such an activity is implied to be the desired front-door for the
// overall package (such as if it has multiple launcher entries).
Intent intent = getLaunchIntentForPackageCategory(this, packageName,
Intent.CATEGORY_INFO);
if (intent != null) {
return intent;
}
Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
intentToResolve.addCategory(Intent.CATEGORY_INFO);
ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0, packageName);
// Otherwise, try to find a main launcher activity.
return getLaunchIntentForPackageCategory(this, packageName,
Intent.CATEGORY_LAUNCHER);
}
// XXX This should be implemented as a call to the package manager,
// to reduce the work needed.
static Intent getLaunchIntentForPackageCategory(PackageManager pm,
String packageName, String category) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent intentToResolve = new Intent(Intent.ACTION_MAIN, null);
intentToResolve.addCategory(category);
final List<ResolveInfo> apps =
pm.queryIntentActivities(intentToResolve, 0);
// I wish there were a way to directly get the "main" activity of a
// package but ...
for (ResolveInfo app : apps) {
if (app.activityInfo.packageName.equals(packageName)) {
intent.setClassName(packageName, app.activityInfo.name);
return intent;
}
if (resolveInfo == null) {
// reuse the intent instance
intentToResolve.removeCategory(Intent.CATEGORY_INFO);
intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
resolveInfo = resolveActivity(intentToResolve, 0, packageName);
}
if (resolveInfo == null) {
return null;
}
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName(packageName, resolveInfo.activityInfo.name);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return intent;
}
@Override
public int[] getPackageGids(String packageName)
@ -1808,6 +1796,19 @@ 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

@ -81,6 +81,9 @@ 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

@ -563,8 +563,7 @@ public abstract class PackageManager {
* launch the main activity in the package, or null if the package does
* not contain such an activity.
*/
public abstract Intent getLaunchIntentForPackage(String packageName)
throws NameNotFoundException;
public abstract Intent getLaunchIntentForPackage(String packageName);
/**
* Return an array of all of the secondary group-ids that have been
@ -970,6 +969,23 @@ 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

@ -163,6 +163,23 @@ public class IntentResolver<F extends IntentFilter, R extends Object> {
return Collections.unmodifiableSet(mFilters);
}
public List<R> queryIntentFromList(Intent intent, String resolvedType,
boolean defaultOnly, ArrayList<ArrayList<F>> listCut) {
ArrayList<R> resultList = new ArrayList<R>();
final boolean debug = localLOGV ||
((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
final String scheme = intent.getScheme();
int N = listCut.size();
for (int i = 0; i < N; ++i) {
buildResolveList(intent, debug, defaultOnly,
resolvedType, scheme, listCut.get(i), resultList);
}
sortResults(resultList);
return resultList;
}
public List<R> queryIntent(ContentResolver resolver, Intent intent,
String resolvedType, boolean defaultOnly) {
String scheme = intent.getScheme();

View File

@ -1203,6 +1203,33 @@ class PackageManagerService extends IPackageManager.Stub {
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags) {
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags);
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) {
final int N = query.size();
if (N == 1) {
@ -2856,6 +2883,22 @@ class PackageManagerService extends IPackageManager.Stub {
(flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
}
public List queryIntentForPackage(Intent intent, String resolvedType, int flags,
ArrayList<PackageParser.Activity> packageActivities) {
if (packageActivities == null) {
return null;
}
mFlags = flags;
final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
int N = packageActivities.size();
ArrayList<ArrayList<PackageParser.ActivityIntentInfo>> listCut =
new ArrayList<ArrayList<PackageParser.ActivityIntentInfo>>(N);
for (int i = 0; i < N; ++i) {
listCut.add(packageActivities.get(i).intents);
}
return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut);
}
public final void addActivity(PackageParser.Activity a, String type) {
mActivities.put(a.component, a);
if (SHOW_INFO || Config.LOGV) Log.v(
@ -2863,8 +2906,7 @@ class PackageManagerService extends IPackageManager.Stub {
(a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
if (SHOW_INFO || Config.LOGV) Log.v(TAG, " Class=" + a.info.name);
int NI = a.intents.size();
int j;
for (j=0; j<NI; j++) {
for (int j=0; j<NI; j++) {
PackageParser.ActivityIntentInfo intent = a.intents.get(j);
if (SHOW_INFO || Config.LOGV) {
Log.v(TAG, " IntentFilter:");
@ -2884,8 +2926,7 @@ class PackageManagerService extends IPackageManager.Stub {
(a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
if (SHOW_INFO || Config.LOGV) Log.v(TAG, " Class=" + a.info.name);
int NI = a.intents.size();
int j;
for (j=0; j<NI; j++) {
for (int j=0; j<NI; j++) {
PackageParser.ActivityIntentInfo intent = a.intents.get(j);
if (SHOW_INFO || Config.LOGV) {
Log.v(TAG, " IntentFilter:");

View File

@ -57,8 +57,12 @@ public class MockPackageManager extends PackageManager {
}
@Override
public Intent getLaunchIntentForPackage(String packageName)
throws NameNotFoundException {
public Intent getLaunchIntentForPackage(String packageName) {
throw new UnsupportedOperationException();
}
@Override
public ResolveInfo resolveActivity(Intent intent, int flags, String packageName) {
throw new UnsupportedOperationException();
}