Merge "Show package icon/label for resolved package-targeted implicit intents" into nyc-dev
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index ed6ab56..a5b2a91 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -825,13 +825,31 @@
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 41a563c..b6c269e 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 @@
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 @@
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<ResolveInfo> 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<ResolveInfo> query, boolean debug, int userId) {
final int N = query.size();