diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index ed6ab5674d719..a5b2a9194fd51 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -825,13 +825,31 @@ public class ChooserActivity extends ResolverActivity { if (ii == null) { continue; } - final ActivityInfo ai = ii.resolveActivityInfo(pm, 0); + + // We reimplement Intent#resolveActivityInfo here because if we have an + // implicit intent, we want the ResolveInfo returned by PackageManager + // instead of one we reconstruct ourselves. The ResolveInfo returned might + // have extra metadata and resolvePackageName set and we want to respect that. + ResolveInfo ri = null; + ActivityInfo ai = null; + final ComponentName cn = ii.getComponent(); + if (cn != null) { + try { + ai = pm.getActivityInfo(ii.getComponent(), 0); + ri = new ResolveInfo(); + ri.activityInfo = ai; + } catch (PackageManager.NameNotFoundException ignored) { + // ai will == null below + } + } + if (ai == null) { + ri = pm.resolveActivity(ii, PackageManager.MATCH_DEFAULT_ONLY); + ai = ri != null ? ri.activityInfo : null; + } if (ai == null) { Log.w(TAG, "No activity found for " + ii); continue; } - ResolveInfo ri = new ResolveInfo(); - ri.activityInfo = ai; UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE); if (ii instanceof LabeledIntent) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 41a563c098b0b..b6c269ecf627f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -5011,6 +5011,25 @@ public class PackageManagerService extends IPackageManager.Stub { ri = new ResolveInfo(mResolveInfo); ri.activityInfo = new ActivityInfo(ri.activityInfo); ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); + // If all of the options come from the same package, show the application's + // label and icon instead of the generic resolver's. + // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here + // and then throw away the ResolveInfo itself, meaning that the caller loses + // the resolvePackageName. Therefore the activityInfo.labelRes above provides + // a fallback for this case; we only set the target package's resources on + // the ResolveInfo, not the ActivityInfo. + final String intentPackage = intent.getPackage(); + if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) { + final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo; + ri.resolvePackageName = intentPackage; + if (userNeedsBadging(userId)) { + ri.noResourceId = true; + } else { + ri.icon = appi.icon; + } + ri.iconResourceId = appi.icon; + ri.labelRes = appi.labelRes; + } ri.activityInfo.applicationInfo = new ApplicationInfo( ri.activityInfo.applicationInfo); if (userId != 0) { @@ -5026,6 +5045,24 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } + /** + * Return true if the given list is not empty and all of its contents have + * an activityInfo with the given package name. + */ + private boolean allHavePackage(List list, String packageName) { + if (ArrayUtils.isEmpty(list)) { + return false; + } + for (int i = 0, N = list.size(); i < N; i++) { + final ResolveInfo ri = list.get(i); + final ActivityInfo ai = ri != null ? ri.activityInfo : null; + if (ai == null || !packageName.equals(ai.packageName)) { + return false; + } + } + return true; + } + private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List query, boolean debug, int userId) { final int N = query.size();