Attachment.java revision 856200a2abc6a90711f6eb99fc0340dd75ef6e9b
17b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira/** 27b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * Copyright (c) 2011, Google Inc. 37b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * 47b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License"); 57b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * you may not use this file except in compliance with the License. 67b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * You may obtain a copy of the License at 77b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * 87b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * http://www.apache.org/licenses/LICENSE-2.0 97b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * 107b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * Unless required by applicable law or agreed to in writing, software 117b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS, 127b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * See the License for the specific language governing permissions and 147b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira * limitations under the License. 157b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira */ 1630e2c24b056542f3b1b438aeb798305d1226d0c8Andy Huangpackage com.android.mail.providers; 177b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 1888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huangimport android.database.Cursor; 1988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huangimport android.net.Uri; 207aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereiraimport android.os.Parcel; 217aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereiraimport android.os.Parcelable; 22f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereiraimport android.text.TextUtils; 23f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 2488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huangimport com.android.mail.providers.UIProvider.AttachmentColumns; 2588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huangimport com.android.mail.providers.UIProvider.AttachmentDestination; 2688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huangimport com.android.mail.providers.UIProvider.AttachmentState; 27b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrookimport com.android.mail.utils.LogTag; 28f467d10bb05a8df6ac3c8279f6fda24e89b87482Paul Westbrookimport com.android.mail.utils.LogUtils; 29856200a2abc6a90711f6eb99fc0340dd75ef6e9bMark Weiimport com.android.mail.utils.MimeType; 304f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huangimport com.android.mail.utils.Utils; 314c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sappersteinimport com.google.common.collect.Lists; 325a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 335a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport org.json.JSONArray; 345a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport org.json.JSONException; 355a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport org.json.JSONObject; 367b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 375a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport java.util.Collection; 385a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport java.util.List; 394401c9049f0327019b0bfed554bf8ff5cdaa20e2Mindy Pereira 407aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereirapublic class Attachment implements Parcelable { 41f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira public static final int SERVER_ATTACHMENT = 0; 42f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira /** Extras are "<path>". */ 43f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira public static final int LOCAL_FILE = 1; 44f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 45b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook public static final String LOG_TAG = LogTag.getLogTag(); 465a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 477aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 4888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang * Attachment file name. See {@link AttachmentColumns#NAME}. 497aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 507aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public String name; 51f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 5288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 5388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang * Attachment size in bytes. See {@link AttachmentColumns#SIZE}. 5488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 5588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public int size; 56f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 577aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 585c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * The provider-generated URI for this Attachment. Must be globally unique. For local 595c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * attachments generated by the Compose UI prior to send/save, this field will be null. 605c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * 615c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang *@see AttachmentColumns#URI 627aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 6388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public Uri uri; 6488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 657aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 665c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * MIME type of the file. 675c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * 685c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#CONTENT_TYPE 697aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 701eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang public String contentType; 7188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 7288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 735c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#STATE 7488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 7588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public int state; 7688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 7788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 785c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#DESTINATION 7988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 8088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public int destination; 8188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 827aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 835c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#DOWNLOADED_SIZE 847aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 8588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public int downloadedSize; 8688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 8788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 885c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#CONTENT_URI 8988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 901eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang public Uri contentUri; 9188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 9288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 935c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * Might be null. 945c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * 955c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#THUMBNAIL_URI 9688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 9788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public Uri thumbnailUri; 9888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 9988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 1005c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * Might be null. 1015c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * 102d49db8e3c4fff459f4ae3869ea80d083461eda2cPaul Westbrook * @see AttachmentColumns# PREVIEW_INTENT_URI 10388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 104d49db8e3c4fff459f4ae3869ea80d083461eda2cPaul Westbrook public Uri previewIntentUri; 10588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 1067aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 1077aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira * Part id of the attachment. 1087aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 1095c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang @Deprecated 1105c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang // partId is provider implementation specific. providers must uniquely identify Attachments 1115c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang // by uri. 1127aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public String partId; 11388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 1145c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang @Deprecated 1155c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang // this is a local file iff the provider 'uri' field is null. 11688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public int origin; 11788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 1187aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 11988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang * Attachment origin info. 12088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang * TODO: do we want this? Or location? 1217aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 1225c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang @Deprecated 12388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public String originExtras; 1247b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 1254f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang private transient Uri mIdentifierUri; 1264f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang 1277aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public Attachment(Parcel in) { 1287aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira name = in.readString(); 12988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang size = in.readInt(); 13088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang uri = in.readParcelable(null); 1311eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang contentType = in.readString(); 13288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang state = in.readInt(); 13388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang destination = in.readInt(); 13488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang downloadedSize = in.readInt(); 1351eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang contentUri = in.readParcelable(null); 13688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang thumbnailUri = in.readParcelable(null); 137d49db8e3c4fff459f4ae3869ea80d083461eda2cPaul Westbrook previewIntentUri = in.readParcelable(null); 1387aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira partId = in.readString(); 139f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira origin = in.readInt(); 14088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang originExtras = in.readString(); 1417aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 1427b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 1437aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public Attachment() { 1447aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 1457b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 14688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public Attachment(Cursor cursor) { 14788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang if (cursor == null) { 14888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return; 14988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 15088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 1514c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein name = cursor.getString(cursor.getColumnIndex(AttachmentColumns.NAME)); 1524c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein size = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.SIZE)); 1534c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein uri = Uri.parse(cursor.getString(cursor.getColumnIndex(AttachmentColumns.URI))); 1544c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein contentType = cursor.getString(cursor.getColumnIndex(AttachmentColumns.CONTENT_TYPE)); 1554c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein state = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.STATE)); 1564c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein destination = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.DESTINATION)); 1574c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein downloadedSize = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.DOWNLOADED_SIZE)); 1584c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein contentUri = parseOptionalUri( 1594c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein cursor.getString(cursor.getColumnIndex(AttachmentColumns.CONTENT_URI))); 16088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang thumbnailUri = parseOptionalUri( 1614c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein cursor.getString(cursor.getColumnIndex(AttachmentColumns.THUMBNAIL_URI))); 162d49db8e3c4fff459f4ae3869ea80d083461eda2cPaul Westbrook previewIntentUri = parseOptionalUri( 163d49db8e3c4fff459f4ae3869ea80d083461eda2cPaul Westbrook cursor.getString(cursor.getColumnIndex(AttachmentColumns.PREVIEW_INTENT_URI))); 16488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 16588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang // TODO: ensure that local files attached to a draft have sane values, like SAVED/EXTERNAL 16688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang // and that contentUri is populated 16788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 16888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 1695c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang @Deprecated 170f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira public Attachment(String attachmentString) { 1715e1a5b7a9d694ff812e65f4b1240366252cdcde7Paul Westbrook String[] attachmentValues = TextUtils.split(attachmentString, "\\|"); 172f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira if (attachmentValues != null) { 173f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira partId = attachmentValues[0]; 174f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira name = attachmentValues[1]; 1751eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang contentType = attachmentValues[2]; 176f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira try { 17788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang size = Integer.parseInt(attachmentValues[3]); 178f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } catch (NumberFormatException e) { 179f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira size = 0; 180f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } 1811eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang contentType = attachmentValues[4]; 182f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira origin = Integer.parseInt(attachmentValues[5]); 1831eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang contentUri = parseOptionalUri(attachmentValues[6]); 184f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira originExtras = attachmentValues[7]; 185f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } 186f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } 187f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 1885c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang @Deprecated 18988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public String toJoinedString() { 1901eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang // FIXME: contentType is read/written twice 19188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return TextUtils.join("|", Lists.newArrayList(partId == null ? "" : partId, 1921eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang name == null ? "" : name.replaceAll("[|\n]", ""), contentType, size, contentType, 1935c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang contentUri != null ? LOCAL_FILE : SERVER_ATTACHMENT, contentUri, 1945c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang originExtras == null ? "" : originExtras, "")); 19588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 19688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 197f467d10bb05a8df6ac3c8279f6fda24e89b87482Paul Westbrook @Override 198f467d10bb05a8df6ac3c8279f6fda24e89b87482Paul Westbrook public String toString() { 199f467d10bb05a8df6ac3c8279f6fda24e89b87482Paul Westbrook try { 200b0f4a7da15313c9f1316ab72230bb44cc218ffd5Paul Westbrook final JSONObject jsonObject = toJSON(); 201b0f4a7da15313c9f1316ab72230bb44cc218ffd5Paul Westbrook // Add some additional fields that are helpful when debugging issues 202b0f4a7da15313c9f1316ab72230bb44cc218ffd5Paul Westbrook jsonObject.put(AttachmentColumns.DOWNLOADED_SIZE, downloadedSize); 203b0f4a7da15313c9f1316ab72230bb44cc218ffd5Paul Westbrook jsonObject.put(AttachmentColumns.DESTINATION, destination); 204b0f4a7da15313c9f1316ab72230bb44cc218ffd5Paul Westbrook jsonObject.put(AttachmentColumns.THUMBNAIL_URI, thumbnailUri); 205b0f4a7da15313c9f1316ab72230bb44cc218ffd5Paul Westbrook jsonObject.put(AttachmentColumns.PREVIEW_INTENT_URI, previewIntentUri); 206b0f4a7da15313c9f1316ab72230bb44cc218ffd5Paul Westbrook return jsonObject.toString(); 207f467d10bb05a8df6ac3c8279f6fda24e89b87482Paul Westbrook } catch (JSONException e) { 208f467d10bb05a8df6ac3c8279f6fda24e89b87482Paul Westbrook LogUtils.e(LOG_TAG, e, "JSONException in toString"); 209f467d10bb05a8df6ac3c8279f6fda24e89b87482Paul Westbrook return super.toString(); 210f467d10bb05a8df6ac3c8279f6fda24e89b87482Paul Westbrook } 211f467d10bb05a8df6ac3c8279f6fda24e89b87482Paul Westbrook } 212f467d10bb05a8df6ac3c8279f6fda24e89b87482Paul Westbrook 21388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang private static Uri parseOptionalUri(String uriString) { 21488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return uriString == null ? null : Uri.parse(uriString); 21588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 21688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 2177aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira @Override 2187aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public int describeContents() { 2197aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira return 0; 2207aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 2217b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 2227aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira @Override 2237aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public void writeToParcel(Parcel dest, int flags) { 2247aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira dest.writeString(name); 22588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeInt(size); 22688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeParcelable(uri, flags); 2271eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang dest.writeString(contentType); 22888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeInt(state); 22988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeInt(destination); 23088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeInt(downloadedSize); 2311eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang dest.writeParcelable(contentUri, flags); 23288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeParcelable(thumbnailUri, flags); 233d49db8e3c4fff459f4ae3869ea80d083461eda2cPaul Westbrook dest.writeParcelable(previewIntentUri, flags); 2347aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira dest.writeString(partId); 235f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira dest.writeInt(origin); 23688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeString(originExtras); 2377aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 2387b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 2397aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public static final Creator<Attachment> CREATOR = new Creator<Attachment>() { 2407aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira @Override 2417aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public Attachment createFromParcel(Parcel source) { 2427aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira return new Attachment(source); 2437aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 2447b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 2457aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira @Override 2467aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public Attachment[] newArray(int size) { 2477aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira return new Attachment[size]; 2487aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 2497aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira }; 250f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 25188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public boolean isImage() { 252ac57b84f62110b1897176807ef1a02bd11675e71Mindy Pereira return !TextUtils.isEmpty(contentType) ? contentType.startsWith("image/") : false; 25388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 254f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 25588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public boolean isDownloading() { 25688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return state == AttachmentState.DOWNLOADING; 257f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } 258f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 25988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public boolean isPresentLocally() { 26088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return state == AttachmentState.SAVED || origin == LOCAL_FILE; 26188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 26288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 26388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public boolean isSavedToExternal() { 26488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return state == AttachmentState.SAVED && destination == AttachmentDestination.EXTERNAL; 265f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } 2664401c9049f0327019b0bfed554bf8ff5cdaa20e2Mindy Pereira 267856200a2abc6a90711f6eb99fc0340dd75ef6e9bMark Wei public boolean isInstallable() { 268856200a2abc6a90711f6eb99fc0340dd75ef6e9bMark Wei return MimeType.isInstallable(contentType); 269856200a2abc6a90711f6eb99fc0340dd75ef6e9bMark Wei } 270856200a2abc6a90711f6eb99fc0340dd75ef6e9bMark Wei 27188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public boolean canSave() { 272856200a2abc6a90711f6eb99fc0340dd75ef6e9bMark Wei return origin != LOCAL_FILE && !isSavedToExternal() && !isInstallable(); 27388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 2744401c9049f0327019b0bfed554bf8ff5cdaa20e2Mindy Pereira 275d2f279ff7f4d257ff268b27be7379d4195354798Sara Ting public boolean canShare() { 276d2f279ff7f4d257ff268b27be7379d4195354798Sara Ting return isPresentLocally() && contentUri != null; 277d2f279ff7f4d257ff268b27be7379d4195354798Sara Ting } 278d2f279ff7f4d257ff268b27be7379d4195354798Sara Ting 2794cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein public boolean shouldShowProgress() { 2804cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein return state == AttachmentState.DOWNLOADING 2814cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein && size > 0 && downloadedSize > 0 && downloadedSize < size; 282d0991f7f0d0882ac58dfdb1f8eb8e2a0abd573fcAndy Huang } 283d0991f7f0d0882ac58dfdb1f8eb8e2a0abd573fcAndy Huang 28414977bf661dd6dc4d2a2414d0839e628ebed4d50Andrew Sapperstein public boolean downloadFailed() { 28514977bf661dd6dc4d2a2414d0839e628ebed4d50Andrew Sapperstein return state == AttachmentState.FAILED; 28614977bf661dd6dc4d2a2414d0839e628ebed4d50Andrew Sapperstein } 28714977bf661dd6dc4d2a2414d0839e628ebed4d50Andrew Sapperstein 288d6318e56adadeff4106e9696b5330239175487b1Andrew Sapperstein public boolean canPreview() { 289d6318e56adadeff4106e9696b5330239175487b1Andrew Sapperstein return previewIntentUri != null; 290d6318e56adadeff4106e9696b5330239175487b1Andrew Sapperstein } 291d6318e56adadeff4106e9696b5330239175487b1Andrew Sapperstein 2924f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang /** 2934f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang * Returns a stable identifier URI for this attachment. 2944f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang * 2954f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang * TODO: make the uri field stable, and put provider-specific opaque bits and bobs elsewhere 2964f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang */ 2974f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang public Uri getIdentifierUri() { 2984f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang if (mIdentifierUri == null) { 2994f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang mIdentifierUri = Utils.isEmpty(uri) ? Uri.EMPTY : uri.buildUpon().clearQuery().build(); 3004f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang } 3014f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang return mIdentifierUri; 3024f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang } 3034f24bb48ab2c3e8fbda2af1e1d8fda79e8a458e7Andy Huang 3045a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang // Methods to support JSON [de-]serialization of Attachment data 3055a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang // TODO: add support for origin/originExtras (and possibly partId?) or fold those fields into 3065a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang // other fields so Compose View can use JSON objects 3075a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3085a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang public JSONObject toJSON() throws JSONException { 3098081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook return toJSON(name, size, uri, contentUri, contentType, state); 3105a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3115a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3125c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang public static JSONObject toJSON(String name, int size, Uri uri, Uri contentUri, 3138081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook String contentType, Integer state) throws JSONException { 3145a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang final JSONObject result = new JSONObject(); 3155a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3165a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang result.putOpt(AttachmentColumns.NAME, name); 3175a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang result.putOpt(AttachmentColumns.SIZE, size); 3185a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang if (uri != null) { 3195a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang result.putOpt(AttachmentColumns.URI, uri.toString()); 3205a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3215c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang if (contentUri != null) { 3225c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang result.putOpt(AttachmentColumns.CONTENT_URI, contentUri.toString()); 3235c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang } 3245a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang result.putOpt(AttachmentColumns.CONTENT_TYPE, contentType); 3258081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook if (state != null) { 3268081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook result.put(AttachmentColumns.STATE, state.intValue()); 3278081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook } 3285a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3295a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang return result; 3305a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3315a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3325a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang public Attachment(JSONObject srcJson) { 3335a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang name = srcJson.optString(AttachmentColumns.NAME, null); 3345a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang size = srcJson.optInt(AttachmentColumns.SIZE); 3355a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang uri = parseOptionalUri(srcJson, AttachmentColumns.URI); 3365c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang contentUri = parseOptionalUri(srcJson, AttachmentColumns.CONTENT_URI); 3375a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang contentType = srcJson.optString(AttachmentColumns.CONTENT_TYPE, null); 3388081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook if (srcJson.has(AttachmentColumns.STATE)) { 3398081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook state = srcJson.optInt(AttachmentColumns.STATE); 3408081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook } 3415a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3425a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3435a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang private static Uri parseOptionalUri(JSONObject srcJson, String key) { 3445a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang final String uriStr = srcJson.optString(key, null); 3455a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang return uriStr == null ? null : Uri.parse(uriStr); 3465a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3475a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3485a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang public static String toJSONArray(Collection<Attachment> attachments) { 3495a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang final JSONArray result = new JSONArray(); 3505a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang try { 3515a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang for (Attachment attachment : attachments) { 3525a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang result.put(attachment.toJSON()); 3535a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3545a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } catch (JSONException e) { 3555a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang throw new IllegalArgumentException(e); 3565a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3575a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang return result.toString(); 3585a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3595a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3605a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang public static List<Attachment> fromJSONArray(String jsonArrayStr) { 3615a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang final List<Attachment> results = Lists.newArrayList(); 3625a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang try { 3635a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang final JSONArray arr = new JSONArray(jsonArrayStr); 3645a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3655a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang for (int i = 0; i < arr.length(); i++) { 3665a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang results.add(new Attachment(arr.getJSONObject(i))); 3675a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3685a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3695a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } catch (JSONException e) { 3705a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang throw new IllegalArgumentException(e); 3715a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3725a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang return results; 3735a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3747b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira} 375