ClipDescription.java revision 21c241e061de29a538008ca42df9c878184bcfb8
1/**
2 * Copyright (c) 2010, 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;
21import android.text.TextUtils;
22
23import java.util.ArrayList;
24
25/**
26 * Meta-data describing the contents of a {@link ClipData}.  Provides enough
27 * information to know if you can handle the ClipData, but not the data
28 * itself.
29 *
30 * <div class="special reference">
31 * <h3>Developer Guides</h3>
32 * <p>For more information about using the clipboard framework, read the
33 * <a href="{@docRoot}guide/topics/clipboard/copy-paste.html">Copy and Paste</a>
34 * developer guide.</p>
35 * </div>
36 */
37public class ClipDescription implements Parcelable {
38    /**
39     * The MIME type for a clip holding plain text.
40     */
41    public static final String MIMETYPE_TEXT_PLAIN = "text/plain";
42
43    /**
44     * The MIME type for a clip holding one or more URIs.  This should be
45     * used for URIs that are meaningful to a user (such as an http: URI).
46     * It should <em>not</em> be used for a content: URI that references some
47     * other piece of data; in that case the MIME type should be the type
48     * of the referenced data.
49     */
50    public static final String MIMETYPE_TEXT_URILIST = "text/uri-list";
51
52    /**
53     * The MIME type for a clip holding an Intent.
54     */
55    public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
56
57    final CharSequence mLabel;
58    final String[] mMimeTypes;
59
60    /**
61     * Create a new clip.
62     *
63     * @param label Label to show to the user describing this clip.
64     * @param mimeTypes An array of MIME types this data is available as.
65     */
66    public ClipDescription(CharSequence label, String[] mimeTypes) {
67        if (mimeTypes == null) {
68            throw new NullPointerException("mimeTypes is null");
69        }
70        mLabel = label;
71        mMimeTypes = mimeTypes;
72    }
73
74    /**
75     * Create a copy of a ClipDescription.
76     */
77    public ClipDescription(ClipDescription o) {
78        mLabel = o.mLabel;
79        mMimeTypes = o.mMimeTypes;
80    }
81
82    /**
83     * Helper to compare two MIME types, where one may be a pattern.
84     * @param concreteType A fully-specified MIME type.
85     * @param desiredType A desired MIME type that may be a pattern such as *\/*.
86     * @return Returns true if the two MIME types match.
87     */
88    public static boolean compareMimeTypes(String concreteType, String desiredType) {
89        final int typeLength = desiredType.length();
90        if (typeLength == 3 && desiredType.equals("*/*")) {
91            return true;
92        }
93
94        final int slashpos = desiredType.indexOf('/');
95        if (slashpos > 0) {
96            if (typeLength == slashpos+2 && desiredType.charAt(slashpos+1) == '*') {
97                if (desiredType.regionMatches(0, concreteType, 0, slashpos+1)) {
98                    return true;
99                }
100            } else if (desiredType.equals(concreteType)) {
101                return true;
102            }
103        }
104
105        return false;
106    }
107
108    /**
109     * Return the label for this clip.
110     */
111    public CharSequence getLabel() {
112        return mLabel;
113    }
114
115    /**
116     * Check whether the clip description contains the given MIME type.
117     *
118     * @param mimeType The desired MIME type.  May be a pattern.
119     * @return Returns true if one of the MIME types in the clip description
120     * matches the desired MIME type, else false.
121     */
122    public boolean hasMimeType(String mimeType) {
123        for (int i=0; i<mMimeTypes.length; i++) {
124            if (compareMimeTypes(mMimeTypes[i], mimeType)) {
125                return true;
126            }
127        }
128        return false;
129    }
130
131    /**
132     * Filter the clip description MIME types by the given MIME type.  Returns
133     * all MIME types in the clip that match the given MIME type.
134     *
135     * @param mimeType The desired MIME type.  May be a pattern.
136     * @return Returns an array of all matching MIME types.  If there are no
137     * matching MIME types, null is returned.
138     */
139    public String[] filterMimeTypes(String mimeType) {
140        ArrayList<String> array = null;
141        for (int i=0; i<mMimeTypes.length; i++) {
142            if (compareMimeTypes(mMimeTypes[i], mimeType)) {
143                if (array == null) {
144                    array = new ArrayList<String>();
145                }
146                array.add(mMimeTypes[i]);
147            }
148        }
149        if (array == null) {
150            return null;
151        }
152        String[] rawArray = new String[array.size()];
153        array.toArray(rawArray);
154        return rawArray;
155    }
156
157    /**
158     * Return the number of MIME types the clip is available in.
159     */
160    public int getMimeTypeCount() {
161        return mMimeTypes.length;
162    }
163
164    /**
165     * Return one of the possible clip MIME types.
166     */
167    public String getMimeType(int index) {
168        return mMimeTypes[index];
169    }
170
171    /** @hide */
172    public void validate() {
173        if (mMimeTypes == null) {
174            throw new NullPointerException("null mime types");
175        }
176        if (mMimeTypes.length <= 0) {
177            throw new IllegalArgumentException("must have at least 1 mime type");
178        }
179        for (int i=0; i<mMimeTypes.length; i++) {
180            if (mMimeTypes[i] == null) {
181                throw new NullPointerException("mime type at " + i + " is null");
182            }
183        }
184    }
185
186    @Override
187    public String toString() {
188        StringBuilder b = new StringBuilder(128);
189
190        b.append("ClipDescription { ");
191        toShortString(b);
192        b.append(" }");
193
194        return b.toString();
195    }
196
197    /** @hide */
198    public boolean toShortString(StringBuilder b) {
199        boolean first = true;
200        for (int i=0; i<mMimeTypes.length; i++) {
201            if (!first) {
202                b.append(' ');
203            }
204            first = false;
205            b.append(mMimeTypes[i]);
206        }
207        if (mLabel != null) {
208            if (!first) {
209                b.append(' ');
210            }
211            first = false;
212            b.append('"');
213            b.append(mLabel);
214            b.append('"');
215        }
216        return !first;
217    }
218
219    @Override
220    public int describeContents() {
221        return 0;
222    }
223
224    @Override
225    public void writeToParcel(Parcel dest, int flags) {
226        TextUtils.writeToParcel(mLabel, dest, flags);
227        dest.writeStringArray(mMimeTypes);
228    }
229
230    ClipDescription(Parcel in) {
231        mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
232        mMimeTypes = in.createStringArray();
233    }
234
235    public static final Parcelable.Creator<ClipDescription> CREATOR =
236        new Parcelable.Creator<ClipDescription>() {
237
238            public ClipDescription createFromParcel(Parcel source) {
239                return new ClipDescription(source);
240            }
241
242            public ClipDescription[] newArray(int size) {
243                return new ClipDescription[size];
244            }
245        };
246}
247