summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml38
-rw-r--r--core/java/android/app/ApplicationContext.java61
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl3
-rw-r--r--core/java/android/content/pm/PackageManager.java22
-rw-r--r--services/java/com/android/server/IntentResolver.java17
-rw-r--r--services/java/com/android/server/PackageManagerService.java49
-rw-r--r--test-runner/android/test/mock/MockPackageManager.java10
7 files changed, 156 insertions, 44 deletions
diff --git a/api/current.xml b/api/current.xml
index c03526d..7d55a7d 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -33321,8 +33321,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"
@@ -33750,6 +33748,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"
@@ -111816,8 +111831,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"
@@ -112227,6 +112240,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"
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 81e894f..2c2310a 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -1519,43 +1519,31 @@ 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) {
+ 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);
- 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;
+ return intent;
}
-
+
@Override
public int[] getPackageGids(String packageName)
throws NameNotFoundException {
@@ -1793,6 +1781,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) {
try {
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c199619..bb913cd 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -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);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 3a192f7..eecbce4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -563,9 +563,8 @@ 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
* assigned to a package.
@@ -971,6 +970,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.
*
* @param intent The desired intent as per resolveActivity().
diff --git a/services/java/com/android/server/IntentResolver.java b/services/java/com/android/server/IntentResolver.java
index 72efca5..53e63c2 100644
--- a/services/java/com/android/server/IntentResolver.java
+++ b/services/java/com/android/server/IntentResolver.java
@@ -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();
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 079f363..4ce40b6 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -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) {
@@ -2853,6 +2880,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(
@@ -2860,8 +2903,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:");
@@ -2881,8 +2923,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:");
diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java
index bf1629f..73ae3b9 100644
--- a/test-runner/android/test/mock/MockPackageManager.java
+++ b/test-runner/android/test/mock/MockPackageManager.java
@@ -57,11 +57,15 @@ 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();
+ }
+
@Override
public int[] getPackageGids(String packageName) throws NameNotFoundException {
throw new UnsupportedOperationException();