Gmail does not display inline attachments nor does it offer "Show
pictures" within the EML viewer

b/13912473

The Eml viewer (and indeed all Secure Conversation Views) now
offers "Show Pictures" to display the inline images.

Those inline attachments are also displayed as tiles at the
bottom of the Secure Conversation View so that interaction with
them is possible.

Change-Id: Ida66820c98c88b222e459aa9d2559383a3b608a0
diff --git a/src/com/android/mail/browse/MessageFooterView.java b/src/com/android/mail/browse/MessageFooterView.java
index cfec4e3..6862f63 100644
--- a/src/com/android/mail/browse/MessageFooterView.java
+++ b/src/com/android/mail/browse/MessageFooterView.java
@@ -89,6 +89,12 @@
         MessageFooterView getViewForItem(MessageFooterItem item);
 
         int getUpdatedHeight(MessageFooterItem item);
+
+        /**
+         * @return <tt>true</tt> if this footer is contained within a SecureConversationViewFragment
+         * and cannot assume the content is <strong>not</strong> malicious
+         */
+        boolean isSecure();
     }
 
     public MessageFooterView(Context context) {
@@ -222,13 +228,15 @@
         final List<Attachment> barAttachments = new ArrayList<Attachment>(maxSize);
 
         for (Attachment attachment : attachments) {
-            if (attachment.isInlineAttachment()) {
-                // skip non-standard (aka inline) attachments
-                continue;
-            } else if (AttachmentTile.isTiledAttachment(attachment)) {
-                tiledAttachments.add(attachment);
-            } else {
-                barAttachments.add(attachment);
+            // attachments in secure views are displayed in the footer so the user may interact with
+            // them; for normal views there is no need to show inline attachments in the footer
+            // since users can interact with them in place
+            if (!attachment.isInlineAttachment() || mCallbacks.isSecure()) {
+                if (AttachmentTile.isTiledAttachment(attachment)) {
+                    tiledAttachments.add(attachment);
+                } else {
+                    barAttachments.add(attachment);
+                }
             }
         }
 
diff --git a/src/com/android/mail/browse/MessageHeaderView.java b/src/com/android/mail/browse/MessageHeaderView.java
index d398fc5..04ff421 100644
--- a/src/com/android/mail/browse/MessageHeaderView.java
+++ b/src/com/android/mail/browse/MessageHeaderView.java
@@ -230,6 +230,12 @@
         String getMessageTransforms(Message msg);
 
         FragmentManager getFragmentManager();
+
+        /**
+         * @return <tt>true</tt> if this header is contained within a SecureConversationViewFragment
+         * and cannot assume the content is <strong>not</strong> malicious
+         */
+        boolean isSecure();
     }
 
     public MessageHeaderView(Context context) {
@@ -419,9 +425,21 @@
         mMessage = mMessageHeaderItem.getMessage();
 
         final Account account = getAccount();
-        final boolean alwaysShowImages = (account != null) &&
+        final boolean alwaysShowImagesForAccount = (account != null) &&
                 (account.settings.showImages == Settings.ShowImages.ALWAYS);
-        mShowImagePrompt = mMessage.shouldShowImagePrompt() && !alwaysShowImages;
+
+        final boolean alwaysShowImagesForMessage = mMessage.shouldShowImagePrompt();
+
+        if (!alwaysShowImagesForMessage) {
+            // we don't need the "Show picture" prompt if the user allows images for this message
+            mShowImagePrompt = false;
+        } else if (mCallbacks.isSecure()) {
+            // in a secure view we always display the "Show picture" prompt
+            mShowImagePrompt = true;
+        } else {
+            // otherwise honor the account setting for automatically showing pictures
+            mShowImagePrompt = !alwaysShowImagesForAccount;
+        }
 
         setExpanded(mMessageHeaderItem.isExpanded());
 
diff --git a/src/com/android/mail/providers/Message.java b/src/com/android/mail/providers/Message.java
index 29522e5..7fd3b41 100644
--- a/src/com/android/mail/providers/Message.java
+++ b/src/com/android/mail/providers/Message.java
@@ -468,7 +468,7 @@
         int partId = 0;
         for (final Part attachmentPart : attachments) {
             mAttachments.add(new Attachment(context, attachmentPart,
-                    emlFileUri, messageId, Integer.toString(partId++), false));
+                    emlFileUri, messageId, Integer.toString(partId++), false /* inline */));
         }
 
         // instantiating an Attachment for each viewable will cause it to be registered within the
@@ -477,7 +477,8 @@
             final String[] cids = viewablePart.getHeader(MimeHeader.HEADER_CONTENT_ID);
             if (cids != null && cids.length == 1) {
                 final String cid = REMOVE_OPTIONAL_BRACKETS.matcher(cids[0]).replaceAll("$1");
-                new Attachment(context, viewablePart, emlFileUri, messageId, cid, true);
+                mAttachments.add(new Attachment(context, viewablePart, emlFileUri, messageId, cid,
+                        true /* inline */));
             }
         }
 
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index 74805d5..eefed78 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -1038,6 +1038,11 @@
         return (domId == null) ? null : mMessageTransforms.get(domId);
     }
 
+    @Override
+    public boolean isSecure() {
+        return false;
+    }
+
     // END message header callbacks
 
     @Override
diff --git a/src/com/android/mail/ui/SecureConversationViewController.java b/src/com/android/mail/ui/SecureConversationViewController.java
index ac0aac1..34bc76d 100644
--- a/src/com/android/mail/ui/SecureConversationViewController.java
+++ b/src/com/android/mail/ui/SecureConversationViewController.java
@@ -22,7 +22,6 @@
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.support.v4.text.BidiFormatter;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -292,6 +291,11 @@
     }
 
     @Override
+    public boolean isSecure() {
+        return true;
+    }
+
+    @Override
     public FragmentManager getFragmentManager() {
         return mCallbacks.getFragment().getFragmentManager();
     }