Allow intent resolution to be constrained by package name.
This commit is contained in:
@@ -33321,8 +33321,6 @@
|
|||||||
>
|
>
|
||||||
<parameter name="packageName" type="java.lang.String">
|
<parameter name="packageName" type="java.lang.String">
|
||||||
</parameter>
|
</parameter>
|
||||||
<exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
|
|
||||||
</exception>
|
|
||||||
</method>
|
</method>
|
||||||
<method name="getNameForUid"
|
<method name="getNameForUid"
|
||||||
return="java.lang.String"
|
return="java.lang.String"
|
||||||
@@ -33750,6 +33748,23 @@
|
|||||||
<parameter name="flags" type="int">
|
<parameter name="flags" type="int">
|
||||||
</parameter>
|
</parameter>
|
||||||
</method>
|
</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"
|
<method name="resolveContentProvider"
|
||||||
return="android.content.pm.ProviderInfo"
|
return="android.content.pm.ProviderInfo"
|
||||||
abstract="true"
|
abstract="true"
|
||||||
@@ -111816,8 +111831,6 @@
|
|||||||
>
|
>
|
||||||
<parameter name="packageName" type="java.lang.String">
|
<parameter name="packageName" type="java.lang.String">
|
||||||
</parameter>
|
</parameter>
|
||||||
<exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
|
|
||||||
</exception>
|
|
||||||
</method>
|
</method>
|
||||||
<method name="getNameForUid"
|
<method name="getNameForUid"
|
||||||
return="java.lang.String"
|
return="java.lang.String"
|
||||||
@@ -112227,6 +112240,23 @@
|
|||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="flags" type="int">
|
<parameter name="flags" type="int">
|
||||||
</parameter>
|
</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>
|
||||||
<method name="resolveContentProvider"
|
<method name="resolveContentProvider"
|
||||||
return="android.content.pm.ProviderInfo"
|
return="android.content.pm.ProviderInfo"
|
||||||
|
|||||||
@@ -1519,43 +1519,31 @@ class ApplicationContext extends Context {
|
|||||||
throw new NameNotFoundException(packageName);
|
throw new NameNotFoundException(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Intent getLaunchIntentForPackage(String packageName)
|
@Override
|
||||||
throws NameNotFoundException {
|
public Intent getLaunchIntentForPackage(String packageName) {
|
||||||
// First see if the package has an INFO activity; the existence of
|
// 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
|
// such an activity is implied to be the desired front-door for the
|
||||||
// overall package (such as if it has multiple launcher entries).
|
// overall package (such as if it has multiple launcher entries).
|
||||||
Intent intent = getLaunchIntentForPackageCategory(this, packageName,
|
Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
|
||||||
Intent.CATEGORY_INFO);
|
intentToResolve.addCategory(Intent.CATEGORY_INFO);
|
||||||
if (intent != null) {
|
ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0, packageName);
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, try to find a main launcher activity.
|
// Otherwise, try to find a main launcher activity.
|
||||||
return getLaunchIntentForPackageCategory(this, packageName,
|
if (resolveInfo == null) {
|
||||||
Intent.CATEGORY_LAUNCHER);
|
// reuse the intent instance
|
||||||
}
|
intentToResolve.removeCategory(Intent.CATEGORY_INFO);
|
||||||
|
intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||||
// XXX This should be implemented as a call to the package manager,
|
resolveInfo = resolveActivity(intentToResolve, 0, packageName);
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
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
|
@Override
|
||||||
public int[] getPackageGids(String packageName)
|
public int[] getPackageGids(String packageName)
|
||||||
throws NameNotFoundException {
|
throws NameNotFoundException {
|
||||||
@@ -1792,6 +1780,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
|
@Override
|
||||||
public List<ResolveInfo> queryIntentActivities(Intent intent,
|
public List<ResolveInfo> queryIntentActivities(Intent intent,
|
||||||
int flags) {
|
int flags) {
|
||||||
|
|||||||
@@ -81,6 +81,9 @@ interface IPackageManager {
|
|||||||
|
|
||||||
ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags);
|
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,
|
List<ResolveInfo> queryIntentActivities(in Intent intent,
|
||||||
String resolvedType, int flags);
|
String resolvedType, int flags);
|
||||||
|
|
||||||
|
|||||||
@@ -563,9 +563,8 @@ public abstract class PackageManager {
|
|||||||
* launch the main activity in the package, or null if the package does
|
* launch the main activity in the package, or null if the package does
|
||||||
* not contain such an activity.
|
* not contain such an activity.
|
||||||
*/
|
*/
|
||||||
public abstract Intent getLaunchIntentForPackage(String packageName)
|
public abstract Intent getLaunchIntentForPackage(String packageName);
|
||||||
throws NameNotFoundException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an array of all of the secondary group-ids that have been
|
* Return an array of all of the secondary group-ids that have been
|
||||||
* assigned to a package.
|
* assigned to a package.
|
||||||
@@ -970,6 +969,23 @@ public abstract class PackageManager {
|
|||||||
*/
|
*/
|
||||||
public abstract ResolveInfo resolveActivity(Intent intent, int flags);
|
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.
|
* Retrieve all activities that can be performed for the given intent.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -163,6 +163,23 @@ public class IntentResolver<F extends IntentFilter, R extends Object> {
|
|||||||
return Collections.unmodifiableSet(mFilters);
|
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,
|
public List<R> queryIntent(ContentResolver resolver, Intent intent,
|
||||||
String resolvedType, boolean defaultOnly) {
|
String resolvedType, boolean defaultOnly) {
|
||||||
String scheme = intent.getScheme();
|
String scheme = intent.getScheme();
|
||||||
|
|||||||
@@ -1203,6 +1203,33 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
|
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
|
||||||
int flags) {
|
int flags) {
|
||||||
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, 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) {
|
if (query != null) {
|
||||||
final int N = query.size();
|
final int N = query.size();
|
||||||
if (N == 1) {
|
if (N == 1) {
|
||||||
@@ -2853,6 +2880,22 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
(flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
|
(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) {
|
public final void addActivity(PackageParser.Activity a, String type) {
|
||||||
mActivities.put(a.component, a);
|
mActivities.put(a.component, a);
|
||||||
if (SHOW_INFO || Config.LOGV) Log.v(
|
if (SHOW_INFO || Config.LOGV) Log.v(
|
||||||
@@ -2860,8 +2903,7 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
(a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
|
(a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
|
||||||
if (SHOW_INFO || Config.LOGV) Log.v(TAG, " Class=" + a.info.name);
|
if (SHOW_INFO || Config.LOGV) Log.v(TAG, " Class=" + a.info.name);
|
||||||
int NI = a.intents.size();
|
int NI = a.intents.size();
|
||||||
int j;
|
for (int j=0; j<NI; j++) {
|
||||||
for (j=0; j<NI; j++) {
|
|
||||||
PackageParser.ActivityIntentInfo intent = a.intents.get(j);
|
PackageParser.ActivityIntentInfo intent = a.intents.get(j);
|
||||||
if (SHOW_INFO || Config.LOGV) {
|
if (SHOW_INFO || Config.LOGV) {
|
||||||
Log.v(TAG, " IntentFilter:");
|
Log.v(TAG, " IntentFilter:");
|
||||||
@@ -2881,8 +2923,7 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
(a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
|
(a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
|
||||||
if (SHOW_INFO || Config.LOGV) Log.v(TAG, " Class=" + a.info.name);
|
if (SHOW_INFO || Config.LOGV) Log.v(TAG, " Class=" + a.info.name);
|
||||||
int NI = a.intents.size();
|
int NI = a.intents.size();
|
||||||
int j;
|
for (int j=0; j<NI; j++) {
|
||||||
for (j=0; j<NI; j++) {
|
|
||||||
PackageParser.ActivityIntentInfo intent = a.intents.get(j);
|
PackageParser.ActivityIntentInfo intent = a.intents.get(j);
|
||||||
if (SHOW_INFO || Config.LOGV) {
|
if (SHOW_INFO || Config.LOGV) {
|
||||||
Log.v(TAG, " IntentFilter:");
|
Log.v(TAG, " IntentFilter:");
|
||||||
|
|||||||
@@ -57,11 +57,15 @@ public class MockPackageManager extends PackageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Intent getLaunchIntentForPackage(String packageName)
|
public Intent getLaunchIntentForPackage(String packageName) {
|
||||||
throws NameNotFoundException {
|
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResolveInfo resolveActivity(Intent intent, int flags, String packageName) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] getPackageGids(String packageName) throws NameNotFoundException {
|
public int[] getPackageGids(String packageName) throws NameNotFoundException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|||||||
Reference in New Issue
Block a user