SecureConversationViewController.java revision a9ea8c67dea4eb11ec88c60c70eca6e9b3ca3ab3
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.setOverScrollMode(View.OVER_SCROLL_NEVER); 97 mWebView.setWebViewClient(mCallbacks.getWebViewClient()); 98 mWebView.setFocusable(false); 99 final WebSettings settings = mWebView.getSettings(); 100 101 settings.setJavaScriptEnabled(false); 102 settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL); 103 104 ConversationViewUtils.setTextZoom(mCallbacks.getFragment().getResources(), settings); 105 106 settings.setSupportZoom(true); 107 settings.setBuiltInZoomControls(true); 108 settings.setDisplayZoomControls(false); 109 110 mScrollView.setInnerScrollableView(mWebView); 111 112 return rootView; 113 } 114 115 public void onActivityCreated(Bundle savedInstanceState) { 116 mCallbacks.setupConversationHeaderView(mConversationHeaderView); 117 118 final Fragment fragment = mCallbacks.getFragment(); 119 120 mDateBuilder = new FormattedDateBuilder(fragment.getActivity()); 121 mMessageHeaderView.initialize( 122 mCallbacks.getConversationAccountController(), mCallbacks.getAddressCache()); 123 mMessageHeaderView.setExpandMode(MessageHeaderView.POPUP_MODE); 124 mMessageHeaderView.setContactInfoSource(mCallbacks.getContactInfoSource()); 125 mMessageHeaderView.setCallbacks(this); 126 mMessageHeaderView.setExpandable(false); 127 mMessageHeaderView.setViewOnlyMode(mCallbacks.isViewOnlyMode()); 128 129 mCallbacks.setupMessageHeaderVeiledMatcher(mMessageHeaderView); 130 131 mMessageFooterView.initialize(fragment.getLoaderManager(), fragment.getFragmentManager()); 132 133 mCallbacks.startMessageLoader(); 134 135 mProgressController.showLoadingStatus(mCallbacks.isViewVisibleToUser()); 136 137 final Resources r = mCallbacks.getFragment().getResources(); 138 mSideMarginInWebPx = (int) (r.getDimensionPixelOffset( 139 R.dimen.conversation_message_content_margin_side) / r.getDisplayMetrics().density); 140 } 141 142 /** 143 * Populate the adapter with overlay views (message headers, super-collapsed 144 * blocks, a conversation header), and return an HTML document with spacer 145 * divs inserted for all overlays. 146 */ 147 public void renderMessage(ConversationMessage message) { 148 mMessage = message; 149 150 mWebView.getSettings().setBlockNetworkImage(!mMessage.alwaysShowImages); 151 152 // Add formatting to message body 153 // At this point, only adds margins. 154 StringBuilder dataBuilder = new StringBuilder( 155 String.format(BEGIN_HTML, mSideMarginInWebPx)); 156 dataBuilder.append(mMessage.getBodyAsHtml()); 157 dataBuilder.append(END_HTML); 158 159 mWebView.loadDataWithBaseURL(mCallbacks.getBaseUri(), dataBuilder.toString(), 160 "text/html", "utf-8", null); 161 final MessageHeaderItem item = ConversationViewAdapter.newMessageHeaderItem( 162 null, mDateBuilder, mMessage, true, mMessage.alwaysShowImages); 163 // Clear out the old info from the header before (re)binding 164 mMessageHeaderView.unbind(); 165 mMessageHeaderView.bind(item, false); 166 if (mMessage.hasAttachments) { 167 mMessageFooterView.setVisibility(View.VISIBLE); 168 mMessageFooterView.bind(item, mCallbacks.getAccountUri(), false); 169 } 170 } 171 172 public ConversationMessage getMessage() { 173 return mMessage; 174 } 175 176 public ConversationViewHeader getConversationHeaderView() { 177 return mConversationHeaderView; 178 } 179 180 public void dismissLoadingStatus() { 181 mProgressController.dismissLoadingStatus(); 182 } 183 184 public void setSubject(String subject) { 185 mConversationHeaderView.setSubject(subject); 186 } 187 188 public void printConversation() { 189 // TODO - implement this 190 } 191 192 // Start MessageHeaderViewCallbacks implementations 193 194 @Override 195 public void setMessageSpacerHeight(MessageHeaderItem item, int newSpacerHeight) { 196 // Do nothing. 197 } 198 199 @Override 200 public void setMessageExpanded(MessageHeaderItem item, int newSpacerHeight, 201 int topBorderHeight, int bottomBorderHeight) { 202 // Do nothing. 203 } 204 205 @Override 206 public void setMessageDetailsExpanded(MessageHeaderItem i, boolean expanded, int heightBefore) { 207 // Do nothing. 208 } 209 210 @Override 211 public void showExternalResources(final Message msg) { 212 mWebView.getSettings().setBlockNetworkImage(false); 213 } 214 215 @Override 216 public void showExternalResources(final String rawSenderAddress) { 217 mWebView.getSettings().setBlockNetworkImage(false); 218 } 219 220 @Override 221 public boolean supportsMessageTransforms() { 222 return false; 223 } 224 225 @Override 226 public String getMessageTransforms(final Message msg) { 227 return null; 228 } 229 230 @Override 231 public FragmentManager getFragmentManager() { 232 return mCallbacks.getFragment().getFragmentManager(); 233 } 234 235 // End MessageHeaderViewCallbacks implementations 236} 237