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