• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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