ClipDescription.java revision 3aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45
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 int describeContents() {
188        return 0;
189    }
190
191    @Override
192    public void writeToParcel(Parcel dest, int flags) {
193        TextUtils.writeToParcel(mLabel, dest, flags);
194        dest.writeStringArray(mMimeTypes);
195    }
196
197    ClipDescription(Parcel in) {
198        mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
199        mMimeTypes = in.createStringArray();
200    }
201
202    public static final Parcelable.Creator<ClipDescription> CREATOR =
203        new Parcelable.Creator<ClipDescription>() {
204
205            public ClipDescription createFromParcel(Parcel source) {
206                return new ClipDescription(source);
207            }
208
209            public ClipDescription[] newArray(int size) {
210                return new ClipDescription[size];
211            }
212        };
213}
214