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