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();