blob: 7ca0f01b986924d939b57061966ec8526de9e608 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.content;
18
19import android.os.Parcel;
20import android.os.Parcelable;
Joe Onorato6b61d412009-05-12 14:42:58 -040021import java.lang.Comparable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
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 */
Joe Onoratoedc649a2010-02-08 12:40:45 -080033public final class ComponentName implements Parcelable, Cloneable, Comparable<ComponentName> {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034 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 */
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 */
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 */
74 public ComponentName(Context pkg, Class<?> cls) {
75 mPackage = pkg.getPackageName();
76 mClass = cls.getName();
77 }
78
Joe Onoratoedc649a2010-02-08 12:40:45 -080079 public ComponentName clone() {
80 return new ComponentName(mPackage, mClass);
81 }
82
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 /**
84 * Return the package name of this component.
85 */
86 public String getPackageName() {
87 return mPackage;
88 }
89
90 /**
91 * Return the class name of this component.
92 */
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 */
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 */
124 public String flattenToString() {
125 return mPackage + "/" + mClass;
126 }
127
128 /**
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800129 * The same as {@link #flattenToString()}, but abbreviates the class
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 * 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 */
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 */
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 */
176 public String toShortString() {
177 return "{" + mPackage + "/" + mClass + "}";
178 }
179
180 @Override
181 public String toString() {
182 return "ComponentInfo{" + mPackage + "/" + mClass + "}";
183 }
184
185 @Override
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
201 public int hashCode() {
202 return mPackage.hashCode() + mClass.hashCode();
203 }
Joe Onorato6b61d412009-05-12 14:42:58 -0400204
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 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213
214 public int describeContents() {
215 return 0;
216 }
217
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 */
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 */
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 */
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
286 private ComponentName(String pkg, Parcel in) {
287 mPackage = pkg;
288 mClass = in.readString();
289 }
290}