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