ClipDescription.java revision 1040dc465cbf5ca8f834a87c949e476abefa3f76
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 */
30public class ClipDescription implements Parcelable {
31    /**
32     * The MIME type for a clip holding plain text.
33     */
34    public static final String MIMETYPE_TEXT_PLAIN = "text/plain";
35
36    /**
37     * The MIME type for a clip holding one or more URIs.  This should be
38     * used for URIs that are meaningful to a user (such as an http: URI).
39     * It should <em>not</em> be used for a content: URI that references some
40     * other piece of data; in that case the MIME type should be the type
41     * of the referenced data.
42     */
43    public static final String MIMETYPE_TEXT_URILIST = "text/uri-list";
44
45    /**
46     * The MIME type for a clip holding an Intent.
47     */
48    public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
49
50    final CharSequence mLabel;
51    final String[] mMimeTypes;
52
53    /**
54     * Create a new clip.
55     *
56     * @param label Label to show to the user describing this clip.
57     * @param mimeTypes An array of MIME types this data is available as.
58     */
59    public ClipDescription(CharSequence label, String[] mimeTypes) {
60        if (mimeTypes == null) {
61            throw new NullPointerException("mimeTypes is null");
62        }
63        mLabel = label;
64        mMimeTypes = mimeTypes;
65    }
66
67    /**
68     * Create a copy of a ClipDescription.
69     */
70    public ClipDescription(ClipDescription o) {
71        mLabel = o.mLabel;
72        mMimeTypes = o.mMimeTypes;
73    }
74
75    /**
76     * Helper to compare two MIME types, where one may be a pattern.
77     * @param concreteType A fully-specified MIME type.
78     * @param desiredType A desired MIME type that may be a pattern such as *\/*.
79     * @return Returns true if the two MIME types match.
80     */
81    public static boolean compareMimeTypes(String concreteType, String desiredType) {
82        final int typeLength = desiredType.length();
83        if (typeLength == 3 && desiredType.equals("*/*")) {
84            return true;
85        }
86
87        final int slashpos = desiredType.indexOf('/');
88        if (slashpos > 0) {
89            if (typeLength == slashpos+2 && desiredType.charAt(slashpos+1) == '*') {
90                if (desiredType.regionMatches(0, concreteType, 0, slashpos+1)) {
91                    return true;
92                }
93            } else if (desiredType.equals(concreteType)) {
94                return true;
95            }
96        }
97
98        return false;
99    }
100
101    /**
102     * Return the label for this clip.
103     */
104    public CharSequence getLabel() {
105        return mLabel;
106    }
107
108    /**
109     * Check whether the clip description contains the given MIME type.
110     *
111     * @param mimeType The desired MIME type.  May be a pattern.
112     * @return Returns true if one of the MIME types in the clip description
113     * matches the desired MIME type, else false.
114     */
115    public boolean hasMimeType(String mimeType) {
116        for (int i=0; i<mMimeTypes.length; i++) {
117            if (compareMimeTypes(mMimeTypes[i], mimeType)) {
118                return true;
119            }
120        }
121        return false;
122    }
123
124    /**
125     * Filter the clip description MIME types by the given MIME type.  Returns
126     * all MIME types in the clip that match the given MIME type.
127     *
128     * @param mimeType The desired MIME type.  May be a pattern.
129     * @return Returns an array of all matching MIME types.  If there are no
130     * matching MIME types, null is returned.
131     */
132    public String[] filterMimeTypes(String mimeType) {
133        ArrayList<String> array = null;
134        for (int i=0; i<mMimeTypes.length; i++) {
135            if (compareMimeTypes(mMimeTypes[i], mimeType)) {
136                if (array == null) {
137                    array = new ArrayList<String>();
138                }
139                array.add(mMimeTypes[i]);
140            }
141        }
142        if (array == null) {
143            return null;
144        }
145        String[] rawArray = new String[array.size()];
146        array.toArray(rawArray);
147        return rawArray;
148    }
149
150    /**
151     * Return the number of MIME types the clip is available in.
152     */
153    public int getMimeTypeCount() {
154        return mMimeTypes.length;
155    }
156
157    /**
158     * Return one of the possible clip MIME types.
159     */
160    public String getMimeType(int index) {
161        return mMimeTypes[index];
162    }
163
164    /** @hide */
165    public void validate() {
166        if (mMimeTypes == null) {
167            throw new NullPointerException("null mime types");
168        }
169        if (mMimeTypes.length <= 0) {
170            throw new IllegalArgumentException("must have at least 1 mime type");
171        }
172        for (int i=0; i<mMimeTypes.length; i++) {
173            if (mMimeTypes[i] == null) {
174                throw new NullPointerException("mime type at " + i + " is null");
175            }
176        }
177    }
178
179    @Override
180    public int describeContents() {
181        return 0;
182    }
183
184    @Override
185    public void writeToParcel(Parcel dest, int flags) {
186        TextUtils.writeToParcel(mLabel, dest, flags);
187        dest.writeStringArray(mMimeTypes);
188    }
189
190    ClipDescription(Parcel in) {
191        mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
192        mMimeTypes = in.createStringArray();
193    }
194
195    public static final Parcelable.Creator<ClipDescription> CREATOR =
196        new Parcelable.Creator<ClipDescription>() {
197
198            public ClipDescription createFromParcel(Parcel source) {
199                return new ClipDescription(source);
200            }
201
202            public ClipDescription[] newArray(int size) {
203                return new ClipDescription[size];
204            }
205        };
206}
207