Attachment.java revision 14977bf661dd6dc4d2a2414d0839e628ebed4d50
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.content.Intent; 1988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huangimport android.database.Cursor; 2088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huangimport android.net.Uri; 217aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereiraimport android.os.Parcel; 227aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereiraimport android.os.Parcelable; 23f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereiraimport android.text.TextUtils; 24f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 2588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huangimport com.android.mail.providers.UIProvider.AttachmentColumns; 2688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huangimport com.android.mail.providers.UIProvider.AttachmentDestination; 2788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huangimport com.android.mail.providers.UIProvider.AttachmentState; 28b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrookimport com.android.mail.utils.LogTag; 294c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sappersteinimport com.google.common.collect.Lists; 305a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 315a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport org.json.JSONArray; 325a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport org.json.JSONException; 335a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport org.json.JSONObject; 347b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 355a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport java.util.Collection; 365a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huangimport java.util.List; 374401c9049f0327019b0bfed554bf8ff5cdaa20e2Mindy Pereira 387aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereirapublic class Attachment implements Parcelable { 39f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira public static final int SERVER_ATTACHMENT = 0; 40f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira /** Extras are "<path>". */ 41f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira public static final int LOCAL_FILE = 1; 42f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 43b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook public static final String LOG_TAG = LogTag.getLogTag(); 445a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 457aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 4688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang * Attachment file name. See {@link AttachmentColumns#NAME}. 477aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 487aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public String name; 49f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 5088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 5188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang * Attachment size in bytes. See {@link AttachmentColumns#SIZE}. 5288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 5388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public int size; 54f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 557aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 565c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * The provider-generated URI for this Attachment. Must be globally unique. For local 575c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * attachments generated by the Compose UI prior to send/save, this field will be null. 585c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * 595c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang *@see AttachmentColumns#URI 607aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 6188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public Uri uri; 6288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 637aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 645c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * MIME type of the file. 655c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * 665c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#CONTENT_TYPE 677aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 681eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang public String contentType; 6988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 7088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 715c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#STATE 7288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 7388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public int state; 7488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 7588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 765c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#DESTINATION 7788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 7888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public int destination; 7988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 807aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 815c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#DOWNLOADED_SIZE 827aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 8388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public int downloadedSize; 8488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 8588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 865c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#CONTENT_URI 8788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 881eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang public Uri contentUri; 8988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 9088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 915c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * Might be null. 925c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * 935c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#THUMBNAIL_URI 9488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 9588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public Uri thumbnailUri; 9688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 9788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang /** 985c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * Might be null. 995c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * 1005c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang * @see AttachmentColumns#PREVIEW_INTENT 10188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang */ 10288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public Intent previewIntent; 10388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 1047aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 1057aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira * Part id of the attachment. 1067aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 1075c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang @Deprecated 1085c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang // partId is provider implementation specific. providers must uniquely identify Attachments 1095c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang // by uri. 1107aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public String partId; 11188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 1125c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang @Deprecated 1135c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang // this is a local file iff the provider 'uri' field is null. 11488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public int origin; 11588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 1167aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira /** 11788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang * Attachment origin info. 11888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang * TODO: do we want this? Or location? 1197aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira */ 1205c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang @Deprecated 12188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public String originExtras; 1227b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 1237aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public Attachment(Parcel in) { 1247aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira name = in.readString(); 12588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang size = in.readInt(); 12688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang uri = in.readParcelable(null); 1271eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang contentType = in.readString(); 12888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang state = in.readInt(); 12988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang destination = in.readInt(); 13088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang downloadedSize = in.readInt(); 1311eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang contentUri = in.readParcelable(null); 13288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang thumbnailUri = in.readParcelable(null); 13388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang previewIntent = in.readParcelable(null); 1347aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira partId = in.readString(); 135f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira origin = in.readInt(); 13688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang originExtras = in.readString(); 1377aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 1387b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 1397aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public Attachment() { 1407aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 1417b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 14288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public Attachment(Cursor cursor) { 14388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang if (cursor == null) { 14488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return; 14588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 14688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 1474c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein name = cursor.getString(cursor.getColumnIndex(AttachmentColumns.NAME)); 1484c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein size = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.SIZE)); 1494c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein uri = Uri.parse(cursor.getString(cursor.getColumnIndex(AttachmentColumns.URI))); 1504c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein contentType = cursor.getString(cursor.getColumnIndex(AttachmentColumns.CONTENT_TYPE)); 1514c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein state = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.STATE)); 1524c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein destination = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.DESTINATION)); 1534c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein downloadedSize = cursor.getInt(cursor.getColumnIndex(AttachmentColumns.DOWNLOADED_SIZE)); 1544c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein contentUri = parseOptionalUri( 1554c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein cursor.getString(cursor.getColumnIndex(AttachmentColumns.CONTENT_URI))); 15688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang thumbnailUri = parseOptionalUri( 1574c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein cursor.getString(cursor.getColumnIndex(AttachmentColumns.THUMBNAIL_URI))); 15888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang previewIntent = getOptionalIntentFromBlob( 1594c7d8b5f38bfa80192d457025b834c975d7d38a3Andrew Sapperstein cursor.getBlob(cursor.getColumnIndex(AttachmentColumns.PREVIEW_INTENT))); 16088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 16188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang // TODO: ensure that local files attached to a draft have sane values, like SAVED/EXTERNAL 16288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang // and that contentUri is populated 16388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 16488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 1655c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang @Deprecated 166f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira public Attachment(String attachmentString) { 1675e1a5b7a9d694ff812e65f4b1240366252cdcde7Paul Westbrook String[] attachmentValues = TextUtils.split(attachmentString, "\\|"); 168f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira if (attachmentValues != null) { 169f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira partId = attachmentValues[0]; 170f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira name = attachmentValues[1]; 1711eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang contentType = attachmentValues[2]; 172f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira try { 17388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang size = Integer.parseInt(attachmentValues[3]); 174f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } catch (NumberFormatException e) { 175f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira size = 0; 176f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } 1771eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang contentType = attachmentValues[4]; 178f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira origin = Integer.parseInt(attachmentValues[5]); 1791eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang contentUri = parseOptionalUri(attachmentValues[6]); 180f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira originExtras = attachmentValues[7]; 181f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } 182f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } 183f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 1845c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang @Deprecated 18588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public String toJoinedString() { 1861eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang // FIXME: contentType is read/written twice 18788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return TextUtils.join("|", Lists.newArrayList(partId == null ? "" : partId, 1881eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang name == null ? "" : name.replaceAll("[|\n]", ""), contentType, size, contentType, 1895c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang contentUri != null ? LOCAL_FILE : SERVER_ATTACHMENT, contentUri, 1905c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang originExtras == null ? "" : originExtras, "")); 19188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 19288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 19388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang private static Intent getOptionalIntentFromBlob(byte[] blob) { 19488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang if (blob == null) { 19588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return null; 19688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 19788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang final Parcel intentParcel = Parcel.obtain(); 19888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang intentParcel.unmarshall(blob, 0, blob.length); 19988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang final Intent intent = new Intent(); 20088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang intent.readFromParcel(intentParcel); 20188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return intent; 20288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 20388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 20488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang private static Uri parseOptionalUri(String uriString) { 20588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return uriString == null ? null : Uri.parse(uriString); 20688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 20788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 2087aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira @Override 2097aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public int describeContents() { 2107aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira return 0; 2117aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 2127b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 2137aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira @Override 2147aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public void writeToParcel(Parcel dest, int flags) { 2157aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira dest.writeString(name); 21688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeInt(size); 21788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeParcelable(uri, flags); 2181eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang dest.writeString(contentType); 21988fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeInt(state); 22088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeInt(destination); 22188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeInt(downloadedSize); 2221eb5f96d4e9c459d463d664563c755ec36f958f7Andy Huang dest.writeParcelable(contentUri, flags); 22388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeParcelable(thumbnailUri, flags); 22488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeParcelable(previewIntent, flags); 2257aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira dest.writeString(partId); 226f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira dest.writeInt(origin); 22788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang dest.writeString(originExtras); 2287aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 2297b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 2307aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public static final Creator<Attachment> CREATOR = new Creator<Attachment>() { 2317aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira @Override 2327aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public Attachment createFromParcel(Parcel source) { 2337aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira return new Attachment(source); 2347aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 2357b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira 2367aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira @Override 2377aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira public Attachment[] newArray(int size) { 2387aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira return new Attachment[size]; 2397aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira } 2407aee8f75f07eb39ecacdf0630d2199211aea5718Mindy Pereira }; 241f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 24288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public boolean isImage() { 243ac57b84f62110b1897176807ef1a02bd11675e71Mindy Pereira return !TextUtils.isEmpty(contentType) ? contentType.startsWith("image/") : false; 24488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 245f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 24688fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public boolean isDownloading() { 24788fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return state == AttachmentState.DOWNLOADING; 248f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } 249f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira 25088fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public boolean isPresentLocally() { 25188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return state == AttachmentState.SAVED || origin == LOCAL_FILE; 25288fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 25388fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang 25488fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public boolean isSavedToExternal() { 25588fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang return state == AttachmentState.SAVED && destination == AttachmentDestination.EXTERNAL; 256f944e9655562e321aff52fe5f437e1d2fa2950a9Mindy Pereira } 2574401c9049f0327019b0bfed554bf8ff5cdaa20e2Mindy Pereira 25888fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang public boolean canSave() { 259c6663c4f87b458aefef3213599ddea65e87ae223Andy Huang return origin != LOCAL_FILE && state != AttachmentState.DOWNLOADING && 260c6663c4f87b458aefef3213599ddea65e87ae223Andy Huang !isSavedToExternal(); 26188fc42e48ee4e927eb77e5cab23f2f5151cac649Andy Huang } 2624401c9049f0327019b0bfed554bf8ff5cdaa20e2Mindy Pereira 2634cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein public boolean shouldShowProgress() { 2644cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein return state == AttachmentState.DOWNLOADING 2654cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein && size > 0 && downloadedSize > 0 && downloadedSize < size; 266d0991f7f0d0882ac58dfdb1f8eb8e2a0abd573fcAndy Huang } 267d0991f7f0d0882ac58dfdb1f8eb8e2a0abd573fcAndy Huang 26814977bf661dd6dc4d2a2414d0839e628ebed4d50Andrew Sapperstein public boolean downloadFailed() { 26914977bf661dd6dc4d2a2414d0839e628ebed4d50Andrew Sapperstein return state == AttachmentState.FAILED; 27014977bf661dd6dc4d2a2414d0839e628ebed4d50Andrew Sapperstein } 27114977bf661dd6dc4d2a2414d0839e628ebed4d50Andrew Sapperstein 2725a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang // Methods to support JSON [de-]serialization of Attachment data 2735a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang // TODO: add support for origin/originExtras (and possibly partId?) or fold those fields into 2745a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang // other fields so Compose View can use JSON objects 2755a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 2765a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang public JSONObject toJSON() throws JSONException { 2775c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang return toJSON(name, size, uri, contentUri, contentType); 2785a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 2795a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 2805c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang public static JSONObject toJSON(String name, int size, Uri uri, Uri contentUri, 2815c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang String contentType) throws JSONException { 2825a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang final JSONObject result = new JSONObject(); 2835a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 2845a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang result.putOpt(AttachmentColumns.NAME, name); 2855a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang result.putOpt(AttachmentColumns.SIZE, size); 2865a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang if (uri != null) { 2875a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang result.putOpt(AttachmentColumns.URI, uri.toString()); 2885a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 2895c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang if (contentUri != null) { 2905c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang result.putOpt(AttachmentColumns.CONTENT_URI, contentUri.toString()); 2915c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang } 2925a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang result.putOpt(AttachmentColumns.CONTENT_TYPE, contentType); 2935a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 2945a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang return result; 2955a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 2965a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 2975a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang public Attachment(JSONObject srcJson) { 2985a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang name = srcJson.optString(AttachmentColumns.NAME, null); 2995a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang size = srcJson.optInt(AttachmentColumns.SIZE); 3005a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang uri = parseOptionalUri(srcJson, AttachmentColumns.URI); 3015c5fd571b40a15b95ea5a5d6033f377706ffd0fbAndy Huang contentUri = parseOptionalUri(srcJson, AttachmentColumns.CONTENT_URI); 3025a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang contentType = srcJson.optString(AttachmentColumns.CONTENT_TYPE, null); 3035a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3045a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3055a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang private static Uri parseOptionalUri(JSONObject srcJson, String key) { 3065a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang final String uriStr = srcJson.optString(key, null); 3075a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang return uriStr == null ? null : Uri.parse(uriStr); 3085a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3095a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3105a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang public static String toJSONArray(Collection<Attachment> attachments) { 3115a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang final JSONArray result = new JSONArray(); 3125a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang try { 3135a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang for (Attachment attachment : attachments) { 3145a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang result.put(attachment.toJSON()); 3155a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3165a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } catch (JSONException e) { 3175a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang throw new IllegalArgumentException(e); 3185a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3195a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang return result.toString(); 3205a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3215a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3225a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang public static List<Attachment> fromJSONArray(String jsonArrayStr) { 3235a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang final List<Attachment> results = Lists.newArrayList(); 3245a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang try { 3255a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang final JSONArray arr = new JSONArray(jsonArrayStr); 3265a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3275a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang for (int i = 0; i < arr.length(); i++) { 3285a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang results.add(new Attachment(arr.getJSONObject(i))); 3295a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3305a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang 3315a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } catch (JSONException e) { 3325a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang throw new IllegalArgumentException(e); 3335a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3345a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang return results; 3355a9290731bf565538a9cf91892346c7a6f4da0ecAndy Huang } 3367b56a61174eeb202eea468b7f68b79729737ded2Mindy Pereira} 337