ResolveInfo.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
1package 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}
281