diff options
author | Andrew Sapperstein <asapperstein@google.com> | 2014-01-08 00:55:51 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-01-08 00:55:51 +0000 |
commit | 55820dbe438d6c6a8ac1efaf23e3af20a6dd5020 (patch) | |
tree | 8d1a4e083192fa52975f273d91e04d1e1fcdfc89 | |
parent | 43d9c2c1178bcf55c908a3ec80486a9604649a49 (diff) | |
parent | 8ec43e877a9c1925514f066655984e21fbd255e8 (diff) | |
download | android_packages_apps_UnifiedEmail-55820dbe438d6c6a8ac1efaf23e3af20a6dd5020.tar.gz android_packages_apps_UnifiedEmail-55820dbe438d6c6a8ac1efaf23e3af20a6dd5020.tar.bz2 android_packages_apps_UnifiedEmail-55820dbe438d6c6a8ac1efaf23e3af20a6dd5020.zip |
Merge "View inline images in photo viewer. b/5555553." into ub-mail-master
15 files changed, 311 insertions, 86 deletions
diff --git a/assets/script.js b/assets/script.js index 4667addf5..79987d353 100644 --- a/assets/script.js +++ b/assets/script.js @@ -447,6 +447,9 @@ function hideUnsafeImages(msgContentDivs) { var msgContentDiv, image; var images; var showImages; + var k = 0; + var urls = new Array(); + var messageIds = new Array(); for (i = 0, msgContentCount = msgContentDivs.length; i < msgContentCount; i++) { msgContentDiv = msgContentDivs[i]; showImages = msgContentDiv.classList.contains("mail-show-images"); @@ -454,7 +457,12 @@ function hideUnsafeImages(msgContentDivs) { images = msgContentDiv.getElementsByTagName("img"); for (j = 0, imgCount = images.length; j < imgCount; j++) { image = images[j]; - rewriteRelativeImageSrc(image); + var src = rewriteRelativeImageSrc(image); + if (src) { + urls[k] = src; + messageIds[k] = msgContentDiv.parentNode.id; + k++; + } attachImageLoadListener(image); // TODO: handle inline image attachments for all supported protocols if (!showImages) { @@ -462,11 +470,14 @@ function hideUnsafeImages(msgContentDivs) { } } } + + window.mail.onInlineAttachmentsParsed(urls, messageIds); } /** - * Changes relative paths to absolute path by pre-pending the account uri + * Changes relative paths to absolute path by pre-pending the account uri. * @param {Element} imgElement Image for which the src path will be updated. + * @returns the rewritten image src string or null if the imgElement was not rewritten. */ function rewriteRelativeImageSrc(imgElement) { var src = imgElement.src; @@ -476,7 +487,10 @@ function rewriteRelativeImageSrc(imgElement) { // The conversation specifies a different base uri than the document src = CONVERSATION_BASE_URI + src.substring(DOC_BASE_URI.length); imgElement.src = src; + return src; } + + return null; }; diff --git a/proguard.flags b/proguard.flags index 2d4cfcf91..1ac96a571 100644 --- a/proguard.flags +++ b/proguard.flags @@ -51,10 +51,6 @@ public <methods>; } --keepclasseswithmembers class com.android.mail.ui.ConversationViewFragment$MessageJsBridge { - public <methods>; -} - -keepclasseswithmembers class com.android.mail.ui.TwoPaneLayout { *** setFoldersLeft(...); *** setListBitmapLeft(...); diff --git a/res/menu/webview_context_menu.xml b/res/menu/webview_context_menu.xml index af7a59e2d..790e4f4dd 100644 --- a/res/menu/webview_context_menu.xml +++ b/res/menu/webview_context_menu.xml @@ -50,8 +50,6 @@ <group android:id="@+id/IMAGE_MENU"> <item android:id="@+id/view_image_context_menu_id" android:title="@string/contextmenu_view_image"/> - <item android:id="@+id/save_image_context_menu_id" - android:title="@string/contextmenu_save_image"/> </group> </menu> diff --git a/res/values/strings.xml b/res/values/strings.xml index 985056648..c1b7f391f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -260,8 +260,6 @@ <string name="contextmenu_copylink">Copy link URL</string> <!-- Menu item to view an image [CHAR LIMIT=50]--> <string name="contextmenu_view_image">View image</string> - <!-- Menu item to save an image [CHAR LIMIT=50]--> - <string name="contextmenu_save_image">Save image</string> <!-- Menu item to dial a number [CHAR LIMIT=50]--> <string name="contextmenu_dial_dot">Dial\u2026</string> <!-- Menu item to send an SMS [CHAR LIMIT=50]--> diff --git a/src/com/android/mail/browse/EmlMessageViewFragment.java b/src/com/android/mail/browse/EmlMessageViewFragment.java index 6b73e150c..04eabd64f 100644 --- a/src/com/android/mail/browse/EmlMessageViewFragment.java +++ b/src/com/android/mail/browse/EmlMessageViewFragment.java @@ -250,6 +250,11 @@ public class EmlMessageViewFragment extends Fragment return mAccountUri; } + @Override + public boolean shouldAlwaysShowImages() { + return false; + } + // End SecureConversationViewControllerCallbacks private class MessageLoadCallbacks diff --git a/src/com/android/mail/browse/InlineAttachmentViewIntentBuilder.java b/src/com/android/mail/browse/InlineAttachmentViewIntentBuilder.java new file mode 100644 index 000000000..a8c2d37e5 --- /dev/null +++ b/src/com/android/mail/browse/InlineAttachmentViewIntentBuilder.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2013 Google Inc. + * Licensed to The Android Open Source Project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.mail.browse; + +import android.content.Context; +import android.content.Intent; + +/** + * Builds an intent to be used when the user long presses an + * inline image and selects "View image". + */ +public interface InlineAttachmentViewIntentBuilder { + + /** + * Creates an intent to be used when the user long presses an inline image and + * selects "View image." Null should be returned if "View image" should not be + * shown. + * @param context Used to create the intent. + * @param url The url of the image that was long-pressed. + * @return An intent that should be used when the user long presses an + * inline image and selects "View Image" or {@code null} if there should not + * be a "View image" option for this url. + */ + Intent createInlineAttachmentViewIntent(Context context, String url); +} diff --git a/src/com/android/mail/browse/InlineAttachmentViewIntentBuilderCreator.java b/src/com/android/mail/browse/InlineAttachmentViewIntentBuilderCreator.java new file mode 100644 index 000000000..e57e2a60e --- /dev/null +++ b/src/com/android/mail/browse/InlineAttachmentViewIntentBuilderCreator.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013 Google Inc. + * Licensed to The Android Open Source Project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.mail.browse; + +import java.util.Map; + +/** + * Creates {@link InlineAttachmentViewIntentBuilder}s. Only one + * of these should ever exist and it should be set statically in + * the {@link android.app.Application} class of each app. + */ +public interface InlineAttachmentViewIntentBuilderCreator { + InlineAttachmentViewIntentBuilder createInlineAttachmentViewIntentBuilder( + Map<String, String> urlToMessageIdMap, String account, long conversationId); +} diff --git a/src/com/android/mail/browse/InlineAttachmentViewIntentBuilderCreatorHolder.java b/src/com/android/mail/browse/InlineAttachmentViewIntentBuilderCreatorHolder.java new file mode 100644 index 000000000..eba609da4 --- /dev/null +++ b/src/com/android/mail/browse/InlineAttachmentViewIntentBuilderCreatorHolder.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013 Google Inc. + * Licensed to The Android Open Source Project. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.mail.browse; + +/** + * Holds an {@link InlineAttachmentViewIntentBuilderCreator} that is used to create + * {@link InlineAttachmentViewIntentBuilder}s for the conversation views. <p/> + * + * Unfortunately, this pattern requires three layers. The holder (the top layer) is created at + * application start and should have its creator set in the {@link android.app.Application} + * so that each app has a creator that provides app-specific functionality. + * Typically, that functionality is creating a different type of + * {@link InlineAttachmentViewIntentBuilder} to do app-specific work. <p/> + * + * The middle layer is the {@link InlineAttachmentViewIntentBuilderCreator}. Only one of + * these exist and is created at {@link android.app.Application} start time (usually + * in a static block). During conversation view setup, this is used to create + * an {@link InlineAttachmentViewIntentBuilder}. The creation needs to be done at this + * time so that each conversation view can have its own builder that is passed + * conversation-specific data at builder creation time. <p/> + * + * The bottom layer is the {@link InlineAttachmentViewIntentBuilder}. This builder + * is passed into a {@link com.android.mail.browse.WebViewContextMenu} and used + * when an image is long-pressed to determine whether "View image" should be a menu + * option and what intent should fire when "View image" is selected. + */ +public class InlineAttachmentViewIntentBuilderCreatorHolder { + private static InlineAttachmentViewIntentBuilderCreator sCreator; + + public static void setInlineAttachmentViewIntentCreator( + InlineAttachmentViewIntentBuilderCreator creator) { + sCreator = creator; + } + + public static InlineAttachmentViewIntentBuilderCreator getInlineAttachmentViewIntentCreator() { + return sCreator; + } +} diff --git a/src/com/android/mail/browse/WebViewContextMenu.java b/src/com/android/mail/browse/WebViewContextMenu.java index e8a9ca4f0..7f2bf0b7e 100644 --- a/src/com/android/mail/browse/WebViewContextMenu.java +++ b/src/com/android/mail/browse/WebViewContextMenu.java @@ -53,11 +53,12 @@ import java.nio.charset.Charset; public class WebViewContextMenu implements OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener { + private final Activity mActivity; + private final InlineAttachmentViewIntentBuilder mIntentBuilder; + private final boolean mSupportsDial; private final boolean mSupportsSms; - private Activity mActivity; - protected static enum MenuType { OPEN_MENU, COPY_LINK_MENU, @@ -72,8 +73,9 @@ public class WebViewContextMenu implements OnCreateContextMenuListener, COPY_GEO_MENU, } - public WebViewContextMenu(Activity host) { + public WebViewContextMenu(Activity host, InlineAttachmentViewIntentBuilder builder) { mActivity = host; + mIntentBuilder = builder; // Query the package manager to see if the device // has an app that supports ACTION_DIAL or ACTION_SENDTO @@ -187,8 +189,6 @@ public class WebViewContextMenu implements OnCreateContextMenuListener, menu.setGroupVisible(R.id.GEO_MENU, type == WebView.HitTestResult.GEO_TYPE); menu.setGroupVisible(R.id.ANCHOR_MENU, type == WebView.HitTestResult.SRC_ANCHOR_TYPE || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE); - menu.setGroupVisible(R.id.IMAGE_MENU, type == WebView.HitTestResult.IMAGE_TYPE - || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE); // Setup custom handling depending on the type switch (type) { @@ -273,32 +273,65 @@ public class WebViewContextMenu implements OnCreateContextMenuListener, break; case WebView.HitTestResult.SRC_ANCHOR_TYPE: + setupAnchorMenu(extra, menu); + break; case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE: - menu.findItem(getMenuResIdForMenuType(MenuType.SHARE_LINK_MENU)).setVisible( - showShareLinkMenuItem()); + // Deliberately do not break because we want to fall through to image type. + setupAnchorMenu(extra, menu); + case WebView.HitTestResult.IMAGE_TYPE: + // The image menu will be visible whenever the + // intent builder returns an intent. If it returns null, + // the image menu will not be shown. + menu.setGroupVisible(R.id.IMAGE_MENU, setupImageMenu(extra, menu)); + break; + default: + break; + } + } - // The documentation for WebView indicates that if the HitTestResult is - // SRC_ANCHOR_TYPE or the url would be specified in the extra. We don't need to - // call requestFocusNodeHref(). If we wanted to handle UNKNOWN HitTestResults, we - // would. With this knowledge, we can just set the title - menu.setHeaderTitle(extra); + private void setupAnchorMenu(String extra, ContextMenu menu) { + menu.findItem(getMenuResIdForMenuType(MenuType.SHARE_LINK_MENU)).setVisible( + showShareLinkMenuItem()); - menu.findItem(getMenuResIdForMenuType(MenuType.COPY_LINK_MENU)). - setOnMenuItemClickListener(new Copy(extra)); + // The documentation for WebView indicates that if the HitTestResult is + // SRC_ANCHOR_TYPE or the url would be specified in the extra. We don't need to + // call requestFocusNodeHref(). If we wanted to handle UNKNOWN HitTestResults, we + // would. With this knowledge, we can just set the title + menu.setHeaderTitle(extra); - final MenuItem openLinkMenuItem = - menu.findItem(getMenuResIdForMenuType(MenuType.OPEN_MENU)); - // remove the on click listener - openLinkMenuItem.setOnMenuItemClickListener(null); - openLinkMenuItem.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(extra))); + menu.findItem(getMenuResIdForMenuType(MenuType.COPY_LINK_MENU)). + setOnMenuItemClickListener(new Copy(extra)); - menu.findItem(getMenuResIdForMenuType(MenuType.SHARE_LINK_MENU)). - setOnMenuItemClickListener(new Share(extra)); - break; - case WebView.HitTestResult.IMAGE_TYPE: - default: - break; + final MenuItem openLinkMenuItem = + menu.findItem(getMenuResIdForMenuType(MenuType.OPEN_MENU)); + // remove the on click listener + openLinkMenuItem.setOnMenuItemClickListener(null); + openLinkMenuItem.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(extra))); + + menu.findItem(getMenuResIdForMenuType(MenuType.SHARE_LINK_MENU)). + setOnMenuItemClickListener(new Share(extra)); + } + + /** + * Used to setup the image menu group if the {@link android.webkit.WebView.HitTestResult} + * is of type {@link android.webkit.WebView.HitTestResult#IMAGE_TYPE} or + * {@link android.webkit.WebView.HitTestResult#SRC_IMAGE_ANCHOR_TYPE}. + * @param url Url that was long pressed. + * @param menu The {@link android.view.ContextMenu} that is about to be shown. + * @return {@code true} if the view image menu item should be visible. + * {@code false}, otherwise. + */ + protected boolean setupImageMenu(String url, ContextMenu menu) { + final Intent intent = mIntentBuilder.createInlineAttachmentViewIntent(mActivity, url); + if (intent == null) { + return false; } + + final MenuItem menuItem = menu.findItem(R.id.view_image_context_menu_id); + menuItem.setOnMenuItemClickListener(null); + menuItem.setIntent(intent); + + return true; } @Override diff --git a/src/com/android/mail/photo/MailPhotoViewActivity.java b/src/com/android/mail/photo/MailPhotoViewActivity.java index 510562f37..a0618ba4f 100644 --- a/src/com/android/mail/photo/MailPhotoViewActivity.java +++ b/src/com/android/mail/photo/MailPhotoViewActivity.java @@ -19,6 +19,7 @@ package com.android.mail.photo; import android.app.ActionBar; import android.content.Context; +import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -106,15 +107,20 @@ public class MailPhotoViewActivity extends PhotoViewActivity { */ public static void startMailPhotoViewActivity(final Context context, final Uri imageListUri, final String initialPhotoUri) { - final Intents.PhotoViewIntentBuilder builder = - Intents.newPhotoViewIntentBuilder(context, - "com.android.mail.photo.MailPhotoViewActivity"); - builder - .setPhotosUri(imageListUri.toString()) + context.startActivity( + buildMailPhotoViewActivityIntent(context, imageListUri, initialPhotoUri)); + } + + public static Intent buildMailPhotoViewActivityIntent( + final Context context, final Uri imageListUri, final String initialPhotoUri) { + final Intents.PhotoViewIntentBuilder builder = Intents.newPhotoViewIntentBuilder( + context, "com.android.mail.photo.MailPhotoViewActivity"); + + builder.setPhotosUri(imageListUri.toString()) .setProjection(UIProvider.ATTACHMENT_PROJECTION) .setInitialPhotoUri(initialPhotoUri); - context.startActivity(builder.build()); + return builder.build(); } @Override diff --git a/src/com/android/mail/ui/AbstractConversationViewFragment.java b/src/com/android/mail/ui/AbstractConversationViewFragment.java index 06542c1ca..5425f7d6c 100644 --- a/src/com/android/mail/ui/AbstractConversationViewFragment.java +++ b/src/com/android/mail/ui/AbstractConversationViewFragment.java @@ -47,6 +47,7 @@ import com.android.mail.providers.Address; import com.android.mail.providers.Conversation; import com.android.mail.providers.Folder; import com.android.mail.providers.ListParams; +import com.android.mail.providers.Settings; import com.android.mail.providers.UIProvider; import com.android.mail.providers.UIProvider.CursorStatus; import com.android.mail.utils.LogTag; @@ -688,4 +689,8 @@ public abstract class AbstractConversationViewFragment extends Fragment implemen } protected abstract void printConversation(); + + public boolean shouldAlwaysShowImages() { + return (mAccount != null) && (mAccount.settings.showImages == Settings.ShowImages.ALWAYS); + } } diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java index 279316435..76c4b4e4f 100644 --- a/src/com/android/mail/ui/ConversationViewFragment.java +++ b/src/com/android/mail/ui/ConversationViewFragment.java @@ -28,6 +28,7 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.SystemClock; import android.support.v4.text.BidiFormatter; +import android.support.v4.util.ArrayMap; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -56,6 +57,8 @@ import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem; import com.android.mail.browse.ConversationViewAdapter.SuperCollapsedBlockItem; import com.android.mail.browse.ConversationViewHeader; import com.android.mail.browse.ConversationWebView; +import com.android.mail.browse.InlineAttachmentViewIntentBuilderCreator; +import com.android.mail.browse.InlineAttachmentViewIntentBuilderCreatorHolder; import com.android.mail.browse.MailWebView.ContentSizeChangeListener; import com.android.mail.browse.MessageCursor; import com.android.mail.browse.MessageHeaderView; @@ -210,6 +213,11 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i private BidiFormatter sBidiFormatter; /** + * Contains a mapping between inline image attachments and their local message id. + */ + private Map<String, String> mUrlToMessageIdMap; + + /** * Constructor needs to be public to handle orientation changes and activity lifecycle events. */ public ConversationViewFragment() {} @@ -280,7 +288,14 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i mSideMarginPx = resources.getDimensionPixelOffset( R.dimen.conversation_message_content_margin_side); - mWebView.setOnCreateContextMenuListener(new WebViewContextMenu(getActivity())); + mUrlToMessageIdMap = new ArrayMap<String, String>(); + final InlineAttachmentViewIntentBuilderCreator creator = + InlineAttachmentViewIntentBuilderCreatorHolder. + getInlineAttachmentViewIntentCreator(); + mWebView.setOnCreateContextMenuListener(new WebViewContextMenu(getActivity(), + creator.createInlineAttachmentViewIntentBuilder( + mUrlToMessageIdMap, mAccount.getEmailAddress(), + mConversation != null ? mConversation.id : -1))); // set this up here instead of onCreateView to ensure the latest Account is loaded setupOverviewMode(); @@ -370,9 +385,15 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i final WebChromeClient wcc = new WebChromeClient() { @Override public boolean onConsoleMessage(ConsoleMessage consoleMessage) { - LogUtils.i(LOG_TAG, "JS: %s (%s:%d) f=%s", consoleMessage.message(), - consoleMessage.sourceId(), consoleMessage.lineNumber(), - ConversationViewFragment.this); + if (consoleMessage.messageLevel() == ConsoleMessage.MessageLevel.ERROR) { + LogUtils.wtf(LOG_TAG, "JS: %s (%s:%d) f=%s", consoleMessage.message(), + consoleMessage.sourceId(), consoleMessage.lineNumber(), + ConversationViewFragment.this); + } else { + LogUtils.i(LOG_TAG, "JS: %s (%s:%d) f=%s", consoleMessage.message(), + consoleMessage.sourceId(), consoleMessage.lineNumber(), + ConversationViewFragment.this); + } return true; } }; @@ -686,8 +707,7 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i int collapsedStart = -1; ConversationMessage prevCollapsedMsg = null; - final boolean alwaysShowImages = (mAccount != null) && - (mAccount.settings.showImages == Settings.ShowImages.ALWAYS); + final boolean alwaysShowImages = shouldAlwaysShowImages(); boolean prevSafeForImages = alwaysShowImages; @@ -1141,17 +1161,14 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i * */ private class MailJsBridge { - - @SuppressWarnings("unused") @JavascriptInterface public void onWebContentGeometryChange(final String[] overlayTopStrs, final String[] overlayBottomStrs) { - getHandler().post(new FragmentRunnable("onWebContentGeometryChange", - ConversationViewFragment.this) { - - @Override - public void go() { - try { + try { + getHandler().post(new FragmentRunnable("onWebContentGeometryChange", + ConversationViewFragment.this) { + @Override + public void go() { if (!mViewsCreated) { LogUtils.d(LOG_TAG, "ignoring webContentGeometryChange because views" + " are gone, %s", ConversationViewFragment.this); @@ -1167,14 +1184,13 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i } mDiff = 0; } - } catch (Throwable t) { - LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onWebContentGeometryChange"); } - } - }); + }); + } catch (Throwable t) { + LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onWebContentGeometryChange"); + } } - @SuppressWarnings("unused") @JavascriptInterface public String getTempMessageBodies() { try { @@ -1191,7 +1207,6 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i } } - @SuppressWarnings("unused") @JavascriptInterface public String getMessageBody(String domId) { try { @@ -1216,7 +1231,6 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i } } - @SuppressWarnings("unused") @JavascriptInterface public String getMessageSender(String domId) { try { @@ -1241,31 +1255,33 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i } } - @SuppressWarnings("unused") @JavascriptInterface public void onContentReady() { - getHandler().post(new FragmentRunnable("onContentReady", - ConversationViewFragment.this) { - @Override - public void go() { - try { - if (mWebViewLoadStartMs != 0) { - LogUtils.i(LOG_TAG, "IN CVF.onContentReady, f=%s vis=%s t=%sms", - ConversationViewFragment.this, - isUserVisible(), - (SystemClock.uptimeMillis() - mWebViewLoadStartMs)); + try { + getHandler().post(new FragmentRunnable("onContentReady", + ConversationViewFragment.this) { + @Override + public void go() { + try { + if (mWebViewLoadStartMs != 0) { + LogUtils.i(LOG_TAG, "IN CVF.onContentReady, f=%s vis=%s t=%sms", + ConversationViewFragment.this, + isUserVisible(), + (SystemClock.uptimeMillis() - mWebViewLoadStartMs)); + } + revealConversation(); + } catch (Throwable t) { + LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onContentReady"); + // Still try to show the conversation. + revealConversation(); } - revealConversation(); - } catch (Throwable t) { - LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onContentReady"); - // Still try to show the conversation. - revealConversation(); } - } - }); + }); + } catch (Throwable t) { + LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onContentReady"); + } } - @SuppressWarnings("unused") @JavascriptInterface public float getScrollYPercent() { try { @@ -1276,7 +1292,6 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i } } - @SuppressWarnings("unused") @JavascriptInterface public void onMessageTransform(String messageDomId, String transformText) { try { @@ -1285,7 +1300,29 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i onConversationTransformed(); } catch (Throwable t) { LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onMessageTransform"); - return; + } + } + + @JavascriptInterface + public void onInlineAttachmentsParsed(final String[] urls, final String[] messageIds) { + try { + getHandler().post(new FragmentRunnable("onInlineAttachmentsParsed", + ConversationViewFragment.this) { + @Override + public void go() { + try { + for (int i = 0, size = urls.length; i < size; i++) { + mUrlToMessageIdMap.put(urls[i], messageIds[i]); + } + } catch (ArrayIndexOutOfBoundsException e) { + LogUtils.e(LOG_TAG, e, + "Number of urls does not match number of message ids - %s:%s", + urls.length, messageIds.length); + } + } + }); + } catch (Throwable t) { + LogUtils.e(LOG_TAG, t, "Error in MailJsBridge.onInlineAttachmentsParsed"); } } } diff --git a/src/com/android/mail/ui/HtmlConversationTemplates.java b/src/com/android/mail/ui/HtmlConversationTemplates.java index 104d0c03e..3e37a6827 100644 --- a/src/com/android/mail/ui/HtmlConversationTemplates.java +++ b/src/com/android/mail/ui/HtmlConversationTemplates.java @@ -36,6 +36,7 @@ public class HtmlConversationTemplates extends AbstractHtmlTemplates { * Prefix applied to a message id for use as a div id */ public static final String MESSAGE_PREFIX = "m"; + public static final int MESSAGE_PREFIX_LENGTH = MESSAGE_PREFIX.length(); private static final String TAG = LogTag.getLogTag(); diff --git a/src/com/android/mail/ui/SecureConversationViewController.java b/src/com/android/mail/ui/SecureConversationViewController.java index e8e8417e0..0ed03f6f2 100644 --- a/src/com/android/mail/ui/SecureConversationViewController.java +++ b/src/com/android/mail/ui/SecureConversationViewController.java @@ -33,6 +33,8 @@ import com.android.mail.browse.ConversationMessage; import com.android.mail.browse.ConversationViewAdapter; import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem; import com.android.mail.browse.ConversationViewHeader; +import com.android.mail.browse.InlineAttachmentViewIntentBuilderCreator; +import com.android.mail.browse.InlineAttachmentViewIntentBuilderCreatorHolder; import com.android.mail.browse.MessageFooterView; import com.android.mail.browse.MessageHeaderView; import com.android.mail.browse.MessageScrollView; @@ -98,8 +100,12 @@ public class SecureConversationViewController implements mWebView = (MessageWebView) rootView.findViewById(R.id.webview); mWebView.setOverScrollMode(View.OVER_SCROLL_NEVER); mWebView.setWebViewClient(mCallbacks.getWebViewClient()); - mWebView.setOnCreateContextMenuListener( - new WebViewContextMenu(mCallbacks.getFragment().getActivity())); + final InlineAttachmentViewIntentBuilderCreator creator = + InlineAttachmentViewIntentBuilderCreatorHolder. + getInlineAttachmentViewIntentCreator(); + mWebView.setOnCreateContextMenuListener(new WebViewContextMenu( + mCallbacks.getFragment().getActivity(), + creator.createInlineAttachmentViewIntentBuilder(null, null, -1))); mWebView.setFocusable(false); final WebSettings settings = mWebView.getSettings(); @@ -151,7 +157,9 @@ public class SecureConversationViewController implements public void renderMessage(ConversationMessage message) { mMessage = message; - mWebView.getSettings().setBlockNetworkImage(!mMessage.alwaysShowImages); + final boolean alwaysShowImages = mCallbacks.shouldAlwaysShowImages(); + mWebView.getSettings().setBlockNetworkImage( + !alwaysShowImages && !mMessage.alwaysShowImages); // Add formatting to message body // At this point, only adds margins. diff --git a/src/com/android/mail/ui/SecureConversationViewControllerCallbacks.java b/src/com/android/mail/ui/SecureConversationViewControllerCallbacks.java index 2e4f5d97e..f53de7d18 100644 --- a/src/com/android/mail/ui/SecureConversationViewControllerCallbacks.java +++ b/src/com/android/mail/ui/SecureConversationViewControllerCallbacks.java @@ -46,4 +46,5 @@ public interface SecureConversationViewControllerCallbacks { public String getBaseUri(); public boolean isViewOnlyMode(); public Uri getAccountUri(); + public boolean shouldAlwaysShowImages(); } |