1bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/* 2bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Copyright (C) 2011 The Android Open Source Project 3bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 4bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Licensed under the Apache License, Version 2.0 (the "License"); 5bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * you may not use this file except in compliance with the License. 6bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * You may obtain a copy of the License at 7bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 8bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * http://www.apache.org/licenses/LICENSE-2.0 9bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 10bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Unless required by applicable law or agreed to in writing, software 11bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * distributed under the License is distributed on an "AS IS" BASIS, 12bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * See the License for the specific language governing permissions and 14bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * limitations under the License. 15bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 16bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 17bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpackage com.android.email.activity; 18bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.app.Activity; 20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.app.Fragment; 21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.app.FragmentManager; 22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.app.FragmentTransaction; 23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.os.Bundle; 24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.util.Log; 25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.view.Menu; 26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.view.MenuInflater; 27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.view.MenuItem; 28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.Email; 30bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.FolderProperties; 31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.MessageListContext; 32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.Preferences; 33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.R; 34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.RefreshManager; 35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.RequireManualSyncDialog; 36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.activity.setup.AccountSettings; 37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.activity.setup.MailboxSettings; 38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.Logging; 39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.Account; 40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.EmailContent.Message; 41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.HostAuth; 42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.Mailbox; 43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.utility.EmailAsyncTask; 44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.utility.Utility; 45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.google.common.base.Objects; 46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.google.common.base.Preconditions; 47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.util.LinkedList; 49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.util.List; 50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/** 52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Base class for the UI controller. 53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookabstract class UIControllerBase implements MailboxListFragment.Callback, 55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MessageListFragment.Callback, MessageViewFragment.Callback { 56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook static final boolean DEBUG_FRAGMENTS = false; // DO NOT SUBMIT WITH TRUE 57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook static final String KEY_LIST_CONTEXT = "UIControllerBase.listContext"; 59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** The owner activity */ 61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final EmailActivity mActivity; 62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final FragmentManager mFragmentManager; 63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final ActionBarController mActionBarController; 65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private MessageOrderManager mOrderManager; 67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final MessageOrderManagerCallback mMessageOrderManagerCallback = 68bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook new MessageOrderManagerCallback(); 69bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 70bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final EmailAsyncTask.Tracker mTaskTracker = new EmailAsyncTask.Tracker(); 71bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 72bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final RefreshManager mRefreshManager; 73bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 74bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Fragments that are installed. 76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * A fragment is installed in {@link Fragment#onActivityCreated} and uninstalled in 78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link Fragment#onDestroyView}, using {@link FragmentInstallable} callbacks. 79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This means fragments in the back stack are *not* installed. 81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * We set callbacks to fragments only when they are installed. 83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @see FragmentInstallable 85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private MailboxListFragment mMailboxListFragment; 87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private MessageListFragment mMessageListFragment; 88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private MessageViewFragment mMessageViewFragment; 89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * To avoid double-deleting a fragment (which will cause a runtime exception), 92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * we put a fragment in this list when we {@link FragmentTransaction#remove(Fragment)} it, 93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * and remove from the list when we actually uninstall it. 94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final List<Fragment> mRemovedFragments = new LinkedList<Fragment>(); 96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The NfcHandler implements Near Field Communication sharing features 99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * whenever the activity is in the foreground. 100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private NfcHandler mNfcHandler; 102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The active context for the current MessageList. 105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * In some UI layouts such as the one-pane view, the message list may not be visible, but is 106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * on the backstack. This list context will still be accessible in those cases. 107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Should be set using {@link #setListContext(MessageListContext)}. 109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected MessageListContext mListContext; 111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private class RefreshListener implements RefreshManager.Listener { 113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private MenuItem mRefreshIcon; 114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onMessagingError(final long accountId, long mailboxId, final String message) { 117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook updateRefreshIcon(); 118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onRefreshStatusChanged(long accountId, long mailboxId) { 122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook updateRefreshIcon(); 123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook void setRefreshIcon(MenuItem icon) { 126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mRefreshIcon = icon; 127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook updateRefreshIcon(); 128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private void updateRefreshIcon() { 131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mRefreshIcon == null) { 132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return; 133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (isRefreshInProgress()) { 136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mRefreshIcon.setActionView(R.layout.action_bar_indeterminate_progress); 137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mRefreshIcon.setActionView(null); 139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook }; 142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final RefreshListener mRefreshListener = new RefreshListener(); 144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public UIControllerBase(EmailActivity activity) { 146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity = activity; 147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mFragmentManager = activity.getFragmentManager(); 148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mRefreshManager = RefreshManager.getInstance(mActivity); 149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActionBarController = createActionBarController(activity); 150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (DEBUG_FRAGMENTS) { 151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook FragmentManager.enableDebugLogging(true); 152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 155bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 156bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Called by the base class to let a subclass create an {@link ActionBarController}. 157bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 158bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected abstract ActionBarController createActionBarController(Activity activity); 159bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 160bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** @return the layout ID for the activity. */ 161bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public abstract int getLayoutId(); 162bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 164bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Must be called just after the activity sets up the content view. Used to initialize views. 165bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 166bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * (Due to the complexity regarding class/activity initialization order, we can't do this in 167bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the constructor.) 168bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 169bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onActivityViewReady() { 170bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 171bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " onActivityViewReady"); 172bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 173bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 174bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 175bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 176bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Called at the end of {@link EmailActivity#onCreate}. 177bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 178bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onActivityCreated() { 179bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 180bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " onActivityCreated"); 181bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 182bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mRefreshManager.registerListener(mRefreshListener); 183bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActionBarController.onActivityCreated(); 184bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mNfcHandler = NfcHandler.register(this, mActivity); 185bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 186bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 187bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 188bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the {@link android.app.Activity#onStart} callback. 189bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 190bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onActivityStart() { 191bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 192bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " onActivityStart"); 193bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 194bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (isMessageViewInstalled()) { 195bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook updateMessageOrderManager(); 196bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 197bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 198bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 199bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 200bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the {@link android.app.Activity#onResume} callback. 201bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 202bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onActivityResume() { 203bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 204bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " onActivityResume"); 205bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 206bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook refreshActionBar(); 207bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mNfcHandler != null) { 208bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mNfcHandler.onAccountChanged(); // workaround for email not set on initial load 209bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 210bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook long accountId = getUIAccountId(); 211bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Preferences.getPreferences(mActivity).setLastUsedAccountId(accountId); 212bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook showAccountSpecificWarning(accountId); 213bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 214bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 215bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 216bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the {@link android.app.Activity#onPause} callback. 217bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 218bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onActivityPause() { 219bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 220bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " onActivityPause"); 221bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 222bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 223bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 224bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 225bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the {@link android.app.Activity#onStop} callback. 226bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 227bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onActivityStop() { 228bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 229bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " onActivityStop"); 230bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 231bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook stopMessageOrderManager(); 232bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 233bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 234bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 235bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the {@link android.app.Activity#onDestroy} callback. 236bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 237bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onActivityDestroy() { 238bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 239bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " onActivityDestroy"); 240bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 241bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActionBarController.onActivityDestroy(); 242bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mRefreshManager.unregisterListener(mRefreshListener); 243bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mTaskTracker.cancellAllInterrupt(); 244bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 245bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 246bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 247bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the {@link android.app.Activity#onSaveInstanceState} callback. 248bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 249bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onSaveInstanceState(Bundle outState) { 250bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 251bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " onSaveInstanceState"); 252bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 253bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActionBarController.onSaveInstanceState(outState); 254bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook outState.putParcelable(KEY_LIST_CONTEXT, mListContext); 255bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 256bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 257bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 258bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the {@link android.app.Activity#onRestoreInstanceState} callback. 259bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 260bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onRestoreInstanceState(Bundle savedInstanceState) { 261bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 262bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " restoreInstanceState"); 263bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 264bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActionBarController.onRestoreInstanceState(savedInstanceState); 265bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mListContext = savedInstanceState.getParcelable(KEY_LIST_CONTEXT); 266bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 267bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 268bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // MessageViewFragment$Callback 269bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 270bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onMessageSetUnread() { 271bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook doAutoAdvance(); 272bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 273bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 274bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // MessageViewFragment$Callback 275bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 276bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onMessageNotExists() { 277bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook doAutoAdvance(); 278bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 279bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 280bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // MessageViewFragment$Callback 281bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 282bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onRespondedToInvite(int response) { 283bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook doAutoAdvance(); 284bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 285bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 286bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // MessageViewFragment$Callback 287bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 288bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onBeforeMessageGone() { 289bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook doAutoAdvance(); 290bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 291bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 292bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 293bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Install a fragment. Must be caleld from the host activity's 294bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link FragmentInstallable#onInstallFragment}. 295bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 296bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final void onInstallFragment(Fragment fragment) { 297bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 298bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " onInstallFragment fragment=" + fragment); 299bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 300bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (fragment instanceof MailboxListFragment) { 301bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook installMailboxListFragment((MailboxListFragment) fragment); 302bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else if (fragment instanceof MessageListFragment) { 303bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook installMessageListFragment((MessageListFragment) fragment); 304bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else if (fragment instanceof MessageViewFragment) { 305bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook installMessageViewFragment((MessageViewFragment) fragment); 306bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 307bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new IllegalArgumentException("Tried to install unknown fragment"); 308bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 309bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 310bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 311bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** Install fragment */ 312bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void installMailboxListFragment(MailboxListFragment fragment) { 313bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMailboxListFragment = fragment; 314bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMailboxListFragment.setCallback(this); 315bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 316bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // TODO: consolidate this refresh with the one that the Fragment itself does. since 317bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // the fragment calls setHasOptionsMenu(true) - it invalidates when it gets attached. 318bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // However the timing is slightly different and leads to a delay in update if this isn't 319bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // here - investigate why. same for the other installs. 320bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook refreshActionBar(); 321bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 322bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 323bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** Install fragment */ 324bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void installMessageListFragment(MessageListFragment fragment) { 325bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMessageListFragment = fragment; 326bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMessageListFragment.setCallback(this); 327bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook refreshActionBar(); 328bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 329bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 330bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** Install fragment */ 331bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void installMessageViewFragment(MessageViewFragment fragment) { 332bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMessageViewFragment = fragment; 333bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMessageViewFragment.setCallback(this); 334bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 335bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook updateMessageOrderManager(); 336bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook refreshActionBar(); 337bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 338bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 339bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 340bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Uninstall a fragment. Must be caleld from the host activity's 341bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link FragmentInstallable#onUninstallFragment}. 342bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 343bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final void onUninstallFragment(Fragment fragment) { 344bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 345bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " onUninstallFragment fragment=" + fragment); 346bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 347bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mRemovedFragments.remove(fragment); 348bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (fragment == mMailboxListFragment) { 349bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook uninstallMailboxListFragment(); 350bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else if (fragment == mMessageListFragment) { 351bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook uninstallMessageListFragment(); 352bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else if (fragment == mMessageViewFragment) { 353bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook uninstallMessageViewFragment(); 354bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 355bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new IllegalArgumentException("Tried to uninstall unknown fragment"); 356bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 357bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 358bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 359bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** Uninstall {@link MailboxListFragment} */ 360bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void uninstallMailboxListFragment() { 361bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMailboxListFragment.setCallback(null); 362bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMailboxListFragment = null; 363bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 364bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 365bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** Uninstall {@link MessageListFragment} */ 366bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void uninstallMessageListFragment() { 367bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMessageListFragment.setCallback(null); 368bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMessageListFragment = null; 369bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 370bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 371bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** Uninstall {@link MessageViewFragment} */ 372bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void uninstallMessageViewFragment() { 373bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMessageViewFragment.setCallback(null); 374bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mMessageViewFragment = null; 375bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 376bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 377bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 378bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * If a {@link Fragment} is not already in {@link #mRemovedFragments}, 379bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link FragmentTransaction#remove} it and add to the list. 380bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 381bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Do nothing if {@code fragment} is null. 382bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 383bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final void removeFragment(FragmentTransaction ft, Fragment fragment) { 384bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 385bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " removeFragment fragment=" + fragment); 386bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 387bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (fragment == null) { 388bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return; 389bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 390bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!mRemovedFragments.contains(fragment)) { 391bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Remove try/catch when b/4981556 is fixed (framework bug) 392bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook try { 393bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ft.remove(fragment); 394bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } catch (IllegalStateException ex) { 395bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.e(Logging.LOG_TAG, "Swalling IllegalStateException due to known bug for " 396bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook + " fragment: " + fragment, ex); 397bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.e(Logging.LOG_TAG, Utility.dumpFragment(fragment)); 398bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 399bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook addFragmentToRemovalList(fragment); 400bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 401bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 402bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 403bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 404bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Remove a {@link Fragment} from {@link #mRemovedFragments}. No-op if {@code fragment} is 405bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * null. 406bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 407bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link #removeMailboxListFragment}, {@link #removeMessageListFragment} and 408bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link #removeMessageViewFragment} all call this, so subclasses don't have to do this when 409bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * using them. 410bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 411bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * However, unfortunately, subclasses have to call this manually when popping from the 412bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * back stack to avoid double-delete. 413bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 414bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void addFragmentToRemovalList(Fragment fragment) { 415bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (fragment != null) { 416bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mRemovedFragments.add(fragment); 417bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 418bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 419bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 420bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 421bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Remove the fragment if it's installed. 422bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 423bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected FragmentTransaction removeMailboxListFragment(FragmentTransaction ft) { 424bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook removeFragment(ft, mMailboxListFragment); 425bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return ft; 426bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 427bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 428bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 429bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Remove the fragment if it's installed. 430bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 431bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected FragmentTransaction removeMessageListFragment(FragmentTransaction ft) { 432bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook removeFragment(ft, mMessageListFragment); 433bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return ft; 434bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 435bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 436bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 437bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Remove the fragment if it's installed. 438bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 439bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected FragmentTransaction removeMessageViewFragment(FragmentTransaction ft) { 440bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook removeFragment(ft, mMessageViewFragment); 441bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return ft; 442bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 443bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 444bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** @return true if a {@link MailboxListFragment} is installed. */ 445bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final boolean isMailboxListInstalled() { 446bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mMailboxListFragment != null; 447bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 448bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 449bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** @return true if a {@link MessageListFragment} is installed. */ 450bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final boolean isMessageListInstalled() { 451bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mMessageListFragment != null; 452bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 453bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 454bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** @return true if a {@link MessageViewFragment} is installed. */ 455bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final boolean isMessageViewInstalled() { 456bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mMessageViewFragment != null; 457bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 458bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 459bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** @return the installed {@link MailboxListFragment} or null. */ 460bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final MailboxListFragment getMailboxListFragment() { 461bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mMailboxListFragment; 462bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 463bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 464bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** @return the installed {@link MessageListFragment} or null. */ 465bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final MessageListFragment getMessageListFragment() { 466bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mMessageListFragment; 467bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 468bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 469bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** @return the installed {@link MessageViewFragment} or null. */ 470bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final MessageViewFragment getMessageViewFragment() { 471bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mMessageViewFragment; 472bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 473bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 474bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 475bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Commit a {@link FragmentTransaction}. 476bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 477bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void commitFragmentTransaction(FragmentTransaction ft) { 478bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (DEBUG_FRAGMENTS) { 479bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, this + " commitFragmentTransaction: " + ft); 480bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 481bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!ft.isEmpty()) { 482bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // NB: there should be no cases in which a transaction is committed after 483bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // onSaveInstanceState. Unfortunately, the "state loss" check also happens when in 484bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // LoaderCallbacks.onLoadFinished, and we wish to perform transactions there. The check 485bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // by the framework is conservative and prevents cases where there are transactions 486bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // affecting Loader lifecycles - but we have no such cases. 487bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // TODO: use asynchronous callbacks from loaders to avoid this implicit dependency 488bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ft.commitAllowingStateLoss(); 489bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mFragmentManager.executePendingTransactions(); 490bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 491bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 492bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 493bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 494bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return the currently selected account ID, *or* {@link Account#ACCOUNT_ID_COMBINED_VIEW}. 495bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 496bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @see #getActualAccountId() 497bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 498bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public abstract long getUIAccountId(); 499bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 500bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 501bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return true if an account is selected, or the current view is the combined view. 502bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 503bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final boolean isAccountSelected() { 504bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return getUIAccountId() != Account.NO_ACCOUNT; 505bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 506bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 507bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 508bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return if an actual account is selected. (i.e. {@link Account#ACCOUNT_ID_COMBINED_VIEW} 509bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * is not considered "actual".s) 510bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 511bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final boolean isActualAccountSelected() { 512bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return isAccountSelected() && (getUIAccountId() != Account.ACCOUNT_ID_COMBINED_VIEW); 513bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 514bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 515bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 516bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return the currently selected account ID. If the current view is the combined view, 517bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * it'll return {@link Account#NO_ACCOUNT}. 518bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 519bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @see #getUIAccountId() 520bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 521bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final long getActualAccountId() { 522bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return isActualAccountSelected() ? getUIAccountId() : Account.NO_ACCOUNT; 523bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 524bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 525bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 526bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Show the default view for the given account. 527bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 528bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param accountId ID of the account to load. Can be {@link Account#ACCOUNT_ID_COMBINED_VIEW}. 529bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Must never be {@link Account#NO_ACCOUNT}. 530bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param forceShowInbox If {@code false} and the given account is already selected, do nothing. 531bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * If {@code false}, we always change the view even if the account is selected. 532bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 533bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final void switchAccount(long accountId, boolean forceShowInbox) { 534bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 535bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Account.isSecurityHold(mActivity, accountId)) { 536bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ActivityHelper.showSecurityHoldDialog(mActivity, accountId); 537bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity.finish(); 538bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return; 539bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 540bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 541bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (accountId == getUIAccountId() && !forceShowInbox) { 542bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Do nothing if the account is already selected. Not even going back to the inbox. 543bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return; 544bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 545bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) { 546bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook openMailbox(accountId, Mailbox.QUERY_ALL_INBOXES); 547bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 548bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook long inboxId = Mailbox.findMailboxOfType(mActivity, accountId, Mailbox.TYPE_INBOX); 549bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (inboxId == Mailbox.NO_MAILBOX) { 550bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // The account doesn't have Inbox yet... Redirect to Welcome and let it wait for 551bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // the initial sync... 552bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.w(Logging.LOG_TAG, "Account " + accountId +" doesn't have Inbox. Redirecting" 553bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook + " to Welcome..."); 554bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Welcome.actionOpenAccountInbox(mActivity, accountId); 555bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity.finish(); 556bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 557bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook openMailbox(accountId, inboxId); 558bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 559bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 560bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mNfcHandler != null) { 561bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mNfcHandler.onAccountChanged(); 562bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 563bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Preferences.getPreferences(mActivity).setLastUsedAccountId(accountId); 564bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook showAccountSpecificWarning(accountId); 565bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 566bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 567bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 568bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Returns the id of the parent mailbox used for the mailbox list fragment. 569bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 570bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * IMPORTANT: Do not confuse {@link #getMailboxListMailboxId()} with 571bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link #getMessageListMailboxId()} 572bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 573bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected long getMailboxListMailboxId() { 574bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return isMailboxListInstalled() ? getMailboxListFragment().getSelectedMailboxId() 575bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook : Mailbox.NO_MAILBOX; 576bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 577bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 578bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 579bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Returns the id of the mailbox used for the message list fragment. 580bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 581bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * IMPORTANT: Do not confuse {@link #getMailboxListMailboxId()} with 582bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link #getMessageListMailboxId()} 583bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 584bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected long getMessageListMailboxId() { 585bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return isMessageListInstalled() ? getMessageListFragment().getMailboxId() 586bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook : Mailbox.NO_MAILBOX; 587bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 588bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 589bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 590bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Shortcut for {@link #open} with {@link Message#NO_MESSAGE}. 591bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 592bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final void openMailbox(long accountId, long mailboxId) { 593bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook open(MessageListContext.forMailbox(accountId, mailboxId), Message.NO_MESSAGE); 594bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 595bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 596bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 597bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Opens a given list 598bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param listContext the list context for the message list to open 599bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param messageId if specified and not {@link Message#NO_MESSAGE}, will open the message 600bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * in the message list. 601bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 602bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public final void open(final MessageListContext listContext, final long messageId) { 603bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook setListContext(listContext); 604bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook openInternal(listContext, messageId); 605bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 606bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (listContext.isSearch()) { 607bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActionBarController.enterSearchMode(listContext.getSearchParams().mFilter); 608bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 609bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 610bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 611bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 612bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Sets the internal value of the list context for the message list. 613bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 614bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void setListContext(MessageListContext listContext) { 615bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Objects.equal(listContext, mListContext)) { 616bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return; 617bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 618bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 619bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Email.DEBUG && Logging.DEBUG_LIFECYCLE) { 620bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.i(Logging.LOG_TAG, this + " setListContext: " + listContext); 621bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 622bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mListContext = listContext; 623bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 624bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 625bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected abstract void openInternal( 626bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final MessageListContext listContext, final long messageId); 627bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 628bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 629bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Performs the back action. 630bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 631bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param isSystemBackKey <code>true</code> if the system back key was pressed. 632bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>false</code> if it's caused by the "home" icon click on the action bar. 633bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 634bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public abstract boolean onBackPressed(boolean isSystemBackKey); 635bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 636bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onSearchStarted() { 637bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Show/hide the original search icon. 638bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity.invalidateOptionsMenu(); 639bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 640bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 641bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 642bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Must be called from {@link Activity#onSearchRequested()}. 643bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This initiates the search entry mode - see {@link #onSearchSubmit} for when the search 644bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * is actually submitted. 645bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 646bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onSearchRequested() { 647bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook long accountId = getActualAccountId(); 648bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean accountSearchable = false; 649bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (accountId > 0) { 650bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Account account = Account.restoreAccountWithId(mActivity, accountId); 651bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (account != null) { 652bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook String protocol = account.getProtocol(mActivity); 653bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook accountSearchable = (account.mFlags & Account.FLAGS_SUPPORTS_SEARCH) != 0; 654bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 655bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 656bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 657bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!accountSearchable) { 658bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return; 659bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 660bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 661bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (isMessageListReady()) { 662bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActionBarController.enterSearchMode(null); 663bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 664bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 665bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 666bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 667bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return Whether or not a message list is ready and has its initial meta data loaded. 668bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 669bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected boolean isMessageListReady() { 670bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return isMessageListInstalled() && getMessageListFragment().hasDataLoaded(); 671bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 672bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 673bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 674bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Determines the mailbox to search, if a search was to be initiated now. 675bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This will return {@code null} if the UI is not focused on any particular mailbox to search 676bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * on. 677bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 678bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private Mailbox getSearchableMailbox() { 679bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!isMessageListReady()) { 680bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return null; 681bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 682bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MessageListFragment messageList = getMessageListFragment(); 683bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 684bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // If already in a search, future searches will search the original mailbox. 685bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mListContext.isSearch() 686bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ? messageList.getSearchedMailbox() 687bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook : messageList.getMailbox(); 688bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 689bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 690bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // TODO: this logic probably needs to be tested in the backends as well, so it may be nice 691bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // to consolidate this to a centralized place, so that they don't get out of sync. 692bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 693bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return whether or not this account should do a global search instead when a user 694bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * initiates a search on the given mailbox. 695bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 696bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private static boolean shouldDoGlobalSearch(Account account, Mailbox mailbox) { 697bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return ((account.mFlags & Account.FLAGS_SUPPORTS_GLOBAL_SEARCH) != 0) 698bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook && (mailbox.mType == Mailbox.TYPE_INBOX); 699bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 700bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 701bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 702bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Retrieves the hint text to be shown for when a search entry is being made. 703bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 704bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected String getSearchHint() { 705bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!isMessageListReady()) { 706bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return ""; 707bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 708bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Account account = getMessageListFragment().getAccount(); 709bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Mailbox mailbox = getSearchableMailbox(); 710bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 711bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mailbox == null) { 712bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return ""; 713bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 714bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 715bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (shouldDoGlobalSearch(account, mailbox)) { 716bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mActivity.getString(R.string.search_hint); 717bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 718bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 719bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Regular mailbox, or IMAP - search within that mailbox. 720bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook String mailboxName = FolderProperties.getInstance(mActivity).getDisplayName(mailbox); 721bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return String.format( 722bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity.getString(R.string.search_mailbox_hint), 723bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mailboxName); 724bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 725bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 726bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 727bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Kicks off a search query, if the UI is in a state where a search is possible. 728bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 729bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void onSearchSubmit(final String queryTerm) { 730bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final long accountId = getUIAccountId(); 731bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!Account.isNormalAccount(accountId)) { 732bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return; // Invalid account to search from. 733bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 734bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 735bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Mailbox searchableMailbox = getSearchableMailbox(); 736bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (searchableMailbox == null) { 737bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return; 738bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 739bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final long mailboxId = searchableMailbox.mId; 740bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 741bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Email.DEBUG) { 742bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, 743bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook "Submitting search: [" + queryTerm + "] in mailboxId=" + mailboxId); 744bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 745bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 746bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity.startActivity(EmailActivity.createSearchIntent( 747bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity, accountId, mailboxId, queryTerm)); 748bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 749bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 750bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // TODO: this causes a slight flicker. 751bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // A new instance of the activity will sit on top. When the user exits search and 752bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // returns to this activity, the search box should not be open then. 753bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActionBarController.exitSearchMode(); 754bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 755bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 756bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 757bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles exiting of search entry mode. 758bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 759bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void onSearchExit() { 760bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if ((mListContext != null) && mListContext.isSearch()) { 761bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity.finish(); 762bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 763bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Re show the search icon. 764bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity.invalidateOptionsMenu(); 765bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 766bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 767bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 768bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 769bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the {@link android.app.Activity#onCreateOptionsMenu} callback. 770bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 771bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public boolean onCreateOptionsMenu(MenuInflater inflater, Menu menu) { 772bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook inflater.inflate(R.menu.email_activity_options, menu); 773bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return true; 774bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 775bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 776bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 777bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the {@link android.app.Activity#onPrepareOptionsMenu} callback. 778bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 779bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public boolean onPrepareOptionsMenu(MenuInflater inflater, Menu menu) { 780bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Update the refresh button. 781bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MenuItem item = menu.findItem(R.id.refresh); 782bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (item != null) { 783bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (isRefreshEnabled()) { 784bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook item.setVisible(true); 785bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mRefreshListener.setRefreshIcon(item); 786bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 787bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook item.setVisible(false); 788bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mRefreshListener.setRefreshIcon(null); 789bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 790bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 791bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 792bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Deal with protocol-specific menu options. 793bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean mailboxHasServerCounterpart = false; 794bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean accountSearchable = false; 795bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean isEas = false; 796bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 797bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (isMessageListReady()) { 798bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook long accountId = getActualAccountId(); 799bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (accountId > 0) { 800bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Account account = Account.restoreAccountWithId(mActivity, accountId); 801bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (account != null) { 802bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook String protocol = account.getProtocol(mActivity); 803bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook isEas = HostAuth.SCHEME_EAS.equals(protocol); 804bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Mailbox mailbox = getMessageListFragment().getMailbox(); 805bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mailboxHasServerCounterpart = (mailbox != null) 806bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook && mailbox.loadsFromServer(protocol); 807bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook accountSearchable = (account.mFlags & Account.FLAGS_SUPPORTS_SEARCH) != 0; 808bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 809bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 810bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 811bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 812bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook boolean showSearchIcon = !mActionBarController.isInSearchMode() 813bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook && accountSearchable && mailboxHasServerCounterpart; 814bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 815bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MenuItem search = menu.findItem(R.id.search); 816bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (search != null) { 817bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook search.setVisible(showSearchIcon); 818bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 819bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MenuItem settings = menu.findItem(R.id.mailbox_settings); 820bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (settings != null) { 821bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook settings.setVisible(isEas && mailboxHasServerCounterpart); 822bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 823bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return true; 824bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 825bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 826bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 827bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the {@link android.app.Activity#onOptionsItemSelected} callback. 828bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 829bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return true if the option item is handled. 830bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 831bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public boolean onOptionsItemSelected(MenuItem item) { 832bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook switch (item.getItemId()) { 833bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook case android.R.id.home: 834bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Comes from the action bar when the app icon on the left is pressed. 835bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // It works like a back press, but it won't close the activity. 836bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return onBackPressed(false); 837bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook case R.id.compose: 838bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return onCompose(); 839bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook case R.id.refresh: 840bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook onRefresh(); 841bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return true; 842bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook case R.id.account_settings: 843bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return onAccountSettings(); 844bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook case R.id.search: 845bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook onSearchRequested(); 846bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return true; 847bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook case R.id.mailbox_settings: 848bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final long mailboxId = getMailboxSettingsMailboxId(); 849bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mailboxId != Mailbox.NO_MAILBOX) { 850bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MailboxSettings.start(mActivity, mailboxId); 851bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 852bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return true; 853bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 854bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return false; 855bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 856bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 857bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 858bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Opens the message compose activity. 859bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 860bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private boolean onCompose() { 861bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!isAccountSelected()) { 862bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return false; // this shouldn't really happen 863bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 864bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook MessageCompose.actionCompose(mActivity, getActualAccountId()); 865bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return true; 866bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 867bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 868bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 869bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handles the "Settings" option item. Opens the settings activity. 870bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 871bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private boolean onAccountSettings() { 872bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook AccountSettings.actionSettings(mActivity, getActualAccountId()); 873bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return true; 874bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 875bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 876bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 877bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return the ID of the message in focus and visible, if any. Returns 878bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link Message#NO_MESSAGE} if no message is opened. 879bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 880bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected long getMessageId() { 881bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return isMessageViewInstalled() 882bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ? getMessageViewFragment().getMessageId() 883bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook : Message.NO_MESSAGE; 884bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 885bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 886bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 887bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 888bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return mailbox ID for "mailbox settings" option. 889bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 890bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected abstract long getMailboxSettingsMailboxId(); 891bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 892bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 893bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Performs "refesh". 894bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 895bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected abstract void onRefresh(); 896bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 897bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 898bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return true if refresh is in progress for the current mailbox. 899bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 900bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected abstract boolean isRefreshInProgress(); 901bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 902bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 903bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return true if the UI should enable the "refresh" command. 904bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 905bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected abstract boolean isRefreshEnabled(); 906bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 907bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 908bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Refresh the action bar and menu items, including the "refreshing" icon. 909bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 910bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void refreshActionBar() { 911bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mActionBarController != null) { 912bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActionBarController.refresh(); 913bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 914bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity.invalidateOptionsMenu(); 915bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 916bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 917bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // MessageListFragment.Callback 918bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 919bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onMailboxNotFound(boolean isFirstLoad) { 920bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Something bad happened - the account or mailbox we were looking for was deleted. 921bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Just restart and let the entry flow find a good default view. 922bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (isFirstLoad) { 923bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Only show this if it's the first load (e.g. a shortcut) rather an a return to 924bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // a mailbox (which might be in a just-deleted account) 925bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Utility.showToast(mActivity, R.string.toast_mailbox_not_found); 926bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 927bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook long accountId = getUIAccountId(); 928bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (accountId != Account.NO_ACCOUNT) { 929bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity.startActivity(Welcome.createOpenAccountInboxIntent(mActivity, accountId)); 930bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 931bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Welcome.actionStart(mActivity); 932bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 933bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 934bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity.finish(); 935bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 936bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 937bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final MessageOrderManager getMessageOrderManager() { 938bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return mOrderManager; 939bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 940bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 941bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** Perform "auto-advance. */ 942bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final void doAutoAdvance() { 943bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook switch (Preferences.getPreferences(mActivity).getAutoAdvanceDirection()) { 944bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook case Preferences.AUTO_ADVANCE_NEWER: 945bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (moveToNewer()) return; 946bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook break; 947bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook case Preferences.AUTO_ADVANCE_OLDER: 948bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (moveToOlder()) return; 949bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook break; 950bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 951bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (isMessageViewInstalled()) { // We really should have the message view but just in case 952bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Go back to mailbox list. 953bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Use onBackPressed(), so we'll restore the message view state, such as scroll 954bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // position. 955bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Also make sure to pass false to isSystemBackKey, so on two-pane we don't go back 956bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // to the collapsed mode. 957bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook onBackPressed(true); 958bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 959bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 960bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 961bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 962bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Subclass must implement it to enable/disable the newer/older buttons. 963bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 964bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected abstract void updateNavigationArrows(); 965bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 966bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final boolean moveToOlder() { 967bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if ((mOrderManager != null) && mOrderManager.moveToOlder()) { 968bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook navigateToMessage(mOrderManager.getCurrentMessageId()); 969bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return true; 970bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 971bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return false; 972bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 973bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 974bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final boolean moveToNewer() { 975bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if ((mOrderManager != null) && mOrderManager.moveToNewer()) { 976bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook navigateToMessage(mOrderManager.getCurrentMessageId()); 977bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return true; 978bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 979bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return false; 980bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 981bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 982bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 983bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Called when the user taps newer/older. Subclass must implement it to open the specified 984bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * message. 985bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 986bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * It's a bit different from just showing the message view fragment; on one-pane we show the 987bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * message view fragment but don't want to change back state. 988bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 989bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected abstract void navigateToMessage(long messageId); 990bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 991bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 992bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Potentially create a new {@link MessageOrderManager}; if it's not already started or if 993bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the account has changed, and sync it to the current message. 994bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 995bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private void updateMessageOrderManager() { 996bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!isMessageViewInstalled()) { 997bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return; 998bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 999bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Preconditions.checkNotNull(mListContext); 1000bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 1001bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mOrderManager == null || !mOrderManager.getListContext().equals(mListContext)) { 1002bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook stopMessageOrderManager(); 1003bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mOrderManager = new MessageOrderManager( 1004bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mActivity, mListContext, mMessageOrderManagerCallback); 1005bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1006bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mOrderManager.moveTo(getMessageId()); 1007bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook updateNavigationArrows(); 1008bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1009bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 1010bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 1011bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Stop {@link MessageOrderManager}. 1012bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 1013bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected final void stopMessageOrderManager() { 1014bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mOrderManager != null) { 1015bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mOrderManager.close(); 1016bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mOrderManager = null; 1017bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1018bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1019bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 1020bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private class MessageOrderManagerCallback implements MessageOrderManager.Callback { 1021bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 1022bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onMessagesChanged() { 1023bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook updateNavigationArrows(); 1024bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1025bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 1026bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 1027bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onMessageNotFound() { 1028bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook doAutoAdvance(); 1029bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1030bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1031bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 1032bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 1033bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private void showAccountSpecificWarning(long accountId) { 1034bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (accountId != Account.NO_ACCOUNT && accountId != Account.NO_ACCOUNT) { 1035bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Account account = Account.restoreAccountWithId(mActivity, accountId); 1036bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (account != null && 1037bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Preferences.getPreferences(mActivity) 1038bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook .shouldShowRequireManualSync(mActivity, account)) { 1039bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook new RequireManualSyncDialog(mActivity, account).show(); 1040bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1041bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1042bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1043bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 1044bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 1045bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public String toString() { 1046bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return getClass().getSimpleName(); // Shown on logcat 1047bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 1048bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook} 1049