Finish Attachment support for EAS accounts.

* Change service API to allow caller to supply complete target path/file
* Also allow caller to supply the final content_uri
* In MessageView, use full integration with EAS service API and
  attachments content provider to enable:
  * Save: Only works on SD card
  * View: Works w/o SD card using content provider & intents
  * Thumbnail previews
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index 0d339d6..a9e45e0 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -268,7 +268,6 @@
      * Loads an attachment, based on the PartRequest passed in.  The PartRequest is basically our
      * wrapper for Attachment
      * @param req the part (attachment) to be retrieved
-     * @param external whether the attachment should be loaded to external storage
      * @throws IOException
      */
     protected void getAttachment(PartRequest req) throws IOException {
@@ -291,8 +290,15 @@
                 Log.v(TAG, "Attachment code: " + status + ", Length: " + len + ", Type: " + type);
             }
             InputStream is = res.getEntity().getContent();
-            File f = createUniqueFileInternal(req.dir, att.mFileName);
+            File f = (req.destination != null)
+                    ? new File(req.destination)
+                    : createUniqueFileInternal(req.destination, att.mFileName);
             if (f != null) {
+                // Ensure that the target directory exists
+                File destDir = f.getParentFile();
+                if (!destDir.exists()) {
+                    destDir.mkdirs();
+                }
                 FileOutputStream os = new FileOutputStream(f);
                 if (len > 0) {
                     try {
@@ -318,8 +324,11 @@
 
                 // EmailProvider will throw an exception if we try to update an unsaved attachment
                 if (att.isSaved()) {
+                    String contentUriString = (req.contentUriString != null)
+                            ? req.contentUriString
+                            : "file://" + f.getAbsolutePath();
                     ContentValues cv = new ContentValues();
-                    cv.put(AttachmentColumns.CONTENT_URI, "file://" + f.getAbsolutePath());
+                    cv.put(AttachmentColumns.CONTENT_URI, contentUriString);
                     cv.put(AttachmentColumns.MIME_TYPE, type);
                     att.update(mContext, cv);
                     doStatusCallback(callback, msg.mId, att.mId, EmailServiceStatus.SUCCESS);
diff --git a/src/com/android/exchange/IEmailService.aidl b/src/com/android/exchange/IEmailService.aidl
index 8cf9f09..f0f294a 100644
--- a/src/com/android/exchange/IEmailService.aidl
+++ b/src/com/android/exchange/IEmailService.aidl
@@ -27,7 +27,8 @@
     void stopSync(long mailboxId);
 
     void loadMore(long messageId, IEmailServiceCallback cb);
-    void loadAttachment(long attachmentId, String directory, IEmailServiceCallback cb);
+    void loadAttachment(long attachmentId, String destinationFile, String contentUriString,
+            IEmailServiceCallback cb);
 
     void updateFolderList(long accountId);
 
diff --git a/src/com/android/exchange/PartRequest.java b/src/com/android/exchange/PartRequest.java
index 616d8a2..65b3521 100644
--- a/src/com/android/exchange/PartRequest.java
+++ b/src/com/android/exchange/PartRequest.java
@@ -32,7 +32,8 @@
     public long timeStamp;
     public long emailId;
     public Attachment att;
-    public String dir;
+    public String destination;
+    public String contentUriString;
     public String loc;
     public IEmailServiceCallback callback;
 
@@ -63,9 +64,11 @@
         callback = sCallback;
     }
 
-    public PartRequest(Attachment _att, String _dir, IEmailServiceCallback _callback) {
+    public PartRequest(Attachment _att, String _destination, String _contentUriString,
+            IEmailServiceCallback _callback) {
         this(_att);
-        dir = _dir;
+        destination = _destination;
+        contentUriString = _contentUriString;
         callback = _callback;
     }
 }
diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java
index bbbf570..e642e02 100644
--- a/src/com/android/exchange/SyncManager.java
+++ b/src/com/android/exchange/SyncManager.java
@@ -121,10 +121,10 @@
             stopManualSync(mailboxId);
         }
 
-        public void loadAttachment(long attachmentId, String directory, IEmailServiceCallback cb)
-                throws RemoteException {
+        public void loadAttachment(long attachmentId, String destinationFile,
+                String contentUriString, IEmailServiceCallback cb) throws RemoteException {
             Attachment att = Attachment.restoreAttachmentWithId(SyncManager.this, attachmentId);
-            partRequest(new PartRequest(att, directory, cb));
+            partRequest(new PartRequest(att, destinationFile, contentUriString, cb));
         }
 
         public void updateFolderList(long accountId) throws RemoteException {