SecureConversationViewController.java revision 90eccf969d691abb34f9c6f3d854091adb0c18d1
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.BorderView; 32import com.android.mail.browse.ConversationMessage; 33import com.android.mail.browse.ConversationViewAdapter; 34import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem; 35import com.android.mail.browse.ConversationViewHeader; 36import com.android.mail.browse.MessageFooterView; 37import com.android.mail.browse.MessageHeaderView; 38import com.android.mail.browse.MessageScrollView; 39import com.android.mail.browse.MessageWebView; 40import com.android.mail.providers.Message; 41import com.android.mail.utils.ConversationViewUtils; 42 43/** 44 * Controller to do most of the heavy lifting for {@link SecureConversationViewFragment} 45 * and {@link com.android.mail.browse.EmlMessageViewFragment}. Currently that work is 46 * pretty much the rendering logic. 47 */ 48public class SecureConversationViewController implements 49 MessageHeaderView.MessageHeaderViewCallbacks { 50 private static final String BEGIN_HTML = 51 "<body style=\"margin: 0 %spx;\"><div style=\"margin: 16px 0; font-size: 80%%\">"; 52 private static final String END_HTML = "</div></body>"; 53 54 private final SecureConversationViewControllerCallbacks mCallbacks; 55 56 private MessageWebView mWebView; 57 private ConversationViewHeader mConversationHeaderView; 58 private MessageHeaderView mMessageHeaderView; 59 private MessageFooterView mMessageFooterView; 60 private ConversationMessage mMessage; 61 private MessageScrollView mScrollView; 62 63 private ConversationViewProgressController mProgressController; 64 private FormattedDateBuilder mDateBuilder; 65 66 private int mSideMarginInWebPx; 67 68 public SecureConversationViewController(SecureConversationViewControllerCallbacks callbacks) { 69 mCallbacks = callbacks; 70 } 71 72 public View onCreateView(LayoutInflater inflater, ViewGroup container, 73 Bundle savedInstanceState) { 74 View rootView = inflater.inflate(R.layout.secure_conversation_view, container, false); 75 mScrollView = (MessageScrollView) rootView.findViewById(R.id.scroll_view); 76 mConversationHeaderView = (ConversationViewHeader) rootView.findViewById(R.id.conv_header); 77 mMessageHeaderView = (MessageHeaderView) rootView.findViewById(R.id.message_header); 78 mMessageFooterView = (MessageFooterView) rootView.findViewById(R.id.message_footer); 79 80 // Add color backgrounds to the header and footer. 81 // Otherwise the backgrounds are grey. They can't 82 // be set in xml because that would add more overdraw 83 // in ConversationViewFragment. 84 final int color = rootView.getResources().getColor( 85 R.color.message_header_background_color); 86 mMessageHeaderView.setBackgroundColor(color); 87 mMessageFooterView.setBackgroundColor(color); 88 89 ((BorderView) rootView.findViewById(R.id.top_border)).disableCardBottomBorder(); 90 ((BorderView) rootView.findViewById(R.id.bottom_border)).disableCardTopBorder(); 91 92 mProgressController = new ConversationViewProgressController( 93 mCallbacks.getFragment(), mCallbacks.getHandler()); 94 mProgressController.instantiateProgressIndicators(rootView); 95 mWebView = (MessageWebView) rootView.findViewById(R.id.webview); 96 mWebView.setWebViewClient(mCallbacks.getWebViewClient()); 97 mWebView.setFocusable(false); 98 final WebSettings settings = mWebView.getSettings(); 99 100 settings.setJavaScriptEnabled(false); 101 settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); 102 103 ConversationViewUtils.setTextZoom(mCallbacks.getFragment().getResources(), settings); 104 105 settings.setSupportZoom(true); 106 settings.setBuiltInZoomControls(true); 107 settings.setDisplayZoomControls(false); 108 109 mScrollView.setInnerScrollableView(mWebView); 110 111 return rootView; 112 } 113 114 public void onActivityCreated(Bundle savedInstanceState) { 115 mCallbacks.setupConversationHeaderView(mConversationHeaderView); 116 117 final Fragment fragment = mCallbacks.getFragment(); 118 119 mDateBuilder = new FormattedDateBuilder(fragment.getActivity()); 120 mMessageHeaderView.initialize( 121 mCallbacks.getConversationAccountController(), mCallbacks.getAddressCache()); 122 mMessageHeaderView.setExpandMode(MessageHeaderView.POPUP_MODE); 123 mMessageHeaderView.setContactInfoSource(mCallbacks.getContactInfoSource()); 124 mMessageHeaderView.setCallbacks(this); 125 mMessageHeaderView.setExpandable(false); 126 mMessageHeaderView.setViewOnlyMode(mCallbacks.isViewOnlyMode()); 127 128 mCallbacks.setupMessageHeaderVeiledMatcher(mMessageHeaderView); 129 130 mMessageFooterView.initialize(fragment.getLoaderManager(), fragment.getFragmentManager()); 131 132 mCallbacks.startMessageLoader(); 133 134 mProgressController.showLoadingStatus(mCallbacks.isViewVisibleToUser()); 135 136 final Resources r = mCallbacks.getFragment().getResources(); 137 mSideMarginInWebPx = (int) (r.getDimensionPixelOffset( 138 R.dimen.conversation_message_content_margin_side) / r.getDisplayMetrics().density); 139 } 140 141 /** 142 * Populate the adapter with overlay views (message headers, super-collapsed 143 * blocks, a conversation header), and return an HTML document with spacer 144 * divs inserted for all overlays. 145 */ 146 public void renderMessage(ConversationMessage message) { 147 mMessage = message; 148 149 mWebView.getSettings().setBlockNetworkImage(!mMessage.alwaysShowImages); 150 151 // Add formatting to message body 152 // At this point, only adds margins. 153 StringBuilder dataBuilder = new StringBuilder( 154 String.format(BEGIN_HTML, mSideMarginInWebPx)); 155 dataBuilder.append(mMessage.getBodyAsHtml()); 156 dataBuilder.append(END_HTML); 157 158 mWebView.loadDataWithBaseURL(mCallbacks.getBaseUri(), dataBuilder.toString(), 159 "text/html", "utf-8", null); 160 final MessageHeaderItem item = ConversationViewAdapter.newMessageHeaderItem( 161 null, mDateBuilder, mMessage, true, mMessage.alwaysShowImages); 162 mMessageHeaderView.bind(item, false); 163 if (mMessage.hasAttachments) { 164 mMessageFooterView.setVisibility(View.VISIBLE); 165 mMessageFooterView.bind(item, mCallbacks.getAccountUri(), false); 166 } 167 } 168 169 public ConversationMessage getMessage() { 170 return mMessage; 171 } 172 173 public ConversationViewHeader getConversationHeaderView() { 174 return mConversationHeaderView; 175 } 176 177 public void dismissLoadingStatus() { 178 mProgressController.dismissLoadingStatus(); 179 } 180 181 public void setSubject(String subject) { 182 mConversationHeaderView.setSubject(subject); 183 } 184 185 // Start MessageHeaderViewCallbacks implementations 186 187 @Override 188 public void setMessageSpacerHeight(MessageHeaderItem item, int newSpacerHeight) { 189 // Do nothing. 190 } 191 192 @Override 193 public void setMessageExpanded(MessageHeaderItem item, int newSpacerHeight, 194 int topBorderHeight, int bottomBorderHeight) { 195 // Do nothing. 196 } 197 198 @Override 199 public void setMessageDetailsExpanded(MessageHeaderItem i, boolean expanded, int heightBefore) { 200 // Do nothing. 201 } 202 203 @Override 204 public void showExternalResources(final Message msg) { 205 mWebView.getSettings().setBlockNetworkImage(false); 206 } 207 208 @Override 209 public void showExternalResources(final String rawSenderAddress) { 210 mWebView.getSettings().setBlockNetworkImage(false); 211 } 212 213 @Override 214 public boolean supportsMessageTransforms() { 215 return false; 216 } 217 218 @Override 219 public String getMessageTransforms(final Message msg) { 220 return null; 221 } 222 223 @Override 224 public FragmentManager getFragmentManager() { 225 return mCallbacks.getFragment().getFragmentManager(); 226 } 227 228 // End MessageHeaderViewCallbacks implementations 229} 230