blob: 07117fe0754e8d2276fa4ed9f3a046beb18c5b73 [file] [log] [blame]
Kenny Root15a4d2f2010-03-11 18:20:12 -08001/*
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080017package android.content.pm;
18
19import android.content.IntentFilter;
20import android.graphics.drawable.Drawable;
21import android.os.Parcel;
22import android.os.Parcelable;
23import android.text.TextUtils;
24import android.util.Printer;
25
26import java.text.Collator;
27import 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 */
35public class ResolveInfo implements Parcelable {
36 /**
Jeff Hamiltonca756bf2011-10-26 16:42:46 -050037 * The activity or broadcast receiver that corresponds to this resolution match,
38 * if this resolution is for an activity or broadcast receiver. One and only one of this and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039 * 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 /**
Dianne Hackborneb034652009-09-07 00:49:58 -0700111 * 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;
Dianne Hackbornd99b2932011-08-18 14:39:58 -0700116
117 /**
118 * @hide Target comes from system process?
119 */
120 public boolean system;
121
Dianne Hackborneb034652009-09-07 00:49:58 -0700122 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 * 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 */
133 public CharSequence loadLabel(PackageManager pm) {
134 if (nonLocalizedLabel != null) {
135 return nonLocalizedLabel;
136 }
Dianne Hackborneb034652009-09-07 00:49:58 -0700137 CharSequence label;
138 if (resolvePackageName != null && labelRes != 0) {
139 label = pm.getText(resolvePackageName, labelRes, null);
140 if (label != null) {
Romain Guy2aba11f2010-03-29 16:03:01 -0700141 return label.toString().trim();
Dianne Hackborneb034652009-09-07 00:49:58 -0700142 }
143 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo;
145 ApplicationInfo ai = ci.applicationInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 if (labelRes != 0) {
147 label = pm.getText(ci.packageName, labelRes, ai);
148 if (label != null) {
Romain Guy2aba11f2010-03-29 16:03:01 -0700149 return label.toString().trim();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 }
151 }
Romain Guy2aba11f2010-03-29 16:03:01 -0700152
153 CharSequence data = ci.loadLabel(pm);
154 // Make the data safe
155 if (data != null) data = data.toString().trim();
156 return data;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 }
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 */
170 public Drawable loadIcon(PackageManager pm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 Drawable dr;
Dianne Hackborneb034652009-09-07 00:49:58 -0700172 if (resolvePackageName != null && icon != 0) {
173 dr = pm.getDrawable(resolvePackageName, icon, null);
174 if (dr != null) {
175 return dr;
176 }
177 }
Jeff Brown07330792010-03-30 19:57:08 -0700178 ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo;
179 ApplicationInfo ai = ci.applicationInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 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 */
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
203 public void dump(Printer pw, String prefix) {
204 if (filter != null) {
205 pw.println(prefix + "Filter:");
206 filter.dump(pw, prefix + " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 }
208 pw.println(prefix + "priority=" + priority
209 + " preferredOrder=" + preferredOrder
210 + " match=0x" + Integer.toHexString(match)
211 + " specificIndex=" + specificIndex
212 + " isDefault=" + isDefault);
Dianne Hackborneb034652009-09-07 00:49:58 -0700213 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 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 if (activityInfo != null) {
222 pw.println(prefix + "ActivityInfo:");
223 activityInfo.dump(pw, prefix + " ");
224 } else if (serviceInfo != null) {
225 pw.println(prefix + "ServiceInfo:");
Dianne Hackborneb034652009-09-07 00:49:58 -0700226 serviceInfo.dump(pw, prefix + " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 }
228 }
229
230 public ResolveInfo() {
231 }
232
Dianne Hackborn8da429e2012-09-23 12:52:19 -0700233 public ResolveInfo(ResolveInfo orig) {
234 activityInfo = orig.activityInfo;
235 serviceInfo = orig.serviceInfo;
236 filter = orig.filter;
237 priority = orig.priority;
238 preferredOrder = orig.preferredOrder;
239 match = orig.match;
240 specificIndex = orig.specificIndex;
241 labelRes = orig.labelRes;
242 nonLocalizedLabel = orig.nonLocalizedLabel;
243 icon = orig.icon;
244 resolvePackageName = orig.resolvePackageName;
245 system = orig.system;
246 }
247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 public String toString() {
249 ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo;
250 return "ResolveInfo{"
251 + Integer.toHexString(System.identityHashCode(this))
252 + " " + ci.name + " p=" + priority + " o="
253 + preferredOrder + " m=0x" + Integer.toHexString(match) + "}";
254 }
255
256 public int describeContents() {
257 return 0;
258 }
259
260 public void writeToParcel(Parcel dest, int parcelableFlags) {
261 if (activityInfo != null) {
262 dest.writeInt(1);
263 activityInfo.writeToParcel(dest, parcelableFlags);
264 } else if (serviceInfo != null) {
265 dest.writeInt(2);
266 serviceInfo.writeToParcel(dest, parcelableFlags);
267 } else {
268 dest.writeInt(0);
269 }
270 if (filter != null) {
271 dest.writeInt(1);
272 filter.writeToParcel(dest, parcelableFlags);
273 } else {
274 dest.writeInt(0);
275 }
276 dest.writeInt(priority);
277 dest.writeInt(preferredOrder);
278 dest.writeInt(match);
279 dest.writeInt(specificIndex);
280 dest.writeInt(labelRes);
281 TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags);
282 dest.writeInt(icon);
Dianne Hackborneb034652009-09-07 00:49:58 -0700283 dest.writeString(resolvePackageName);
Dianne Hackbornd99b2932011-08-18 14:39:58 -0700284 dest.writeInt(system ? 1 : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 }
286
287 public static final Creator<ResolveInfo> CREATOR
288 = new Creator<ResolveInfo>() {
289 public ResolveInfo createFromParcel(Parcel source) {
290 return new ResolveInfo(source);
291 }
292 public ResolveInfo[] newArray(int size) {
293 return new ResolveInfo[size];
294 }
295 };
296
297 private ResolveInfo(Parcel source) {
298 switch (source.readInt()) {
299 case 1:
300 activityInfo = ActivityInfo.CREATOR.createFromParcel(source);
301 serviceInfo = null;
302 break;
303 case 2:
304 serviceInfo = ServiceInfo.CREATOR.createFromParcel(source);
305 activityInfo = null;
306 break;
307 default:
308 activityInfo = null;
309 serviceInfo = null;
310 break;
311 }
312 if (source.readInt() != 0) {
313 filter = IntentFilter.CREATOR.createFromParcel(source);
314 }
315 priority = source.readInt();
316 preferredOrder = source.readInt();
317 match = source.readInt();
318 specificIndex = source.readInt();
319 labelRes = source.readInt();
320 nonLocalizedLabel
321 = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
322 icon = source.readInt();
Dianne Hackborneb034652009-09-07 00:49:58 -0700323 resolvePackageName = source.readString();
Dianne Hackbornd99b2932011-08-18 14:39:58 -0700324 system = source.readInt() != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 }
326
327 public static class DisplayNameComparator
328 implements Comparator<ResolveInfo> {
329 public DisplayNameComparator(PackageManager pm) {
330 mPM = pm;
331 }
332
333 public final int compare(ResolveInfo a, ResolveInfo b) {
334 CharSequence sa = a.loadLabel(mPM);
335 if (sa == null) sa = a.activityInfo.name;
336 CharSequence sb = b.loadLabel(mPM);
337 if (sb == null) sb = b.activityInfo.name;
338
339 return sCollator.compare(sa.toString(), sb.toString());
340 }
341
342 private final Collator sCollator = Collator.getInstance();
343 private PackageManager mPM;
344 }
345}