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