14ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein/*
24ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * Copyright (C) 2013 Google Inc.
34ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * Licensed to The Android Open Source Project.
44ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein *
54ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * Licensed under the Apache License, Version 2.0 (the "License");
64ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * you may not use this file except in compliance with the License.
74ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * You may obtain a copy of the License at
84ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein *
94ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein *      http://www.apache.org/licenses/LICENSE-2.0
104ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein *
114ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * Unless required by applicable law or agreed to in writing, software
124ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * distributed under the License is distributed on an "AS IS" BASIS,
134ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * See the License for the specific language governing permissions and
154ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * limitations under the License.
164ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein */
174ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
184ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinpackage com.android.mail.browse;
194ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
20cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantlerimport android.app.Activity;
214ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport android.app.Fragment;
224ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport android.app.LoaderManager;
237638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sappersteinimport android.content.CursorLoader;
244ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport android.content.Loader;
257638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sappersteinimport android.database.Cursor;
264ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport android.net.Uri;
274ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport android.os.Bundle;
284ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport android.os.Handler;
297638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sappersteinimport android.provider.OpenableColumns;
30f4bb971c2da34f2dbef505af5159333cb510e781Aurimas Liutikasimport android.support.v7.app.AppCompatActivity;
314ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport android.view.LayoutInflater;
32f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sappersteinimport android.view.Menu;
33f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sappersteinimport android.view.MenuInflater;
34562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sappersteinimport android.view.MenuItem;
354ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport android.view.View;
364ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport android.view.ViewGroup;
37934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieuximport android.webkit.WebResourceResponse;
384ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport android.webkit.WebView;
39cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantlerimport android.widget.Toast;
404ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
41821e578a71c7015646522e729600618f0ec16fc0Tony Mantlerimport com.android.emailcommon.mail.Address;
427638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sappersteinimport com.android.mail.R;
434ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport com.android.mail.providers.Account;
444ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport com.android.mail.ui.AbstractConversationWebViewClient;
454ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport com.android.mail.ui.ContactLoaderCallbacks;
464ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport com.android.mail.ui.SecureConversationViewController;
474ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport com.android.mail.ui.SecureConversationViewControllerCallbacks;
484b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrookimport com.android.mail.utils.LogTag;
494b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrookimport com.android.mail.utils.LogUtils;
50f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sappersteinimport com.android.mail.utils.Utils;
514ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport com.google.common.collect.ImmutableList;
524ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport com.google.common.collect.Sets;
534ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
544ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport java.util.Collections;
554ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport java.util.HashMap;
564ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport java.util.List;
574ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport java.util.Map;
584ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinimport java.util.Set;
594ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
604ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein/**
614ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * Fragment that is used to view EML files. It is mostly stubs
624ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * that calls {@link SecureConversationViewController} to do most
634ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein * of the rendering work.
644ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein */
654ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sappersteinpublic class EmlMessageViewFragment extends Fragment
667638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        implements SecureConversationViewControllerCallbacks {
674ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    private static final String ARG_EML_FILE_URI = "eml_file_uri";
684ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    private static final String BASE_URI = "x-thread://message/rfc822/";
697638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein
704ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    private static final int MESSAGE_LOADER = 0;
714ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    private static final int CONTACT_LOADER = 1;
727638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein    private static final int FILENAME_LOADER = 2;
734ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
744b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrook    private static final String LOG_TAG = LogTag.getLogTag();
754b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrook
764ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    private final Handler mHandler = new Handler();
774ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
784ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    private EmlWebViewClient mWebViewClient;
794ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    private SecureConversationViewController mViewController;
804ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    private ContactLoaderCallbacks mContactLoaderCallbacks;
814ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
827638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein    private final MessageLoadCallbacks mMessageLoadCallbacks = new MessageLoadCallbacks();
837638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein    private final FilenameLoadCallbacks mFilenameLoadCallbacks = new FilenameLoadCallbacks();
847638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein
854ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    private Uri mEmlFileUri;
864ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
87cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler    private boolean mMessageLoadFailed;
88cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler
894ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    /**
904ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     * Cache of email address strings to parsed Address objects.
914ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     * <p>
924ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     * Remember to synchronize on the map when reading or writing to this cache, because some
934ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     * instances use it off the UI thread (e.g. from WebView).
944ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     */
954ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    protected final Map<String, Address> mAddressCache = Collections.synchronizedMap(
964ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            new HashMap<String, Address>());
974ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
984ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    private class EmlWebViewClient extends AbstractConversationWebViewClient {
994ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        public EmlWebViewClient(Account account) {
1004ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            super(account);
1014ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        }
1024ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
1034ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        @Override
104934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
105934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux            // try to load the url assuming it is a cid url
106934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux            final Uri uri = Uri.parse(url);
107934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux            final WebResourceResponse response = loadCIDUri(uri, mViewController.getMessage());
108934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux            if (response != null) {
109934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux                return response;
110934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux            }
111934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux
112934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux            return super.shouldInterceptRequest(view, url);
113934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux        }
114934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux
115934b1f470a646a4ca64fc63eeb823d4c5c12698eJames Lemieux        @Override
1164ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        public void onPageFinished(WebView view, String url) {
1174b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrook            // Ignore unsafe calls made after a fragment is detached from an activity.
1184b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrook            // This method needs to, for example, get at the loader manager, which needs
1194b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrook            // the fragment to be added.
1204b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrook            if (!isAdded()) {
1214b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrook                LogUtils.d(LOG_TAG, "ignoring EMLVF.onPageFinished, url=%s fragment=%s", url,
1224b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrook                        EmlMessageViewFragment.this);
1234b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrook                return;
1244b23dcad99603ec59734cb22cccebbbd3f4a4210Paul Westbrook            }
1254ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            mViewController.dismissLoadingStatus();
1264ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
1274ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            final Set<String> emailAddresses = Sets.newHashSet();
1284ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            final List<Address> cacheCopy;
1294ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            synchronized (mAddressCache) {
1304ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein                cacheCopy = ImmutableList.copyOf(mAddressCache.values());
1314ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            }
1324ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            for (Address addr : cacheCopy) {
1334ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein                emailAddresses.add(addr.getAddress());
1344ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            }
1354ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            final ContactLoaderCallbacks callbacks = getContactInfoSource();
1364ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            callbacks.setSenders(emailAddresses);
1374ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            getLoaderManager().restartLoader(CONTACT_LOADER, Bundle.EMPTY, callbacks);
1384ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        }
139cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler    }
1404ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
1414ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    /**
1424ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     * Creates a new instance of {@link EmlMessageViewFragment},
1434ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     * initialized to display an eml file from the specified {@link Uri}.
1444ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     */
1457638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein    public static EmlMessageViewFragment newInstance(Uri emlFileUri, Uri accountUri) {
1464ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        EmlMessageViewFragment f = new EmlMessageViewFragment();
147f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sapperstein        Bundle args = new Bundle(1);
1484ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        args.putParcelable(ARG_EML_FILE_URI, emlFileUri);
1494ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        f.setArguments(args);
1504ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        return f;
1514ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
1524ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
1534ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    /**
1544ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     * Constructor needs to be public to handle orientation changes and activity
1554ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     * lifecycle events.
1564ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein     */
157f0ea4849bf7a2c11f99ca0b42307ae8ba665b1dcPaul Westbrook    public EmlMessageViewFragment() {}
1584ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
1594ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
1604ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public void onCreate(Bundle savedState) {
1614ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        super.onCreate(savedState);
1624ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
1634ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        Bundle args = getArguments();
1644ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        mEmlFileUri = args.getParcelable(ARG_EML_FILE_URI);
1654ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
1664ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        mWebViewClient = new EmlWebViewClient(null);
1674ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        mViewController = new SecureConversationViewController(this);
1687638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein
169562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein        setHasOptionsMenu(true);
1704ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
1714ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
1724ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
1734ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public View onCreateView(LayoutInflater inflater, ViewGroup container,
1744ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            Bundle savedInstanceState) {
1754ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        return mViewController.onCreateView(inflater, container, savedInstanceState);
1764ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
1774ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
1784ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
1794ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public void onActivityCreated(Bundle savedInstanceState) {
1804ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        super.onActivityCreated(savedInstanceState);
181cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler        if (mMessageLoadFailed) {
182cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler            bailOutOnLoadError();
183cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler            return;
184cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler        }
185b622d2b6750423c185a2a2463277e5e2b853fadaAndy Huang        mWebViewClient.setActivity(getActivity());
1864ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        mViewController.onActivityCreated(savedInstanceState);
1874ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
1884ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
189562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein    @Override
190f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sapperstein    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
191f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sapperstein        if (Utils.isRunningKitkatOrLater()) {
192f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sapperstein            inflater.inflate(R.menu.eml_fragment_menu, menu);
193f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sapperstein        }
194f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sapperstein    }
195f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sapperstein
196f59d01c3116dc2adde97a5b52aa6094144c2d315Andrew Sapperstein    @Override
197562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein    public boolean onOptionsItemSelected(MenuItem item) {
198562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein        final int itemId = item.getItemId();
199562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein        if (itemId == R.id.print_message) {
200562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein            mViewController.printMessage();
201562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein        } else {
202562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein            return super.onOptionsItemSelected(item);
203562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein        }
204562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein
205562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein        return true;
206562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein    }
207562c5ba7235948cf1d20a9afa40e67cd62f43cf7Andrew Sapperstein
208cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler    private void bailOutOnLoadError() {
209cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler        final Activity activity = getActivity();
210cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler        Toast.makeText(activity, R.string.eml_loader_error_toast, Toast.LENGTH_LONG).show();
211cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler        activity.finish();
212cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler    }
213cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler
2144ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    // Start SecureConversationViewControllerCallbacks
2154ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2164ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2174ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public Handler getHandler() {
2184ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        return mHandler;
2194ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2204ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2214ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2224ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public AbstractConversationWebViewClient getWebViewClient() {
2234ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        return mWebViewClient;
2244ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2254ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2264ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2274ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public Fragment getFragment() {
2284ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        return this;
2294ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2304ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2314ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2324ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public void setupConversationHeaderView(ConversationViewHeader headerView) {
2334ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        // DO NOTHING
2344ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2354ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2364ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2374ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public boolean isViewVisibleToUser() {
2384ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        return true;
2394ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2404ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2414ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2424ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public ContactLoaderCallbacks getContactInfoSource() {
2434ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        if (mContactLoaderCallbacks == null) {
2444ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein            mContactLoaderCallbacks = new ContactLoaderCallbacks(getActivity());
2454ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        }
2464ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        return mContactLoaderCallbacks;
2474ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2484ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2494ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2504ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public ConversationAccountController getConversationAccountController() {
2513de76eca03ed7ec1d40f2cce23cbbbe8e5e6d70fAndrew Sapperstein        return (EmlViewerActivity) getActivity();
2524ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2534ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2544ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2554ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public Map<String, Address> getAddressCache() {
2564ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        return mAddressCache;
2574ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2584ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2594ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2604ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public void setupMessageHeaderVeiledMatcher(MessageHeaderView messageHeaderView) {
2614ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        // DO NOTHING
2624ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2634ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2644ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2654ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public void startMessageLoader() {
2667638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        final LoaderManager manager = getLoaderManager();
2677638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        manager.initLoader(MESSAGE_LOADER, null, mMessageLoadCallbacks);
2687638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        manager.initLoader(FILENAME_LOADER, null, mFilenameLoadCallbacks);
2694ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2704ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2714ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2724ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public String getBaseUri() {
2734ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        return BASE_URI;
2744ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2754ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2764ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    @Override
2774ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    public boolean isViewOnlyMode() {
2784ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        return true;
2794ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
2804ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2817638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein    @Override
2828ec43e877a9c1925514f066655984e21fbd255e8Andrew Sapperstein    public boolean shouldAlwaysShowImages() {
2838ec43e877a9c1925514f066655984e21fbd255e8Andrew Sapperstein        return false;
2848ec43e877a9c1925514f066655984e21fbd255e8Andrew Sapperstein    }
2858ec43e877a9c1925514f066655984e21fbd255e8Andrew Sapperstein
2864ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    // End SecureConversationViewControllerCallbacks
2874ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
2887638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein    private class MessageLoadCallbacks
2897638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein            implements LoaderManager.LoaderCallbacks<ConversationMessage> {
2907638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        @Override
2917638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        public Loader<ConversationMessage> onCreateLoader(int id, Bundle args) {
2927638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein            switch (id) {
2937638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein                case MESSAGE_LOADER:
2947638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein                    return new EmlMessageLoader(getActivity(), mEmlFileUri);
2957638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein                default:
2967638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein                    return null;
2977638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein            }
2987638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        }
2994ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
3007638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        @Override
3017638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        public void onLoadFinished(Loader<ConversationMessage> loader, ConversationMessage data) {
302cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler            if (data == null) {
303cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler                final Activity activity = getActivity();
304cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler                if (activity != null) {
305cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler                    bailOutOnLoadError();
306cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler                } else {
307cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler                    mMessageLoadFailed = true;
308cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler                }
309cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler                return;
310cd10aee59ff768745d0a75bfd659e0ec53ac88deTony Mantler            }
3117638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein            mViewController.setSubject(data.subject);
3127638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein            mViewController.renderMessage(data);
3134ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein        }
3144ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
3157638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        @Override
3167638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        public void onLoaderReset(Loader<ConversationMessage> loader) {
3177638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein            // Do nothing
3187638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        }
3194ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
3204ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
3217638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein    private class FilenameLoadCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {
3227638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        @Override
3237638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
3247638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein            switch (id) {
3257638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein                case FILENAME_LOADER:
3267638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein                    return new CursorLoader(getActivity(), mEmlFileUri,
327c9524ef7a38c0f949fe614e96af3a5313f36aa0fAndrew Sapperstein                            new String[] { OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE },
328c9524ef7a38c0f949fe614e96af3a5313f36aa0fAndrew Sapperstein                            null, null, null);
3297638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein                default:
3307638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein                    return null;
3317638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein            }
3327638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        }
3337638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein
3347638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        @Override
3357638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
336459e2e7829cc53c911cc9c153e08a5deed7c1b97Andrew Sapperstein            if (data == null || !data.moveToFirst()) {
337459e2e7829cc53c911cc9c153e08a5deed7c1b97Andrew Sapperstein                return;
338459e2e7829cc53c911cc9c153e08a5deed7c1b97Andrew Sapperstein            }
339459e2e7829cc53c911cc9c153e08a5deed7c1b97Andrew Sapperstein
340f4bb971c2da34f2dbef505af5159333cb510e781Aurimas Liutikas            ((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(
3417638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein                    data.getString(data.getColumnIndex(OpenableColumns.DISPLAY_NAME)));
3427638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        }
3437638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein
3447638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        @Override
3457638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        public void onLoaderReset(Loader<Cursor> loader) {
3467638a1004e7c8ed7a85620243da3b051b60217e8Andrew Sapperstein        }
3474ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein    }
3484ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein
3494ddda2f0a4ee5381a90779a6939b05b064ce5d11Andrew Sapperstein}
350