1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.content.pm; 18 19 import android.content.IntentFilter; 20 import android.graphics.drawable.Drawable; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.text.TextUtils; 24 import android.util.Printer; 25 26 import java.text.Collator; 27 import java.util.Comparator; 28 29 /** 30 * Information that is returned from resolving an intent 31 * against an IntentFilter. This partially corresponds to 32 * information collected from the AndroidManifest.xml's 33 * <intent> tags. 34 */ 35 public class ResolveInfo implements Parcelable { 36 /** 37 * The activity that corresponds to this resolution match, if this 38 * resolution is for an activity. One and only one of this and 39 * serviceInfo must be non-null. 40 */ 41 public ActivityInfo activityInfo; 42 43 /** 44 * The service that corresponds to this resolution match, if this 45 * resolution is for a service. One and only one of this and 46 * activityInfo must be non-null. 47 */ 48 public ServiceInfo serviceInfo; 49 50 /** 51 * The IntentFilter that was matched for this ResolveInfo. 52 */ 53 public IntentFilter filter; 54 55 /** 56 * The declared priority of this match. Comes from the "priority" 57 * attribute or, if not set, defaults to 0. Higher values are a higher 58 * priority. 59 */ 60 public int priority; 61 62 /** 63 * Order of result according to the user's preference. If the user 64 * has not set a preference for this result, the value is 0; higher 65 * values are a higher priority. 66 */ 67 public int preferredOrder; 68 69 /** 70 * The system's evaluation of how well the activity matches the 71 * IntentFilter. This is a match constant, a combination of 72 * {@link IntentFilter#MATCH_CATEGORY_MASK IntentFilter.MATCH_CATEGORY_MASK} 73 * and {@link IntentFilter#MATCH_ADJUSTMENT_MASK IntentFiler.MATCH_ADJUSTMENT_MASK}. 74 */ 75 public int match; 76 77 /** 78 * Only set when returned by 79 * {@link PackageManager#queryIntentActivityOptions}, this tells you 80 * which of the given specific intents this result came from. 0 is the 81 * first in the list, < 0 means it came from the generic Intent query. 82 */ 83 public int specificIndex = -1; 84 85 /** 86 * This filter has specified the Intent.CATEGORY_DEFAULT, meaning it 87 * would like to be considered a default action that the user can 88 * perform on this data. 89 */ 90 public boolean isDefault; 91 92 /** 93 * A string resource identifier (in the package's resources) of this 94 * match's label. From the "label" attribute or, if not set, 0. 95 */ 96 public int labelRes; 97 98 /** 99 * The actual string retrieve from <var>labelRes</var> or null if none 100 * was provided. 101 */ 102 public CharSequence nonLocalizedLabel; 103 104 /** 105 * A drawable resource identifier (in the package's resources) of this 106 * match's icon. From the "icon" attribute or, if not set, 0. 107 */ 108 public int icon; 109 110 /** 111 * Optional -- if non-null, the {@link #labelRes} and {@link #icon} 112 * resources will be loaded from this package, rather than the one 113 * containing the resolved component. 114 */ 115 public String resolvePackageName; 116 117 /** 118 * @hide Target comes from system process? 119 */ 120 public boolean system; 121 122 /** 123 * Retrieve the current textual label associated with this resolution. This 124 * will call back on the given PackageManager to load the label from 125 * the application. 126 * 127 * @param pm A PackageManager from which the label can be loaded; usually 128 * the PackageManager from which you originally retrieved this item. 129 * 130 * @return Returns a CharSequence containing the resolutions's label. If the 131 * item does not have a label, its name is returned. 132 */ loadLabel(PackageManager pm)133 public CharSequence loadLabel(PackageManager pm) { 134 if (nonLocalizedLabel != null) { 135 return nonLocalizedLabel; 136 } 137 CharSequence label; 138 if (resolvePackageName != null && labelRes != 0) { 139 label = pm.getText(resolvePackageName, labelRes, null); 140 if (label != null) { 141 return label.toString().trim(); 142 } 143 } 144 ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo; 145 ApplicationInfo ai = ci.applicationInfo; 146 if (labelRes != 0) { 147 label = pm.getText(ci.packageName, labelRes, ai); 148 if (label != null) { 149 return label.toString().trim(); 150 } 151 } 152 153 CharSequence data = ci.loadLabel(pm); 154 // Make the data safe 155 if (data != null) data = data.toString().trim(); 156 return data; 157 } 158 159 /** 160 * Retrieve the current graphical icon associated with this resolution. This 161 * will call back on the given PackageManager to load the icon from 162 * the application. 163 * 164 * @param pm A PackageManager from which the icon can be loaded; usually 165 * the PackageManager from which you originally retrieved this item. 166 * 167 * @return Returns a Drawable containing the resolution's icon. If the 168 * item does not have an icon, the default activity icon is returned. 169 */ loadIcon(PackageManager pm)170 public Drawable loadIcon(PackageManager pm) { 171 Drawable dr; 172 if (resolvePackageName != null && icon != 0) { 173 dr = pm.getDrawable(resolvePackageName, icon, null); 174 if (dr != null) { 175 return dr; 176 } 177 } 178 ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo; 179 ApplicationInfo ai = ci.applicationInfo; 180 if (icon != 0) { 181 dr = pm.getDrawable(ci.packageName, icon, ai); 182 if (dr != null) { 183 return dr; 184 } 185 } 186 return ci.loadIcon(pm); 187 } 188 189 /** 190 * Return the icon resource identifier to use for this match. If the 191 * match defines an icon, that is used; else if the activity defines 192 * an icon, that is used; else, the application icon is used. 193 * 194 * @return The icon associated with this match. 195 */ getIconResource()196 public final int getIconResource() { 197 if (icon != 0) return icon; 198 if (activityInfo != null) return activityInfo.getIconResource(); 199 if (serviceInfo != null) return serviceInfo.getIconResource(); 200 return 0; 201 } 202 dump(Printer pw, String prefix)203 public void dump(Printer pw, String prefix) { 204 if (filter != null) { 205 pw.println(prefix + "Filter:"); 206 filter.dump(pw, prefix + " "); 207 } 208 pw.println(prefix + "priority=" + priority 209 + " preferredOrder=" + preferredOrder 210 + " match=0x" + Integer.toHexString(match) 211 + " specificIndex=" + specificIndex 212 + " isDefault=" + isDefault); 213 if (resolvePackageName != null) { 214 pw.println(prefix + "resolvePackageName=" + resolvePackageName); 215 } 216 if (labelRes != 0 || nonLocalizedLabel != null || icon != 0) { 217 pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes) 218 + " nonLocalizedLabel=" + nonLocalizedLabel 219 + " icon=0x" + Integer.toHexString(icon)); 220 } 221 if (activityInfo != null) { 222 pw.println(prefix + "ActivityInfo:"); 223 activityInfo.dump(pw, prefix + " "); 224 } else if (serviceInfo != null) { 225 pw.println(prefix + "ServiceInfo:"); 226 serviceInfo.dump(pw, prefix + " "); 227 } 228 } 229 ResolveInfo()230 public ResolveInfo() { 231 } 232 toString()233 public String toString() { 234 ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo; 235 return "ResolveInfo{" 236 + Integer.toHexString(System.identityHashCode(this)) 237 + " " + ci.name + " p=" + priority + " o=" 238 + preferredOrder + " m=0x" + Integer.toHexString(match) + "}"; 239 } 240 describeContents()241 public int describeContents() { 242 return 0; 243 } 244 writeToParcel(Parcel dest, int parcelableFlags)245 public void writeToParcel(Parcel dest, int parcelableFlags) { 246 if (activityInfo != null) { 247 dest.writeInt(1); 248 activityInfo.writeToParcel(dest, parcelableFlags); 249 } else if (serviceInfo != null) { 250 dest.writeInt(2); 251 serviceInfo.writeToParcel(dest, parcelableFlags); 252 } else { 253 dest.writeInt(0); 254 } 255 if (filter != null) { 256 dest.writeInt(1); 257 filter.writeToParcel(dest, parcelableFlags); 258 } else { 259 dest.writeInt(0); 260 } 261 dest.writeInt(priority); 262 dest.writeInt(preferredOrder); 263 dest.writeInt(match); 264 dest.writeInt(specificIndex); 265 dest.writeInt(labelRes); 266 TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags); 267 dest.writeInt(icon); 268 dest.writeString(resolvePackageName); 269 dest.writeInt(system ? 1 : 0); 270 } 271 272 public static final Creator<ResolveInfo> CREATOR 273 = new Creator<ResolveInfo>() { 274 public ResolveInfo createFromParcel(Parcel source) { 275 return new ResolveInfo(source); 276 } 277 public ResolveInfo[] newArray(int size) { 278 return new ResolveInfo[size]; 279 } 280 }; 281 ResolveInfo(Parcel source)282 private ResolveInfo(Parcel source) { 283 switch (source.readInt()) { 284 case 1: 285 activityInfo = ActivityInfo.CREATOR.createFromParcel(source); 286 serviceInfo = null; 287 break; 288 case 2: 289 serviceInfo = ServiceInfo.CREATOR.createFromParcel(source); 290 activityInfo = null; 291 break; 292 default: 293 activityInfo = null; 294 serviceInfo = null; 295 break; 296 } 297 if (source.readInt() != 0) { 298 filter = IntentFilter.CREATOR.createFromParcel(source); 299 } 300 priority = source.readInt(); 301 preferredOrder = source.readInt(); 302 match = source.readInt(); 303 specificIndex = source.readInt(); 304 labelRes = source.readInt(); 305 nonLocalizedLabel 306 = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 307 icon = source.readInt(); 308 resolvePackageName = source.readString(); 309 system = source.readInt() != 0; 310 } 311 312 public static class DisplayNameComparator 313 implements Comparator<ResolveInfo> { DisplayNameComparator(PackageManager pm)314 public DisplayNameComparator(PackageManager pm) { 315 mPM = pm; 316 } 317 compare(ResolveInfo a, ResolveInfo b)318 public final int compare(ResolveInfo a, ResolveInfo b) { 319 CharSequence sa = a.loadLabel(mPM); 320 if (sa == null) sa = a.activityInfo.name; 321 CharSequence sb = b.loadLabel(mPM); 322 if (sb == null) sb = b.activityInfo.name; 323 324 return sCollator.compare(sa.toString(), sb.toString()); 325 } 326 327 private final Collator sCollator = Collator.getInstance(); 328 private PackageManager mPM; 329 } 330 } 331