SecureConversationViewController.java revision cee3c90574b48ccaa0f8b9f9341383c231ed41d2
1/* 2 * Copyright (C) 2013 Google Inc. 3 * Licensed to The Android Open Source Project. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.mail.ui; 19 20import android.app.Fragment; 21import android.app.FragmentManager; 22import android.content.res.Resources; 23import android.os.Bundle; 24import android.view.LayoutInflater; 25import android.view.View; 26import android.view.ViewGroup; 27import android.webkit.WebSettings; 28 29import com.android.mail.FormattedDateBuilder; 30import com.android.mail.R; 31import com.android.mail.browse.ConversationMessage; 32import com.android.mail.browse.ConversationViewAdapter; 33import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem; 34import com.android.mail.browse.ConversationViewHeader; 35import com.android.mail.browse.MessageFooterView; 36import com.android.mail.browse.MessageHeaderView; 37import com.android.mail.browse.MessageScrollView; 38import com.android.mail.browse.MessageWebView; 39import com.android.mail.providers.Message; 40import com.android.mail.utils.ConversationViewUtils; 41 42/** 43 * Controller to do most of the heavy lifting for {@link SecureConversationViewFragment} 44 * and {@link com.android.mail.browse.EmlMessageViewFragment}. Currently that work is 45 * pretty much the rendering logic. 46 */ 47public class SecureConversationViewController implements 48 MessageHeaderView.MessageHeaderViewCallbacks { 49 private static final String BEGIN_HTML = 50 "<body style=\"margin: 0 %spx;\"><div style=\"margin: 16px 0; font-size: 80%%\">"; 51 private static final String END_HTML = "</div></body>"; 52 53 private final SecureConversationViewControllerCallbacks mCallbacks; 54 55 private MessageWebView mWebView; 56 private ConversationViewHeader mConversationHeaderView; 57 private MessageHeaderView mMessageHeaderView; 58 private MessageFooterView mMessageFooterView; 59 private ConversationMessage mMessage; 60 private MessageScrollView mScrollView; 61 62 private ConversationViewProgressController mProgressController; 63 private FormattedDateBuilder mDateBuilder; 64 65 private int mSideMarginInWebPx; 66 67 public SecureConversationViewController(SecureConversationViewControllerCallbacks callbacks) { 68 mCallbacks = callbacks; 69 } 70 71 public View onCreateView(LayoutInflater inflater, ViewGroup container, 72 Bundle savedInstanceState) { 73 View rootView = inflater.inflate(R.layout.secure_conversation_view, container, false); 74 mScrollView = (MessageScrollView) rootView.findViewById(R.id.scroll_view); 75 mConversationHeaderView = (ConversationViewHeader) rootView.findViewById(R.id.conv_header); 76 mMessageHeaderView = (MessageHeaderView) rootView.findViewById(R.id.message_header); 77 mMessageFooterView = (MessageFooterView) rootView.findViewById(R.id.message_footer); 78 79 mProgressController = new ConversationViewProgressController( 80 mCallbacks.getFragment(), mCallbacks.getHandler()); 81 mProgressController.instantiateProgressIndicators(rootView); 82 mWebView = (MessageWebView) rootView.findViewById(R.id.webview); 83 mWebView.setWebViewClient(mCallbacks.getWebViewClient()); 84 mWebView.setFocusable(false); 85 final WebSettings settings = mWebView.getSettings(); 86 87 settings.setJavaScriptEnabled(false); 88 settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); 89 90 ConversationViewUtils.setTextZoom(mCallbacks.getFragment().getResources(), settings); 91 92 settings.setSupportZoom(true); 93 settings.setBuiltInZoomControls(true); 94 settings.setDisplayZoomControls(false); 95 96 mScrollView.setInnerScrollableView(mWebView); 97 98 return rootView; 99 } 100 101 public void onActivityCreated(Bundle savedInstanceState) { 102 mCallbacks.setupConversationHeaderView(mConversationHeaderView); 103 104 final Fragment fragment = mCallbacks.getFragment(); 105 106 mDateBuilder = new FormattedDateBuilder(fragment.getActivity()); 107 mMessageHeaderView.initialize( 108 mCallbacks.getConversationAccountController(), mCallbacks.getAddressCache()); 109 mMessageHeaderView.setExpandMode(MessageHeaderView.POPUP_MODE); 110 mMessageHeaderView.setContactInfoSource(mCallbacks.getContactInfoSource()); 111 mMessageHeaderView.setCallbacks(this); 112 mMessageHeaderView.setExpandable(false); 113 mMessageHeaderView.setViewOnlyMode(mCallbacks.isViewOnlyMode()); 114 115 mCallbacks.setupMessageHeaderVeiledMatcher(mMessageHeaderView); 116 117 mMessageFooterView.initialize(fragment.getLoaderManager(), fragment.getFragmentManager()); 118 119 mCallbacks.startMessageLoader(); 120 121 mProgressController.showLoadingStatus(mCallbacks.isViewVisibleToUser()); 122 123 final Resources r = mCallbacks.getFragment().getResources(); 124 mSideMarginInWebPx = (int) ((r.getDimensionPixelOffset( 125 R.dimen.conversation_view_margin_side) + r.getDimensionPixelOffset( 126 R.dimen.conversation_message_content_margin_side)) / r.getDisplayMetrics().density); 127 } 128 129 /** 130 * Populate the adapter with overlay views (message headers, super-collapsed 131 * blocks, a conversation header), and return an HTML document with spacer 132 * divs inserted for all overlays. 133 */ 134 public void renderMessage(ConversationMessage message) { 135 mMessage = message; 136 137 mWebView.getSettings().setBlockNetworkImage(!mMessage.alwaysShowImages); 138 139 // Add formatting to message body 140 // At this point, only adds margins. 141 StringBuilder dataBuilder = new StringBuilder( 142 String.format(BEGIN_HTML, mSideMarginInWebPx)); 143 dataBuilder.append(mMessage.getBodyAsHtml()); 144 dataBuilder.append(END_HTML); 145 146 mWebView.loadDataWithBaseURL(mCallbacks.getBaseUri(), dataBuilder.toString(), 147 "text/html", "utf-8", null); 148 final MessageHeaderItem item = ConversationViewAdapter.newMessageHeaderItem( 149 null, mDateBuilder, mMessage, true, mMessage.alwaysShowImages); 150 mMessageHeaderView.bind(item, false); 151 if (mMessage.hasAttachments) { 152 mMessageFooterView.setVisibility(View.VISIBLE); 153 mMessageFooterView.bind(item, mCallbacks.getAccountUri(), false); 154 } 155 } 156 157 public ConversationMessage getMessage() { 158 return mMessage; 159 } 160 161 public ConversationViewHeader getConversationHeaderView() { 162 return mConversationHeaderView; 163 } 164 165 public void dismissLoadingStatus() { 166 mProgressController.dismissLoadingStatus(); 167 } 168 169 public void setSubject(String subject) { 170 mConversationHeaderView.setSubject(subject); 171 } 172 173 // Start MessageHeaderViewCallbacks implementations 174 175 @Override 176 public void setMessageSpacerHeight(MessageHeaderItem item, int newSpacerHeight) { 177 // Do nothing. 178 } 179 180 @Override 181 public void setMessageExpanded(MessageHeaderItem item, int newSpacerHeight, 182 int topBorderHeight, int bottomBorderHeight) { 183 // Do nothing. 184 } 185 186 @Override 187 public void setMessageDetailsExpanded(MessageHeaderItem i, boolean expanded, int heightBefore) { 188 // Do nothing. 189 } 190 191 @Override 192 public void showExternalResources(final Message msg) { 193 mWebView.getSettings().setBlockNetworkImage(false); 194 } 195 196 @Override 197 public void showExternalResources(final String rawSenderAddress) { 198 mWebView.getSettings().setBlockNetworkImage(false); 199 } 200 201 @Override 202 public boolean supportsMessageTransforms() { 203 return false; 204 } 205 206 @Override 207 public String getMessageTransforms(final Message msg) { 208 return null; 209 } 210 211 @Override 212 public FragmentManager getFragmentManager() { 213 return mCallbacks.getFragment().getFragmentManager(); 214 } 215 216 // End MessageHeaderViewCallbacks implementations 217} 218