From eae850cefe7e149f396c9e8ca1f34ec02b20a3f0 Mon Sep 17 00:00:00 2001 From: Mihai Preda Date: Wed, 13 May 2009 10:13:48 +0200 Subject: Allow intent resolution to be constrained by package name. --- core/java/android/app/ApplicationContext.java | 61 ++++++++++++----------- core/java/android/content/pm/IPackageManager.aidl | 3 ++ core/java/android/content/pm/PackageManager.java | 22 ++++++-- 3 files changed, 53 insertions(+), 33 deletions(-) (limited to 'core') 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 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 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 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(). -- cgit v1.1