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