Handle attachments on sent messages.

Change-Id: I13a2b9250b61fd059b4b3f92caff03c7a3614881
diff --git a/src/com/android/mail/compose/AttachmentsView.java b/src/com/android/mail/compose/AttachmentsView.java
index 94a4809..54b4c7f 100644
--- a/src/com/android/mail/compose/AttachmentsView.java
+++ b/src/com/android/mail/compose/AttachmentsView.java
@@ -177,7 +177,7 @@
      * @return int size of the attachment added.
      * @throws AttachmentFailureException if an error occurs adding the attachment.
      */
-    public long addAttachment(Account account, Uri uri, boolean doSave)
+    public long addAttachment(Account account, Uri uri, boolean doSave, boolean isLocal)
             throws AttachmentFailureException {
         final ContentResolver contentResolver = getContext().getContentResolver();
         String contentType = contentResolver.getType(uri);
@@ -194,6 +194,7 @@
         attachment.mimeType = contentType;
         attachment.size = 0;
         attachment.contentUri = uri.toString();
+        attachment.origin = isLocal ? Attachment.LOCAL_FILE : Attachment.SERVER_ATTACHMENT;
         attachment.originExtras = uri.toString();
 
         Cursor metadataCursor = null;
@@ -286,7 +287,7 @@
                 while (attachmentCursor.moveToNext()) {
                     attachmentUri = attachmentCursor.getString(UIProvider.ATTACHMENT_URI_COLUMN);
                     if (!TextUtils.isEmpty(attachmentUri)) {
-                        addAttachment(account, Uri.parse(attachmentUri), false);
+                        addAttachment(account, Uri.parse(attachmentUri), false, false);
                     }
                 }
             } catch (AttachmentFailureException e) {
diff --git a/src/com/android/mail/compose/ComposeActivity.java b/src/com/android/mail/compose/ComposeActivity.java
index ecce59e..fb13ba9 100644
--- a/src/com/android/mail/compose/ComposeActivity.java
+++ b/src/com/android/mail/compose/ComposeActivity.java
@@ -401,7 +401,8 @@
     public void addAttachmentAndUpdateView(Intent data) {
         Uri uri = data != null ? data.getData() : null;
         try {
-            long size =  mAttachmentsView.addAttachment(mAccount, uri, false /* doSave */);
+            long size =  mAttachmentsView.addAttachment(mAccount, uri, false /* doSave */,
+                    true /* local file */);
             if (size > 0) {
                 mAttachmentsChanged = true;
                 updateSaveUi();
@@ -1068,6 +1069,7 @@
         }
         MessageModification.putBody(values, Html.fromHtml(fullBody.toString()).toString());
         MessageModification.putBodyHtml(values, fullBody.toString());
+        MessageModification.putAttachments(values, attachments);
 
        SendOrSaveMessage sendOrSaveMessage = new SendOrSaveMessage(account, selectedAccount,
                values, refMessageId, save);
diff --git a/src/com/android/mail/providers/Attachment.java b/src/com/android/mail/providers/Attachment.java
index a3faad7..d3e567e 100644
--- a/src/com/android/mail/providers/Attachment.java
+++ b/src/com/android/mail/providers/Attachment.java
@@ -17,12 +17,22 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.google.common.collect.Lists;
 
 public class Attachment implements Parcelable {
+    public static final int SERVER_ATTACHMENT = 0;
+    /** Extras are "<path>". */
+    public static final int  LOCAL_FILE = 1;
+
     /**
      * Attachment name.
      */
     public String name;
+
+    public int origin;
+
     /**
      * Attachment origin info.
      * TODO: do we want this? Or location?
@@ -57,11 +67,30 @@
         partId = in.readString();
         isSynced = in.readInt() == 1;
         size = in.readLong();
+        origin = in.readInt();
     }
 
     public Attachment() {
     }
 
+    public Attachment(String attachmentString) {
+        String[] attachmentValues = attachmentString.split("\\|");
+        if (attachmentValues != null) {
+            partId = attachmentValues[0];
+            name = attachmentValues[1];
+            mimeType = attachmentValues[2];
+            try {
+                size = Long.parseLong(attachmentValues[3]);
+            } catch (NumberFormatException e) {
+                size = 0;
+            }
+            mimeType = attachmentValues[4];
+            origin = Integer.parseInt(attachmentValues[5]);
+            contentUri = attachmentValues[6];
+            originExtras = attachmentValues[7];
+        }
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -76,6 +105,7 @@
         dest.writeString(partId);
         dest.writeInt(isSynced? 1 : 0);
         dest.writeLong(size);
+        dest.writeInt(origin);
     }
 
     public static final Creator<Attachment> CREATOR = new Creator<Attachment>() {
@@ -89,4 +119,16 @@
             return new Attachment[size];
         }
     };
+
+
+    public String toJoinedString() {
+        return TextUtils.join("|", Lists.newArrayList(partId == null ? "" : partId,
+                name == null ? "" : name.replaceAll("[|\n]", ""), mimeType, size, mimeType,
+                origin + "", contentUri, TextUtils.isEmpty(originExtras) ? contentUri
+                        : originExtras, ""));
+    }
+
+    public boolean isImage() {
+        return mimeType.startsWith("image");
+    }
 }
diff --git a/src/com/android/mail/providers/Message.java b/src/com/android/mail/providers/Message.java
index 0ccc872..9a428c6 100644
--- a/src/com/android/mail/providers/Message.java
+++ b/src/com/android/mail/providers/Message.java
@@ -43,6 +43,7 @@
     public boolean hasAttachments;
     public String attachmentListUri;
     public long messageFlags;
+    public String joinedAttachmentInfos;
 
     @Override
     public int describeContents() {
@@ -72,6 +73,10 @@
         dest.writeInt(hasAttachments ? 1 : 0);
         dest.writeString(attachmentListUri);
         dest.writeLong(messageFlags);
+        dest.writeString(joinedAttachmentInfos);
+    }
+
+    public Message() {
     }
 
     private Message(Parcel in) {
@@ -96,6 +101,7 @@
         hasAttachments = in.readInt() != 0;
         attachmentListUri = in.readString();
         messageFlags = in.readLong();
+        joinedAttachmentInfos = in.readString();
     }
 
     @Override
@@ -146,7 +152,8 @@
             hasAttachments = cursor.getInt(UIProvider.MESSAGE_HAS_ATTACHMENTS_COLUMN) != 0;
             attachmentListUri = cursor.getString(UIProvider.MESSAGE_ATTACHMENT_LIST_URI_COLUMN);
             messageFlags = cursor.getLong(UIProvider.MESSAGE_FLAGS_COLUMN);
+            joinedAttachmentInfos = cursor
+                    .getString(UIProvider.MESSAGE_JOINED_ATTACHMENT_INFOS_COLUMN);
         }
     }
-
 }
diff --git a/src/com/android/mail/providers/MessageModification.java b/src/com/android/mail/providers/MessageModification.java
index f542731..0d3e51e 100644
--- a/src/com/android/mail/providers/MessageModification.java
+++ b/src/com/android/mail/providers/MessageModification.java
@@ -22,6 +22,8 @@
 import com.android.mail.providers.UIProvider.DraftType;
 import com.android.mail.providers.UIProvider.MessageColumns;
 
+import java.util.List;
+
 /**
  * A helper class for creating or updating messages. Use the putXxx methods to
  * provide initial or new values for the message. Then save or send the message.
@@ -113,4 +115,23 @@
     public static void putBodyHtml(ContentValues values, String body) {
         values.put(MessageColumns.BODY_HTML, body);
     }
+
+    public static void putAttachments(ContentValues values, List<Attachment> attachments) {
+        values.put(
+                MessageColumns.JOINED_ATTACHMENT_INFOS, joinedAttachmentsString(attachments));
+    }
+
+    /**
+     * The string produced here is parsed by Gmail.MessageCursor#getAttachmentInfos.
+     */
+    public static String joinedAttachmentsString(List<Attachment> attachments) {
+        StringBuilder attachmentsSb = new StringBuilder();
+        for (Attachment attachment : attachments) {
+            if (attachmentsSb.length() != 0) {
+                attachmentsSb.append(UIProvider.MESSAGE_ATTACHMENT_INFO_SEPARATOR);
+            }
+            attachmentsSb.append(attachment.toJoinedString());
+        }
+        return attachmentsSb.toString();
+    }
 }
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index 6aa6657..ae73db1 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -375,9 +375,12 @@
         MessageColumns.APPEND_REF_MESSAGE_CONTENT,
         MessageColumns.HAS_ATTACHMENTS,
         MessageColumns.ATTACHMENT_LIST_URI,
-        MessageColumns.MESSAGE_FLAGS
+        MessageColumns.MESSAGE_FLAGS,
+        MessageColumns.JOINED_ATTACHMENT_INFOS
     };
 
+    /** Separates attachment info parts in strings in a message. */
+    public static final String MESSAGE_ATTACHMENT_INFO_SEPARATOR = "\n";
     public static final String MESSAGE_LIST_TYPE =
             "vnd.android.cursor.dir/vnd.com.android.mail.message";
     public static final String MESSAGE_TYPE =
@@ -404,6 +407,7 @@
     public static final int MESSAGE_HAS_ATTACHMENTS_COLUMN = 18;
     public static final int MESSAGE_ATTACHMENT_LIST_URI_COLUMN = 19;
     public static final int MESSAGE_FLAGS_COLUMN = 20;
+    public static final int MESSAGE_JOINED_ATTACHMENT_INFOS_COLUMN = 21;
 
     public static final class MessageFlags {
         public static final int STARRED =       1 << 0;
@@ -496,6 +500,11 @@
          * This long column is a bit field of flags defined in {@link MessageFlags}.
          */
         public static final String MESSAGE_FLAGS = "messageFlags";
+        /**
+         * This string column contains a specially formatted string representing all
+         * attachments that we added to a message that is being sent or saved.
+         */
+        public static String JOINED_ATTACHMENT_INFOS;
 
         private MessageColumns() {}
     }
@@ -520,6 +529,9 @@
     public static final int ATTACHMENT_NAME_COLUMN = 1;
     public static final int ATTACHMENT_SIZE_COLUMN = 2;
     public static final int ATTACHMENT_URI_COLUMN = 3;
+    public static final int ATTACHMENT_ORIGIN_EXTRAS_COLUMN = 4;
+    public static final int ATTACHMENT_CONTENT_TYPE_COLUMN = 5;
+    public static final int ATTACHMENT_SYNCED_COLUMN = 6;
 
     public static final class AttachmentColumns {
         public static final String NAME = "name";
diff --git a/src/com/android/mail/utils/AttachmentUtils.java b/src/com/android/mail/utils/AttachmentUtils.java
index ad7714e..d60e292 100644
--- a/src/com/android/mail/utils/AttachmentUtils.java
+++ b/src/com/android/mail/utils/AttachmentUtils.java
@@ -16,10 +16,15 @@
 package com.android.mail.utils;
 
 import android.content.Context;
+import android.text.TextUtils;
 
 import com.android.mail.R;
+import com.android.mail.providers.Attachment;
+import com.android.mail.providers.Message;
+import com.android.mail.providers.UIProvider;
 
 import java.text.DecimalFormat;
+import java.util.ArrayList;
 
 public class AttachmentUtils {
     private static final int KILO = 1024;
@@ -40,4 +45,25 @@
                     + context.getString(R.string.megabytes);
         }
     }
+
+    /**
+     * Translate attachment info from a message into attachment objects.
+     * @param msg
+     * @return list of Attachment objects, or an empty list if the message
+     * had no associated attachments.
+     */
+    public static ArrayList<Attachment> getAttachmentsFromMessage(Message msg) {
+        String infoString = msg.joinedAttachmentInfos;
+        ArrayList<Attachment> infoList = new ArrayList<Attachment>();
+        if (!TextUtils.isEmpty(infoString)) {
+            Attachment attachment;
+            String[] attachmentStrings = infoString
+                    .split(UIProvider.MESSAGE_ATTACHMENT_INFO_SEPARATOR);
+            for (String attachmentString : attachmentStrings) {
+                attachment = new Attachment(attachmentString);
+                infoList.add(attachment);
+            }
+        }
+        return infoList;
+    }
 }