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