diff --git a/api/current.xml b/api/current.xml index c03526d064651..7d55a7d043a22 100644 --- a/api/current.xml +++ b/api/current.xml @@ -33321,8 +33321,6 @@ > - - + + + + + + + + - - + + + + + + + + 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); } - 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 public int[] getPackageGids(String packageName) 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 public List queryIntentActivities(Intent intent, int flags) { diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index c199619c57a92..bb913cdca90c1 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 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 3a192f7eb7493..eecbce4fa23b3 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. @@ -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. * diff --git a/services/java/com/android/server/IntentResolver.java b/services/java/com/android/server/IntentResolver.java index 72efca5eb4b9e..53e63c272c729 100644 --- a/services/java/com/android/server/IntentResolver.java +++ b/services/java/com/android/server/IntentResolver.java @@ -163,6 +163,23 @@ public class IntentResolver { return Collections.unmodifiableSet(mFilters); } + public List queryIntentFromList(Intent intent, String resolvedType, + boolean defaultOnly, ArrayList> listCut) { + ArrayList resultList = new ArrayList(); + + 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 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 079f363b5fc87..4ce40b62ef499 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 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 query = null; + synchronized (mPackages) { + PackageParser.Package pkg = mPackages.get(packageName); + if (pkg != null) { + query = (List) mActivities. + queryIntentForPackage(intent, resolvedType, flags, pkg.activities); + } + } + return chooseBestActivity(intent, resolvedType, flags, query); + } + } + + private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, + int flags, List 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 packageActivities) { + if (packageActivities == null) { + return null; + } + mFlags = flags; + final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; + int N = packageActivities.size(); + ArrayList> listCut = + new ArrayList>(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