• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 import java.lang.Comparable;
22 
23 /**
24  * Identifier for a specific application component
25  * ({@link android.app.Activity}, {@link android.app.Service},
26  * {@link android.content.BroadcastReceiver}, or
27  * {@link android.content.ContentProvider}) that is available.  Two
28  * pieces of information, encapsulated here, are required to identify
29  * a component: the package (a String) it exists in, and the class (a String)
30  * name inside of that package.
31  *
32  */
33 public final class ComponentName implements Parcelable, Comparable<ComponentName> {
34     private final String mPackage;
35     private final String mClass;
36 
37     /**
38      * Create a new component identifier.
39      *
40      * @param pkg The name of the package that the component exists in.  Can
41      * not be null.
42      * @param cls The name of the class inside of <var>pkg</var> that
43      * implements the component.  Can not be null.
44      */
ComponentName(String pkg, String cls)45     public ComponentName(String pkg, String cls) {
46         if (pkg == null) throw new NullPointerException("package name is null");
47         if (cls == null) throw new NullPointerException("class name is null");
48         mPackage = pkg;
49         mClass = cls;
50     }
51 
52     /**
53      * Create a new component identifier from a Context and class name.
54      *
55      * @param pkg A Context for the package implementing the component,
56      * from which the actual package name will be retrieved.
57      * @param cls The name of the class inside of <var>pkg</var> that
58      * implements the component.
59      */
ComponentName(Context pkg, String cls)60     public ComponentName(Context pkg, String cls) {
61         if (cls == null) throw new NullPointerException("class name is null");
62         mPackage = pkg.getPackageName();
63         mClass = cls;
64     }
65 
66     /**
67      * Create a new component identifier from a Context and Class object.
68      *
69      * @param pkg A Context for the package implementing the component, from
70      * which the actual package name will be retrieved.
71      * @param cls The Class object of the desired component, from which the
72      * actual class name will be retrieved.
73      */
ComponentName(Context pkg, Class<?> cls)74     public ComponentName(Context pkg, Class<?> cls) {
75         mPackage = pkg.getPackageName();
76         mClass = cls.getName();
77     }
78 
79     /**
80      * Return the package name of this component.
81      */
getPackageName()82     public String getPackageName() {
83         return mPackage;
84     }
85 
86     /**
87      * Return the class name of this component.
88      */
getClassName()89     public String getClassName() {
90         return mClass;
91     }
92 
93     /**
94      * Return the class name, either fully qualified or in a shortened form
95      * (with a leading '.') if it is a suffix of the package.
96      */
getShortClassName()97     public String getShortClassName() {
98         if (mClass.startsWith(mPackage)) {
99             int PN = mPackage.length();
100             int CN = mClass.length();
101             if (CN > PN && mClass.charAt(PN) == '.') {
102                 return mClass.substring(PN, CN);
103             }
104         }
105         return mClass;
106     }
107 
108     /**
109      * Return a String that unambiguously describes both the package and
110      * class names contained in the ComponentName.  You can later recover
111      * the ComponentName from this string through
112      * {@link #unflattenFromString(String)}.
113      *
114      * @return Returns a new String holding the package and class names.  This
115      * is represented as the package name, concatenated with a '/' and then the
116      * class name.
117      *
118      * @see #unflattenFromString(String)
119      */
flattenToString()120     public String flattenToString() {
121         return mPackage + "/" + mClass;
122     }
123 
124     /**
125      * The samee as {@link #flattenToString()}, but abbreviates the class
126      * name if it is a suffix of the package.  The result can still be used
127      * with {@link #unflattenFromString(String)}.
128      *
129      * @return Returns a new String holding the package and class names.  This
130      * is represented as the package name, concatenated with a '/' and then the
131      * class name.
132      *
133      * @see #unflattenFromString(String)
134      */
flattenToShortString()135     public String flattenToShortString() {
136         return mPackage + "/" + getShortClassName();
137     }
138 
139     /**
140      * Recover a ComponentName from a String that was previously created with
141      * {@link #flattenToString()}.  It splits the string at the first '/',
142      * taking the part before as the package name and the part after as the
143      * class name.  As a special convenience (to use, for example, when
144      * parsing component names on the command line), if the '/' is immediately
145      * followed by a '.' then the final class name will be the concatenation
146      * of the package name with the string following the '/'.  Thus
147      * "com.foo/.Blah" becomes package="com.foo" class="com.foo.Blah".
148      *
149      * @param str The String that was returned by flattenToString().
150      * @return Returns a new ComponentName containing the package and class
151      * names that were encoded in <var>str</var>
152      *
153      * @see #flattenToString()
154      */
unflattenFromString(String str)155     public static ComponentName unflattenFromString(String str) {
156         int sep = str.indexOf('/');
157         if (sep < 0 || (sep+1) >= str.length()) {
158             return null;
159         }
160         String pkg = str.substring(0, sep);
161         String cls = str.substring(sep+1);
162         if (cls.length() > 0 && cls.charAt(0) == '.') {
163             cls = pkg + cls;
164         }
165         return new ComponentName(pkg, cls);
166     }
167 
168     /**
169      * Return string representation of this class without the class's name
170      * as a prefix.
171      */
toShortString()172     public String toShortString() {
173         return "{" + mPackage + "/" + mClass + "}";
174     }
175 
176     @Override
toString()177     public String toString() {
178         return "ComponentInfo{" + mPackage + "/" + mClass + "}";
179     }
180 
181     @Override
equals(Object obj)182     public boolean equals(Object obj) {
183         try {
184             if (obj != null) {
185                 ComponentName other = (ComponentName)obj;
186                 // Note: no null checks, because mPackage and mClass can
187                 // never be null.
188                 return mPackage.equals(other.mPackage)
189                         && mClass.equals(other.mClass);
190             }
191         } catch (ClassCastException e) {
192         }
193         return false;
194     }
195 
196     @Override
hashCode()197     public int hashCode() {
198         return mPackage.hashCode() + mClass.hashCode();
199     }
200 
compareTo(ComponentName that)201     public int compareTo(ComponentName that) {
202         int v;
203         v = this.mPackage.compareTo(that.mPackage);
204         if (v != 0) {
205             return v;
206         }
207         return this.mClass.compareTo(that.mClass);
208     }
209 
describeContents()210     public int describeContents() {
211         return 0;
212     }
213 
writeToParcel(Parcel out, int flags)214     public void writeToParcel(Parcel out, int flags) {
215         out.writeString(mPackage);
216         out.writeString(mClass);
217     }
218 
219     /**
220      * Write a ComponentName to a Parcel, handling null pointers.  Must be
221      * read with {@link #readFromParcel(Parcel)}.
222      *
223      * @param c The ComponentName to be written.
224      * @param out The Parcel in which the ComponentName will be placed.
225      *
226      * @see #readFromParcel(Parcel)
227      */
writeToParcel(ComponentName c, Parcel out)228     public static void writeToParcel(ComponentName c, Parcel out) {
229         if (c != null) {
230             c.writeToParcel(out, 0);
231         } else {
232             out.writeString(null);
233         }
234     }
235 
236     /**
237      * Read a ComponentName from a Parcel that was previously written
238      * with {@link #writeToParcel(ComponentName, Parcel)}, returning either
239      * a null or new object as appropriate.
240      *
241      * @param in The Parcel from which to read the ComponentName
242      * @return Returns a new ComponentName matching the previously written
243      * object, or null if a null had been written.
244      *
245      * @see #writeToParcel(ComponentName, Parcel)
246      */
readFromParcel(Parcel in)247     public static ComponentName readFromParcel(Parcel in) {
248         String pkg = in.readString();
249         return pkg != null ? new ComponentName(pkg, in) : null;
250     }
251 
252     public static final Parcelable.Creator<ComponentName> CREATOR
253             = new Parcelable.Creator<ComponentName>() {
254         public ComponentName createFromParcel(Parcel in) {
255             return new ComponentName(in);
256         }
257 
258         public ComponentName[] newArray(int size) {
259             return new ComponentName[size];
260         }
261     };
262 
263     /**
264      * Instantiate a new ComponentName from the data in a Parcel that was
265      * previously written with {@link #writeToParcel(Parcel, int)}.  Note that you
266      * must not use this with data written by
267      * {@link #writeToParcel(ComponentName, Parcel)} since it is not possible
268      * to handle a null ComponentObject here.
269      *
270      * @param in The Parcel containing the previously written ComponentName,
271      * positioned at the location in the buffer where it was written.
272      */
ComponentName(Parcel in)273     public ComponentName(Parcel in) {
274         mPackage = in.readString();
275         if (mPackage == null) throw new NullPointerException(
276                 "package name is null");
277         mClass = in.readString();
278         if (mClass == null) throw new NullPointerException(
279                 "class name is null");
280     }
281 
ComponentName(String pkg, Parcel in)282     private ComponentName(String pkg, Parcel in) {
283         mPackage = pkg;
284         mClass = in.readString();
285     }
286 }
287