Home | History | Annotate | Download | only in ui
      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 
     18 package com.android.mail.ui;
     19 
     20 import android.app.Fragment;
     21 import android.app.FragmentManager;
     22 import android.content.res.Resources;
     23 import android.os.Bundle;
     24 import android.view.LayoutInflater;
     25 import android.view.View;
     26 import android.view.ViewGroup;
     27 import android.webkit.WebSettings;
     28 
     29 import com.android.mail.FormattedDateBuilder;
     30 import com.android.mail.R;
     31 import com.android.mail.browse.BorderView;
     32 import com.android.mail.browse.ConversationMessage;
     33 import com.android.mail.browse.ConversationViewAdapter;
     34 import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem;
     35 import com.android.mail.browse.ConversationViewHeader;
     36 import com.android.mail.browse.MessageFooterView;
     37 import com.android.mail.browse.MessageHeaderView;
     38 import com.android.mail.browse.MessageScrollView;
     39 import com.android.mail.browse.MessageWebView;
     40 import com.android.mail.providers.Message;
     41 import 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  */
     48 public 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     // Start MessageHeaderViewCallbacks implementations
    189 
    190     @Override
    191     public void setMessageSpacerHeight(MessageHeaderItem item, int newSpacerHeight) {
    192         // Do nothing.
    193     }
    194 
    195     @Override
    196     public void setMessageExpanded(MessageHeaderItem item, int newSpacerHeight,
    197             int topBorderHeight, int bottomBorderHeight) {
    198         // Do nothing.
    199     }
    200 
    201     @Override
    202     public void setMessageDetailsExpanded(MessageHeaderItem i, boolean expanded, int heightBefore) {
    203         // Do nothing.
    204     }
    205 
    206     @Override
    207     public void showExternalResources(final Message msg) {
    208         mWebView.getSettings().setBlockNetworkImage(false);
    209     }
    210 
    211     @Override
    212     public void showExternalResources(final String rawSenderAddress) {
    213         mWebView.getSettings().setBlockNetworkImage(false);
    214     }
    215 
    216     @Override
    217     public boolean supportsMessageTransforms() {
    218         return false;
    219     }
    220 
    221     @Override
    222     public String getMessageTransforms(final Message msg) {
    223         return null;
    224     }
    225 
    226     @Override
    227     public FragmentManager getFragmentManager() {
    228         return mCallbacks.getFragment().getFragmentManager();
    229     }
    230 
    231     // End MessageHeaderViewCallbacks implementations
    232 }
    233