blob: 1ff41c022186aa757a4023c56db8ecc86236a4d3 [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
Dianne Hackborn6d8dfbd2013-09-23 17:38:51 -070019import android.content.ComponentName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.content.IntentFilter;
21import android.graphics.drawable.Drawable;
22import android.os.Parcel;
23import android.os.Parcelable;
24import android.text.TextUtils;
25import android.util.Printer;
Jeff Sharkey85f5f812013-10-07 10:16:12 -070026import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027
28import java.text.Collator;
29import java.util.Comparator;
30
31/**
32 * Information that is returned from resolving an intent
33 * against an IntentFilter. This partially corresponds to
34 * information collected from the AndroidManifest.xml's
35 * <intent> tags.
36 */
37public class ResolveInfo implements Parcelable {
Jeff Sharkey85f5f812013-10-07 10:16:12 -070038 private static final String TAG = "ResolveInfo";
39
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 /**
Jeff Sharkey85f5f812013-10-07 10:16:12 -070041 * The activity or broadcast receiver that corresponds to this resolution
42 * match, if this resolution is for an activity or broadcast receiver.
43 * Exactly one of {@link #activityInfo}, {@link #serviceInfo}, or
44 * {@link #providerInfo} will be non-null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 */
46 public ActivityInfo activityInfo;
47
48 /**
Jeff Sharkey85f5f812013-10-07 10:16:12 -070049 * The service that corresponds to this resolution match, if this resolution
50 * is for a service. Exactly one of {@link #activityInfo},
51 * {@link #serviceInfo}, or {@link #providerInfo} will be non-null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052 */
53 public ServiceInfo serviceInfo;
Jeff Sharkey85f5f812013-10-07 10:16:12 -070054
55 /**
56 * The provider that corresponds to this resolution match, if this
57 * resolution is for a provider. Exactly one of {@link #activityInfo},
58 * {@link #serviceInfo}, or {@link #providerInfo} will be non-null.
59 */
60 public ProviderInfo providerInfo;
61
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 /**
63 * The IntentFilter that was matched for this ResolveInfo.
64 */
65 public IntentFilter filter;
66
67 /**
68 * The declared priority of this match. Comes from the "priority"
69 * attribute or, if not set, defaults to 0. Higher values are a higher
70 * priority.
71 */
72 public int priority;
73
74 /**
75 * Order of result according to the user's preference. If the user
76 * has not set a preference for this result, the value is 0; higher
77 * values are a higher priority.
78 */
79 public int preferredOrder;
80
81 /**
82 * The system's evaluation of how well the activity matches the
83 * IntentFilter. This is a match constant, a combination of
84 * {@link IntentFilter#MATCH_CATEGORY_MASK IntentFilter.MATCH_CATEGORY_MASK}
85 * and {@link IntentFilter#MATCH_ADJUSTMENT_MASK IntentFiler.MATCH_ADJUSTMENT_MASK}.
86 */
87 public int match;
88
89 /**
90 * Only set when returned by
91 * {@link PackageManager#queryIntentActivityOptions}, this tells you
92 * which of the given specific intents this result came from. 0 is the
93 * first in the list, < 0 means it came from the generic Intent query.
94 */
95 public int specificIndex = -1;
96
97 /**
98 * This filter has specified the Intent.CATEGORY_DEFAULT, meaning it
99 * would like to be considered a default action that the user can
100 * perform on this data.
101 */
102 public boolean isDefault;
103
104 /**
105 * A string resource identifier (in the package's resources) of this
106 * match's label. From the "label" attribute or, if not set, 0.
107 */
108 public int labelRes;
109
110 /**
111 * The actual string retrieve from <var>labelRes</var> or null if none
112 * was provided.
113 */
114 public CharSequence nonLocalizedLabel;
115
116 /**
117 * A drawable resource identifier (in the package's resources) of this
118 * match's icon. From the "icon" attribute or, if not set, 0.
119 */
120 public int icon;
121
122 /**
Dianne Hackborneb034652009-09-07 00:49:58 -0700123 * Optional -- if non-null, the {@link #labelRes} and {@link #icon}
124 * resources will be loaded from this package, rather than the one
125 * containing the resolved component.
126 */
127 public String resolvePackageName;
Dianne Hackbornd99b2932011-08-18 14:39:58 -0700128
129 /**
130 * @hide Target comes from system process?
131 */
132 public boolean system;
133
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700134 private ComponentInfo getComponentInfo() {
135 if (activityInfo != null) return activityInfo;
136 if (serviceInfo != null) return serviceInfo;
137 if (providerInfo != null) return providerInfo;
138 throw new IllegalStateException("Missing ComponentInfo!");
139 }
140
Dianne Hackborneb034652009-09-07 00:49:58 -0700141 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 * Retrieve the current textual label associated with this resolution. This
143 * will call back on the given PackageManager to load the label from
144 * the application.
145 *
146 * @param pm A PackageManager from which the label can be loaded; usually
147 * the PackageManager from which you originally retrieved this item.
148 *
149 * @return Returns a CharSequence containing the resolutions's label. If the
150 * item does not have a label, its name is returned.
151 */
152 public CharSequence loadLabel(PackageManager pm) {
153 if (nonLocalizedLabel != null) {
154 return nonLocalizedLabel;
155 }
Dianne Hackborneb034652009-09-07 00:49:58 -0700156 CharSequence label;
157 if (resolvePackageName != null && labelRes != 0) {
158 label = pm.getText(resolvePackageName, labelRes, null);
159 if (label != null) {
Romain Guy2aba11f2010-03-29 16:03:01 -0700160 return label.toString().trim();
Dianne Hackborneb034652009-09-07 00:49:58 -0700161 }
162 }
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700163 ComponentInfo ci = getComponentInfo();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 ApplicationInfo ai = ci.applicationInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 if (labelRes != 0) {
166 label = pm.getText(ci.packageName, labelRes, ai);
167 if (label != null) {
Romain Guy2aba11f2010-03-29 16:03:01 -0700168 return label.toString().trim();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 }
170 }
Romain Guy2aba11f2010-03-29 16:03:01 -0700171
172 CharSequence data = ci.loadLabel(pm);
173 // Make the data safe
174 if (data != null) data = data.toString().trim();
175 return data;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 }
177
178 /**
179 * Retrieve the current graphical icon associated with this resolution. This
180 * will call back on the given PackageManager to load the icon from
181 * the application.
182 *
183 * @param pm A PackageManager from which the icon can be loaded; usually
184 * the PackageManager from which you originally retrieved this item.
185 *
186 * @return Returns a Drawable containing the resolution's icon. If the
187 * item does not have an icon, the default activity icon is returned.
188 */
189 public Drawable loadIcon(PackageManager pm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 Drawable dr;
Dianne Hackborneb034652009-09-07 00:49:58 -0700191 if (resolvePackageName != null && icon != 0) {
192 dr = pm.getDrawable(resolvePackageName, icon, null);
193 if (dr != null) {
194 return dr;
195 }
196 }
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700197 ComponentInfo ci = getComponentInfo();
Jeff Brown07330792010-03-30 19:57:08 -0700198 ApplicationInfo ai = ci.applicationInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 if (icon != 0) {
200 dr = pm.getDrawable(ci.packageName, icon, ai);
201 if (dr != null) {
202 return dr;
203 }
204 }
205 return ci.loadIcon(pm);
206 }
207
208 /**
209 * Return the icon resource identifier to use for this match. If the
210 * match defines an icon, that is used; else if the activity defines
211 * an icon, that is used; else, the application icon is used.
212 *
213 * @return The icon associated with this match.
214 */
215 public final int getIconResource() {
216 if (icon != 0) return icon;
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700217 final ComponentInfo ci = getComponentInfo();
218 if (ci != null) return ci.getIconResource();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 return 0;
220 }
221
222 public void dump(Printer pw, String prefix) {
223 if (filter != null) {
224 pw.println(prefix + "Filter:");
225 filter.dump(pw, prefix + " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 }
227 pw.println(prefix + "priority=" + priority
228 + " preferredOrder=" + preferredOrder
229 + " match=0x" + Integer.toHexString(match)
230 + " specificIndex=" + specificIndex
231 + " isDefault=" + isDefault);
Dianne Hackborneb034652009-09-07 00:49:58 -0700232 if (resolvePackageName != null) {
233 pw.println(prefix + "resolvePackageName=" + resolvePackageName);
234 }
235 if (labelRes != 0 || nonLocalizedLabel != null || icon != 0) {
236 pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes)
237 + " nonLocalizedLabel=" + nonLocalizedLabel
238 + " icon=0x" + Integer.toHexString(icon));
239 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 if (activityInfo != null) {
241 pw.println(prefix + "ActivityInfo:");
242 activityInfo.dump(pw, prefix + " ");
243 } else if (serviceInfo != null) {
244 pw.println(prefix + "ServiceInfo:");
Dianne Hackborneb034652009-09-07 00:49:58 -0700245 serviceInfo.dump(pw, prefix + " ");
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700246 } else if (providerInfo != null) {
247 pw.println(prefix + "ProviderInfo:");
248 providerInfo.dump(pw, prefix + " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 }
250 }
251
252 public ResolveInfo() {
253 }
254
Dianne Hackborn8da429e2012-09-23 12:52:19 -0700255 public ResolveInfo(ResolveInfo orig) {
256 activityInfo = orig.activityInfo;
257 serviceInfo = orig.serviceInfo;
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700258 providerInfo = orig.providerInfo;
Dianne Hackborn8da429e2012-09-23 12:52:19 -0700259 filter = orig.filter;
260 priority = orig.priority;
261 preferredOrder = orig.preferredOrder;
262 match = orig.match;
263 specificIndex = orig.specificIndex;
264 labelRes = orig.labelRes;
265 nonLocalizedLabel = orig.nonLocalizedLabel;
266 icon = orig.icon;
267 resolvePackageName = orig.resolvePackageName;
268 system = orig.system;
269 }
270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 public String toString() {
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700272 final ComponentInfo ci = getComponentInfo();
Dianne Hackborn6d8dfbd2013-09-23 17:38:51 -0700273 StringBuilder sb = new StringBuilder(128);
274 sb.append("ResolveInfo{");
275 sb.append(Integer.toHexString(System.identityHashCode(this)));
276 sb.append(' ');
277 ComponentName.appendShortString(sb, ci.packageName, ci.name);
278 if (priority != 0) {
279 sb.append(" p=");
280 sb.append(priority);
281 }
282 if (preferredOrder != 0) {
283 sb.append(" o=");
284 sb.append(preferredOrder);
285 }
286 sb.append(" m=0x");
287 sb.append(Integer.toHexString(match));
288 sb.append('}');
289 return sb.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290 }
291
292 public int describeContents() {
293 return 0;
294 }
295
296 public void writeToParcel(Parcel dest, int parcelableFlags) {
297 if (activityInfo != null) {
298 dest.writeInt(1);
299 activityInfo.writeToParcel(dest, parcelableFlags);
300 } else if (serviceInfo != null) {
301 dest.writeInt(2);
302 serviceInfo.writeToParcel(dest, parcelableFlags);
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700303 } else if (providerInfo != null) {
304 dest.writeInt(3);
305 providerInfo.writeToParcel(dest, parcelableFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 } else {
307 dest.writeInt(0);
308 }
309 if (filter != null) {
310 dest.writeInt(1);
311 filter.writeToParcel(dest, parcelableFlags);
312 } else {
313 dest.writeInt(0);
314 }
315 dest.writeInt(priority);
316 dest.writeInt(preferredOrder);
317 dest.writeInt(match);
318 dest.writeInt(specificIndex);
319 dest.writeInt(labelRes);
320 TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags);
321 dest.writeInt(icon);
Dianne Hackborneb034652009-09-07 00:49:58 -0700322 dest.writeString(resolvePackageName);
Dianne Hackbornd99b2932011-08-18 14:39:58 -0700323 dest.writeInt(system ? 1 : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 }
325
326 public static final Creator<ResolveInfo> CREATOR
327 = new Creator<ResolveInfo>() {
328 public ResolveInfo createFromParcel(Parcel source) {
329 return new ResolveInfo(source);
330 }
331 public ResolveInfo[] newArray(int size) {
332 return new ResolveInfo[size];
333 }
334 };
335
336 private ResolveInfo(Parcel source) {
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700337 activityInfo = null;
338 serviceInfo = null;
339 providerInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 switch (source.readInt()) {
341 case 1:
342 activityInfo = ActivityInfo.CREATOR.createFromParcel(source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 break;
344 case 2:
345 serviceInfo = ServiceInfo.CREATOR.createFromParcel(source);
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700346 break;
347 case 3:
348 providerInfo = ProviderInfo.CREATOR.createFromParcel(source);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 break;
350 default:
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700351 Slog.w(TAG, "Missing ComponentInfo!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 break;
353 }
354 if (source.readInt() != 0) {
355 filter = IntentFilter.CREATOR.createFromParcel(source);
356 }
357 priority = source.readInt();
358 preferredOrder = source.readInt();
359 match = source.readInt();
360 specificIndex = source.readInt();
361 labelRes = source.readInt();
362 nonLocalizedLabel
363 = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
364 icon = source.readInt();
Dianne Hackborneb034652009-09-07 00:49:58 -0700365 resolvePackageName = source.readString();
Dianne Hackbornd99b2932011-08-18 14:39:58 -0700366 system = source.readInt() != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 }
368
369 public static class DisplayNameComparator
370 implements Comparator<ResolveInfo> {
371 public DisplayNameComparator(PackageManager pm) {
372 mPM = pm;
Adam Powell0256c6f2013-05-29 16:42:33 -0700373 mCollator.setStrength(Collator.PRIMARY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 }
375
376 public final int compare(ResolveInfo a, ResolveInfo b) {
377 CharSequence sa = a.loadLabel(mPM);
378 if (sa == null) sa = a.activityInfo.name;
379 CharSequence sb = b.loadLabel(mPM);
380 if (sb == null) sb = b.activityInfo.name;
381
Adam Powell0256c6f2013-05-29 16:42:33 -0700382 return mCollator.compare(sa.toString(), sb.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 }
384
Adam Powell0256c6f2013-05-29 16:42:33 -0700385 private final Collator mCollator = Collator.getInstance();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 private PackageManager mPM;
387 }
388}