• 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, Cloneable, 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 
clone()79     public ComponentName clone() {
80         return new ComponentName(mPackage, mClass);
81     }
82 
83     /**
84      * Return the package name of this component.
85      */
getPackageName()86     public String getPackageName() {
87         return mPackage;
88     }
89 
90     /**
91      * Return the class name of this component.
92      */
getClassName()93     public String getClassName() {
94         return mClass;
95     }
96 
97     /**
98      * Return the class name, either fully qualified or in a shortened form
99      * (with a leading '.') if it is a suffix of the package.
100      */
getShortClassName()101     public String getShortClassName() {
102         if (mClass.startsWith(mPackage)) {
103             int PN = mPackage.length();
104             int CN = mClass.length();
105             if (CN > PN && mClass.charAt(PN) == '.') {
106                 return mClass.substring(PN, CN);
107             }
108         }
109         return mClass;
110     }
111 
112     /**
113      * Return a String that unambiguously describes both the package and
114      * class names contained in the ComponentName.  You can later recover
115      * the ComponentName from this string through
116      * {@link #unflattenFromString(String)}.
117      *
118      * @return Returns a new String holding the package and class names.  This
119      * is represented as the package name, concatenated with a '/' and then the
120      * class name.
121      *
122      * @see #unflattenFromString(String)
123      */
flattenToString()124     public String flattenToString() {
125         return mPackage + "/" + mClass;
126     }
127 
128     /**
129      * The same as {@link #flattenToString()}, but abbreviates the class
130      * name if it is a suffix of the package.  The result can still be used
131      * with {@link #unflattenFromString(String)}.
132      *
133      * @return Returns a new String holding the package and class names.  This
134      * is represented as the package name, concatenated with a '/' and then the
135      * class name.
136      *
137      * @see #unflattenFromString(String)
138      */
flattenToShortString()139     public String flattenToShortString() {
140         return mPackage + "/" + getShortClassName();
141     }
142 
143     /**
144      * Recover a ComponentName from a String that was previously created with
145      * {@link #flattenToString()}.  It splits the string at the first '/',
146      * taking the part before as the package name and the part after as the
147      * class name.  As a special convenience (to use, for example, when
148      * parsing component names on the command line), if the '/' is immediately
149      * followed by a '.' then the final class name will be the concatenation
150      * of the package name with the string following the '/'.  Thus
151      * "com.foo/.Blah" becomes package="com.foo" class="com.foo.Blah".
152      *
153      * @param str The String that was returned by flattenToString().
154      * @return Returns a new ComponentName containing the package and class
155      * names that were encoded in <var>str</var>
156      *
157      * @see #flattenToString()
158      */
unflattenFromString(String str)159     public static ComponentName unflattenFromString(String str) {
160         int sep = str.indexOf('/');
161         if (sep < 0 || (sep+1) >= str.length()) {
162             return null;
163         }
164         String pkg = str.substring(0, sep);
165         String cls = str.substring(sep+1);
166         if (cls.length() > 0 && cls.charAt(0) == '.') {
167             cls = pkg + cls;
168         }
169         return new ComponentName(pkg, cls);
170     }
171 
172     /**
173      * Return string representation of this class without the class's name
174      * as a prefix.
175      */
toShortString()176     public String toShortString() {
177         return "{" + mPackage + "/" + mClass + "}";
178     }
179 
180     @Override
toString()181     public String toString() {
182         return "ComponentInfo{" + mPackage + "/" + mClass + "}";
183     }
184 
185     @Override
equals(Object obj)186     public boolean equals(Object obj) {
187         try {
188             if (obj != null) {
189                 ComponentName other = (ComponentName)obj;
190                 // Note: no null checks, because mPackage and mClass can
191                 // never be null.
192                 return mPackage.equals(other.mPackage)
193                         && mClass.equals(other.mClass);
194             }
195         } catch (ClassCastException e) {
196         }
197         return false;
198     }
199 
200     @Override
hashCode()201     public int hashCode() {
202         return mPackage.hashCode() + mClass.hashCode();
203     }
204 
compareTo(ComponentName that)205     public int compareTo(ComponentName that) {
206         int v;
207         v = this.mPackage.compareTo(that.mPackage);
208         if (v != 0) {
209             return v;
210         }
211         return this.mClass.compareTo(that.mClass);
212     }
213 
describeContents()214     public int describeContents() {
215         return 0;
216     }
217 
writeToParcel(Parcel out, int flags)218     public void writeToParcel(Parcel out, int flags) {
219         out.writeString(mPackage);
220         out.writeString(mClass);
221     }
222 
223     /**
224      * Write a ComponentName to a Parcel, handling null pointers.  Must be
225      * read with {@link #readFromParcel(Parcel)}.
226      *
227      * @param c The ComponentName to be written.
228      * @param out The Parcel in which the ComponentName will be placed.
229      *
230      * @see #readFromParcel(Parcel)
231      */
writeToParcel(ComponentName c, Parcel out)232     public static void writeToParcel(ComponentName c, Parcel out) {
233         if (c != null) {
234             c.writeToParcel(out, 0);
235         } else {
236             out.writeString(null);
237         }
238     }
239 
240     /**
241      * Read a ComponentName from a Parcel that was previously written
242      * with {@link #writeToParcel(ComponentName, Parcel)}, returning either
243      * a null or new object as appropriate.
244      *
245      * @param in The Parcel from which to read the ComponentName
246      * @return Returns a new ComponentName matching the previously written
247      * object, or null if a null had been written.
248      *
249      * @see #writeToParcel(ComponentName, Parcel)
250      */
readFromParcel(Parcel in)251     public static ComponentName readFromParcel(Parcel in) {
252         String pkg = in.readString();
253         return pkg != null ? new ComponentName(pkg, in) : null;
254     }
255 
256     public static final Parcelable.Creator<ComponentName> CREATOR
257             = new Parcelable.Creator<ComponentName>() {
258         public ComponentName createFromParcel(Parcel in) {
259             return new ComponentName(in);
260         }
261 
262         public ComponentName[] newArray(int size) {
263             return new ComponentName[size];
264         }
265     };
266 
267     /**
268      * Instantiate a new ComponentName from the data in a Parcel that was
269      * previously written with {@link #writeToParcel(Parcel, int)}.  Note that you
270      * must not use this with data written by
271      * {@link #writeToParcel(ComponentName, Parcel)} since it is not possible
272      * to handle a null ComponentObject here.
273      *
274      * @param in The Parcel containing the previously written ComponentName,
275      * positioned at the location in the buffer where it was written.
276      */
ComponentName(Parcel in)277     public ComponentName(Parcel in) {
278         mPackage = in.readString();
279         if (mPackage == null) throw new NullPointerException(
280                 "package name is null");
281         mClass = in.readString();
282         if (mClass == null) throw new NullPointerException(
283                 "class name is null");
284     }
285 
ComponentName(String pkg, Parcel in)286     private ComponentName(String pkg, Parcel in) {
287         mPackage = pkg;
288         mClass = in.readString();
289     }
290 }
291