SecureConversationViewFragment.java revision bf1d35fab89443d8e380ab48e98ac1c8cd7a6686
1f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp/*
2f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp * Copyright (C) 2012 Google Inc.
3f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp * Licensed to The Android Open Source Project.
4f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp *
5f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp * Licensed under the Apache License, Version 2.0 (the "License");
6f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp * you may not use this file except in compliance with the License.
7f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp * You may obtain a copy of the License at
8f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp *
9f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp *      http://www.apache.org/licenses/LICENSE-2.0
10f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp *
11f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp * Unless required by applicable law or agreed to in writing, software
12f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp * distributed under the License is distributed on an "AS IS" BASIS,
13f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp * See the License for the specific language governing permissions and
15f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp * limitations under the License.
16f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp */
17f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
18351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huangpackage com.android.mail.ui;
19f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
20f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport android.content.Loader;
21bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sappersteinimport android.content.res.Resources;
22f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport android.database.Cursor;
23f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport android.net.Uri;
24f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport android.os.Bundle;
25f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport android.view.LayoutInflater;
26f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport android.view.View;
27f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport android.view.ViewGroup;
28f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport android.webkit.WebSettings;
29f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport android.webkit.WebSettings.LayoutAlgorithm;
30f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport android.webkit.WebView;
31ff282d0ef252dbdaf6e9f4e2a7fd640287c01e6bmindypimport android.webkit.WebViewClient;
32f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
33f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport com.android.mail.R;
34351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huangimport com.android.mail.browse.ConversationViewAdapter;
351ebc2db723ed29093d724eb5da906a496ee57224Alice Yangimport com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem;
36351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huangimport com.android.mail.browse.ConversationViewHeader;
37351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huangimport com.android.mail.browse.MessageCursor;
381ebc2db723ed29093d724eb5da906a496ee57224Alice Yangimport com.android.mail.browse.MessageCursor.ConversationMessage;
39351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huangimport com.android.mail.browse.MessageFooterView;
40351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huangimport com.android.mail.browse.MessageHeaderView;
41f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport com.android.mail.browse.MessageHeaderView.MessageHeaderViewCallbacks;
42be7739bf0cebc5018c8ffb0c649fc62a74d74e69Andy Huangimport com.android.mail.browse.MessageScrollView;
43be7739bf0cebc5018c8ffb0c649fc62a74d74e69Andy Huangimport com.android.mail.browse.MessageWebView;
44c42ad5ea3a49e6045a79d1fde3d858033176e67bPaul Westbrookimport com.android.mail.content.ObjectCursor;
45adbf3e8cadb66666f307352b72537fbac57b916fAndy Huangimport com.android.mail.providers.Account;
46f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport com.android.mail.providers.Conversation;
47f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport com.android.mail.providers.Message;
48f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport com.android.mail.utils.LogTag;
49f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport com.android.mail.utils.LogUtils;
50f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
51f4fce1227d8b49f45e6569f1590565f2df9e8d6emindypimport java.util.HashSet;
52bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sappersteinimport java.util.Locale;
53f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
54f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyppublic class SecureConversationViewFragment extends AbstractConversationViewFragment implements
55f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        MessageHeaderViewCallbacks {
56f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    private static final String LOG_TAG = LogTag.getLogTag();
57bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein
58bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein    private static final String BEGIN_HTML =
59bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein            "<body style=\"margin: 0 %spx;\"><div style=\"margin: 16px 0;\">";
60bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein    private static final String END_HTML = "</div></body>";
61bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein
62be7739bf0cebc5018c8ffb0c649fc62a74d74e69Andy Huang    private MessageWebView mWebView;
63f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    private ConversationViewHeader mConversationHeaderView;
64f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    private MessageHeaderView mMessageHeaderView;
6526d4d2d9c43c499f458808f050ec73ea3c28dec4mindyp    private MessageFooterView mMessageFooterView;
66f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    private ConversationMessage mMessage;
67be7739bf0cebc5018c8ffb0c649fc62a74d74e69Andy Huang    private MessageScrollView mScrollView;
680a1aa1bb89221eda2f67af52ef274612f28ecf5cPaul Westbrook
69bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein    private int mSideMarginInWebPx;
70bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein
711ebc2db723ed29093d724eb5da906a496ee57224Alice Yang    private final WebViewClient mWebViewClient = new AbstractConversationWebViewClient() {
72ff282d0ef252dbdaf6e9f4e2a7fd640287c01e6bmindyp        @Override
73ff282d0ef252dbdaf6e9f4e2a7fd640287c01e6bmindyp        public void onPageFinished(WebView view, String url) {
749d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang            if (isUserVisible()) {
754d8cad5e37ade03903a23cca8ea3e782af21170fPaul Westbrook                onConversationSeen();
764d8cad5e37ade03903a23cca8ea3e782af21170fPaul Westbrook            }
774d8cad5e37ade03903a23cca8ea3e782af21170fPaul Westbrook
78ff282d0ef252dbdaf6e9f4e2a7fd640287c01e6bmindyp            dismissLoadingStatus();
79ff282d0ef252dbdaf6e9f4e2a7fd640287c01e6bmindyp        }
80ff282d0ef252dbdaf6e9f4e2a7fd640287c01e6bmindyp    };
81f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
82f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    /**
83f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     * Creates a new instance of {@link ConversationViewFragment}, initialized
84f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     * to display a conversation with other parameters inherited/copied from an
85f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     * existing bundle, typically one created using {@link #makeBasicArgs}.
86f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     */
87f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    public static SecureConversationViewFragment newInstance(Bundle existingArgs,
88f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp            Conversation conversation) {
89f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        SecureConversationViewFragment f = new SecureConversationViewFragment();
90f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        Bundle args = new Bundle(existingArgs);
91f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        args.putParcelable(ARG_CONVERSATION, conversation);
92f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        f.setArguments(args);
93f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        return f;
94f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
95f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
96f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    /**
97f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     * Constructor needs to be public to handle orientation changes and activity
98f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     * lifecycle events.
99f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     */
100f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    public SecureConversationViewFragment() {
101f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        super();
102f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
103f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
104f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    @Override
105f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    public void onActivityCreated(Bundle savedInstanceState) {
106f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        super.onActivityCreated(savedInstanceState);
107f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        mConversationHeaderView.setCallbacks(this, this);
1082c6cf4c5e3d04907f2f030dedf983d77de730a4fAndrew Sapperstein        mConversationHeaderView.setFolders(mConversation);
1097388dba58aecafacd91ded0f787cf01bfc7af232Andy Huang        mConversationHeaderView.setSubject(mConversation.subject);
1102e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        mMessageHeaderView.initialize(mDateBuilder, this, mAddressCache);
1112e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        mMessageHeaderView.setExpandMode(MessageHeaderView.POPUP_MODE);
112f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        mMessageHeaderView.setContactInfoSource(getContactInfoSource());
113f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        mMessageHeaderView.setCallbacks(this);
114f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        mMessageHeaderView.setExpandable(false);
11569a6cdff8afde77ec9bcd75a5651ee212344019eVikram Aggarwal        mMessageHeaderView.setVeiledMatcher(
11669a6cdff8afde77ec9bcd75a5651ee212344019eVikram Aggarwal                ((ControllableActivity) getActivity()).getAccountController()
11769a6cdff8afde77ec9bcd75a5651ee212344019eVikram Aggarwal                        .getVeiledAddressMatcher());
1182e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        mMessageFooterView.initialize(getLoaderManager(), getFragmentManager());
119f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        getLoaderManager().initLoader(MESSAGE_LOADER, null, getMessageLoaderCallbacks());
120ff282d0ef252dbdaf6e9f4e2a7fd640287c01e6bmindyp        showLoadingStatus();
121bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein
122bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein        final Resources r = getResources();
123bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein        mSideMarginInWebPx = (int) ((r.getDimensionPixelOffset(
124bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein                R.dimen.conversation_view_margin_side) + r.getDimensionPixelOffset(
125bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein                R.dimen.conversation_message_content_margin_side)) / r.getDisplayMetrics().density);
126f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
127f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
128f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    @Override
129f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    public View onCreateView(LayoutInflater inflater, ViewGroup container,
130f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp            Bundle savedInstanceState) {
131f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        View rootView = inflater.inflate(R.layout.secure_conversation_view, container, false);
132be7739bf0cebc5018c8ffb0c649fc62a74d74e69Andy Huang        mScrollView = (MessageScrollView) rootView.findViewById(R.id.scroll_view);
133f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        mConversationHeaderView = (ConversationViewHeader) rootView.findViewById(R.id.conv_header);
134f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        mMessageHeaderView = (MessageHeaderView) rootView.findViewById(R.id.message_header);
13526d4d2d9c43c499f458808f050ec73ea3c28dec4mindyp        mMessageFooterView = (MessageFooterView) rootView.findViewById(R.id.message_footer);
136ff282d0ef252dbdaf6e9f4e2a7fd640287c01e6bmindyp        instantiateProgressIndicators(rootView);
137be7739bf0cebc5018c8ffb0c649fc62a74d74e69Andy Huang        mWebView = (MessageWebView) rootView.findViewById(R.id.webview);
138ff282d0ef252dbdaf6e9f4e2a7fd640287c01e6bmindyp        mWebView.setWebViewClient(mWebViewClient);
13905e522165c415f0a16a23117cd7d91a033780890mindyp        mWebView.setFocusable(false);
140f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        final WebSettings settings = mWebView.getSettings();
141f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
142f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        settings.setJavaScriptEnabled(false);
143f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
144f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
145f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        settings.setSupportZoom(true);
146f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        settings.setBuiltInZoomControls(true);
147f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        settings.setDisplayZoomControls(false);
1484d8cad5e37ade03903a23cca8ea3e782af21170fPaul Westbrook
149be7739bf0cebc5018c8ffb0c649fc62a74d74e69Andy Huang        mScrollView.setInnerScrollableView(mWebView);
150be7739bf0cebc5018c8ffb0c649fc62a74d74e69Andy Huang
151f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        return rootView;
152f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
153f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
154f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    @Override
155fafcd17adae9b7ba5c270611d0f53608ced92e2eScott Kennedy    protected WebView getWebView() {
156fafcd17adae9b7ba5c270611d0f53608ced92e2eScott Kennedy        return mWebView;
157fafcd17adae9b7ba5c270611d0f53608ced92e2eScott Kennedy    }
158fafcd17adae9b7ba5c270611d0f53608ced92e2eScott Kennedy
159fafcd17adae9b7ba5c270611d0f53608ced92e2eScott Kennedy    @Override
160f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    protected void markUnread() {
161d82a31f04f2a4cce27c8023d5330ff13aad198b0Vikram Aggarwal        super.markUnread();
162d82a31f04f2a4cce27c8023d5330ff13aad198b0Vikram Aggarwal        // Ignore unsafe calls made after a fragment is detached from an activity
163f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        final ControllableActivity activity = (ControllableActivity) getActivity();
164fb05201c2c5c53f58846112240a05849319317a9mindyp        if (activity == null || mConversation == null || mMessage == null) {
165fb05201c2c5c53f58846112240a05849319317a9mindyp            LogUtils.w(LOG_TAG, "ignoring markUnread for conv=%s",
166fb05201c2c5c53f58846112240a05849319317a9mindyp                    mConversation != null ? mConversation.id : 0);
167f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp            return;
168f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        }
169d82a31f04f2a4cce27c8023d5330ff13aad198b0Vikram Aggarwal        final HashSet<Uri> uris = new HashSet<Uri>();
170f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        uris.add(mMessage.uri);
171f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        activity.getConversationUpdater().markConversationMessagesUnread(mConversation, uris,
172351ad4e87e0b0b98df9ca88266a8a63541dc5a81Andy Huang                mViewState.getConversationInfo());
173f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
174f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
175f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    @Override
176adbf3e8cadb66666f307352b72537fbac57b916fAndy Huang    public void onAccountChanged(Account newAccount, Account oldAccount) {
177f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        // Do nothing.
178f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
179f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
180f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    @Override
181f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    public void onConversationViewHeaderHeightChange(int newHeight) {
182f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        // Do nothing.
183f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
184f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
185f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    @Override
186f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    public void onUserVisibleHintChanged() {
187604f7716eaac3bc0989cdb2ff129c383b6dfe4d6mindyp        if (mActivity == null) {
188604f7716eaac3bc0989cdb2ff129c383b6dfe4d6mindyp            return;
189604f7716eaac3bc0989cdb2ff129c383b6dfe4d6mindyp        }
19051ad9041014920d78d9b7b3ab84ec04a7c41beaeVikram Aggarwal        if (isUserVisible()) {
19151ad9041014920d78d9b7b3ab84ec04a7c41beaeVikram Aggarwal            onConversationSeen();
192604f7716eaac3bc0989cdb2ff129c383b6dfe4d6mindyp        }
193f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
194f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
195f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    @Override
1962e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang    public void setMessageSpacerHeight(MessageHeaderItem item, int newSpacerHeight) {
1972e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        // Do nothing.
1982e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang    }
1992e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang
2002e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang    @Override
2012e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang    public void setMessageExpanded(MessageHeaderItem item, int newSpacerHeight) {
2022e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        // Do nothing.
2032e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang    }
2042e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang
2052e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang    @Override
2062e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang    public void setMessageDetailsExpanded(MessageHeaderItem i, boolean expanded, int heightbefore) {
2072e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        // Do nothing.
2082e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang    }
2092e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang
2102e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang    @Override
211eb9a4bdc53269ee05fe11870b9ebf03f18196585Scott Kennedy    public void showExternalResources(final Message msg) {
212eb9a4bdc53269ee05fe11870b9ebf03f18196585Scott Kennedy        mWebView.getSettings().setBlockNetworkImage(false);
213eb9a4bdc53269ee05fe11870b9ebf03f18196585Scott Kennedy    }
214eb9a4bdc53269ee05fe11870b9ebf03f18196585Scott Kennedy
215eb9a4bdc53269ee05fe11870b9ebf03f18196585Scott Kennedy    @Override
216eb9a4bdc53269ee05fe11870b9ebf03f18196585Scott Kennedy    public void showExternalResources(final String rawSenderAddress) {
217f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        mWebView.getSettings().setBlockNetworkImage(false);
218f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
219f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
220f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    @Override
22175b52a50a7b8382d9046d48ea8cda97b5471cbc8Andy Huang    public boolean supportsMessageTransforms() {
22275b52a50a7b8382d9046d48ea8cda97b5471cbc8Andy Huang        return false;
22375b52a50a7b8382d9046d48ea8cda97b5471cbc8Andy Huang    }
22475b52a50a7b8382d9046d48ea8cda97b5471cbc8Andy Huang
22575b52a50a7b8382d9046d48ea8cda97b5471cbc8Andy Huang    @Override
2261ebc2db723ed29093d724eb5da906a496ee57224Alice Yang    public String getMessageTransforms(final Message msg) {
2271ebc2db723ed29093d724eb5da906a496ee57224Alice Yang        return null;
2281ebc2db723ed29093d724eb5da906a496ee57224Alice Yang    }
2291ebc2db723ed29093d724eb5da906a496ee57224Alice Yang
2301ebc2db723ed29093d724eb5da906a496ee57224Alice Yang    @Override
231c42ad5ea3a49e6045a79d1fde3d858033176e67bPaul Westbrook    protected void onMessageCursorLoadFinished(Loader<ObjectCursor<ConversationMessage>> loader,
232c42ad5ea3a49e6045a79d1fde3d858033176e67bPaul Westbrook            MessageCursor newCursor, MessageCursor oldCursor) {
233f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        // ignore cursors that are still loading results
234014ea4c15d147794789b9c5bf4e243fa08781ad9Andy Huang        if (newCursor == null || !newCursor.isLoaded()) {
235f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp            LogUtils.i(LOG_TAG, "CONV RENDER: existing cursor is null, rendering from scratch");
236f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp            return;
237f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        }
2381abfcaf0ee345acee28f0b4892314119082b28a2Mark Wei        if (mActivity == null || mActivity.isFinishing()) {
2391abfcaf0ee345acee28f0b4892314119082b28a2Mark Wei            // Activity is finishing, just bail.
2401abfcaf0ee345acee28f0b4892314119082b28a2Mark Wei            return;
2411abfcaf0ee345acee28f0b4892314119082b28a2Mark Wei        }
2422e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        renderMessageBodies(newCursor);
243f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
244f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp
245f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    /**
246f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     * Populate the adapter with overlay views (message headers, super-collapsed
247f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     * blocks, a conversation header), and return an HTML document with spacer
248f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     * divs inserted for all overlays.
249f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp     */
2502e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang    private void renderMessageBodies(MessageCursor messageCursor) {
2512e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        if (!messageCursor.moveToFirst()) {
2522e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang            LogUtils.e(LOG_TAG, "unable to open message cursor");
2532e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang            return;
2542e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        }
2552e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        final ConversationMessage m = messageCursor.getMessage();
2562e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        mMessage = messageCursor.getMessage();
2572e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        mWebView.getSettings().setBlockNetworkImage(!mMessage.alwaysShowImages);
258bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein
259bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein        // Add formatting to message body
260bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein        // At this point, only adds margins.
261bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein        StringBuilder dataBuilder = new StringBuilder(
262bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein                String.format(BEGIN_HTML, mSideMarginInWebPx));
263bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein        dataBuilder.append(m.getBodyAsHtml());
264bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein        dataBuilder.append(END_HTML);
265bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein
266bf1d35fab89443d8e380ab48e98ac1c8cd7a6686Andrew Sapperstein        mWebView.loadDataWithBaseURL(mBaseUri, dataBuilder.toString(), "text/html", "utf-8", null);
2672e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        final ConversationViewAdapter adapter = new ConversationViewAdapter(mActivity, null, null,
2682e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang                null, null, null, null, null, null);
2692e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        final MessageHeaderItem item = adapter.newMessageHeaderItem(mMessage, true,
2702e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang                mMessage.alwaysShowImages);
2712e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        mMessageHeaderView.bind(item, false);
2722e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang        if (mMessage.hasAttachments) {
2732e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang            mMessageFooterView.setVisibility(View.VISIBLE);
2742e57e5485504c9ea2e5b5186f22bb76ea5f7bf6dAndy Huang            mMessageFooterView.bind(item, false);
27526d4d2d9c43c499f458808f050ec73ea3c28dec4mindyp        }
27626d4d2d9c43c499f458808f050ec73ea3c28dec4mindyp    }
27726d4d2d9c43c499f458808f050ec73ea3c28dec4mindyp
27826d4d2d9c43c499f458808f050ec73ea3c28dec4mindyp    @Override
27926d4d2d9c43c499f458808f050ec73ea3c28dec4mindyp    public void onConversationUpdated(Conversation conv) {
28026d4d2d9c43c499f458808f050ec73ea3c28dec4mindyp        final ConversationViewHeader headerView = mConversationHeaderView;
28126d4d2d9c43c499f458808f050ec73ea3c28dec4mindyp        if (headerView != null) {
28226d4d2d9c43c499f458808f050ec73ea3c28dec4mindyp            headerView.onConversationUpdated(conv);
28351ad9041014920d78d9b7b3ab84ec04a7c41beaeVikram Aggarwal            headerView.setSubject(conv.subject);
284f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp        }
285f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp    }
2861b3cc47f54072105c161d6ed557550e0e149b8bbmindyp
287f4fce1227d8b49f45e6569f1590565f2df9e8d6emindyp}
288