replicant-packages_apps_Email/src/com/android/email/activity/UIControllerTwoPane.java

1064 lines
34 KiB
Java

/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.email.activity;
import com.android.email.Clock;
import com.android.email.Email;
import com.android.email.Preferences;
import com.android.email.R;
import com.android.email.RefreshManager;
import com.android.email.activity.setup.AccountSecurity;
import com.android.emailcommon.Logging;
import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.utility.EmailAsyncTask;
import com.google.common.annotations.VisibleForTesting;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import java.util.Set;
/**
* UI Controller for x-large devices. Supports a multi-pane layout.
*/
class UIControllerTwoPane extends UIControllerBase implements
MailboxFinder.Callback,
ThreePaneLayout.Callback,
MailboxListFragment.Callback,
MessageListFragment.Callback,
MessageViewFragment.Callback {
@VisibleForTesting
static final int MAILBOX_REFRESH_MIN_INTERVAL = 30 * 1000; // in milliseconds
@VisibleForTesting
static final int INBOX_AUTO_REFRESH_MIN_INTERVAL = 10 * 1000; // in milliseconds
private ActionBarController mActionBarController;
private final ActionBarControllerCallback mActionBarControllerCallback =
new ActionBarControllerCallback();
// Other UI elements
private ThreePaneLayout mThreePane;
/**
* Fragments that are installed.
*
* A fragment is installed when:
* - it is attached to the activity
* - the parent activity is created
* - and it is not scheduled to be removed.
*
* We set callbacks to fragments only when they are installed.
*/
private MailboxListFragment mMailboxListFragment;
private MessageListFragment mMessageListFragment;
private MessageViewFragment mMessageViewFragment;
private MessageCommandButtonView mMessageCommandButtons;
private MailboxFinder mMailboxFinder;
private MessageOrderManager mOrderManager;
private final MessageOrderManagerCallback mMessageOrderManagerCallback =
new MessageOrderManagerCallback();
/**
* The mailbox name selected on the mailbox list.
* Passed via {@link #onCurrentMailboxUpdated}.
*/
private String mCurrentMailboxName;
/**
* The unread count for the mailbox selected on the mailbox list.
* Passed via {@link #onCurrentMailboxUpdated}.
*
* 0 if the mailbox doesn't have the concept of "unread". e.g. Drafts.
*/
private int mCurrentMailboxUnreadCount;
public UIControllerTwoPane(EmailActivity activity) {
super(activity);
}
private void refreshActionBar() {
if (mActionBarController != null) {
mActionBarController.refresh();
}
}
@Override
public int getLayoutId() {
return R.layout.email_activity_two_pane;
}
// MailboxFinder$Callback
@Override
public void onAccountNotFound() {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, this + " onAccountNotFound()");
}
// Shouldn't happen
}
// MailboxFinder$Callback
@Override
public void onAccountSecurityHold(long accountId) {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, this + " onAccountSecurityHold()");
}
mActivity.startActivity(AccountSecurity.actionUpdateSecurityIntent(mActivity, accountId,
true));
}
// MailboxFinder$Callback
@Override
public void onMailboxFound(long accountId, long mailboxId) {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, this + " onMailboxFound()");
}
updateMessageList(accountId, mailboxId, true);
}
// MailboxFinder$Callback
@Override
public void onMailboxNotFound(long accountId) {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, this + " onMailboxNotFound()");
}
Log.e(Logging.LOG_TAG, "unable to find mailbox for account " + accountId);
}
// ThreePaneLayoutCallback
@Override
public void onVisiblePanesChanged(int previousVisiblePanes) {
refreshActionBar();
// If the right pane is gone, remove the message view.
final int visiblePanes = mThreePane.getVisiblePanes();
if (((visiblePanes & ThreePaneLayout.PANE_RIGHT) == 0) &&
((previousVisiblePanes & ThreePaneLayout.PANE_RIGHT) != 0)) {
// Message view just got hidden
unselectMessage();
}
// Disable CAB when the message list is not visible.
if (isMessageListInstalled()) {
mMessageListFragment.onHidden((visiblePanes & ThreePaneLayout.PANE_MIDDLE) == 0);
}
}
// MailboxListFragment$Callback
@Override
public void onMailboxSelected(long accountId, long mailboxId, boolean navigate) {
if ((accountId == Account.NO_ACCOUNT) || (mailboxId == Mailbox.NO_MAILBOX)) {
throw new IllegalArgumentException(); // Shouldn't happen.
}
if (navigate) {
if (mailboxId != getMailboxListMailboxId()) {
// Don't navigate to the same mailbox id twice in a row
openMailbox(accountId, mailboxId);
}
} else {
// Regular case -- just open the mailbox on the message list.
updateMessageList(accountId, mailboxId, true);
}
}
public void onMailboxSelectedForDnD(long mailboxId) {
// STOPSHIP the new mailbox list created here doesn't know D&D is in progress. b/4332725
updateMailboxList(getUIAccountId(), mailboxId,
false /* don't clear message list and message view */);
}
// MailboxListFragment$Callback
@Override
public void onAccountSelected(long accountId) {
switchAccount(accountId);
}
// MailboxListFragment$Callback
@Override
public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, int unreadCount) {
mCurrentMailboxName = mailboxName;
mCurrentMailboxUnreadCount = unreadCount;
refreshActionBar();
}
// MessageListFragment$Callback
@Override
public void onMessageOpen(long messageId, long messageMailboxId, long listMailboxId,
int type) {
if (type == MessageListFragment.Callback.TYPE_DRAFT) {
MessageCompose.actionEditDraft(mActivity, messageId);
} else {
updateMessageView(messageId);
mThreePane.showRightPane();
}
}
// MessageListFragment$Callback
@Override
public void onMailboxNotFound() {
Log.e(Logging.LOG_TAG, "unable to find mailbox");
}
// MessageListFragment$Callback
@Override
public void onEnterSelectionMode(boolean enter) {
}
// MessageListFragment$Callback
/**
* Apply the auto-advance policy upon initation of a batch command that could potentially
* affect the currently selected conversation.
*/
@Override
public void onAdvancingOpAccepted(Set<Long> affectedMessages) {
if (!isMessageViewInstalled()) {
// Do nothing if message view is not visible.
return;
}
int autoAdvanceDir = Preferences.getPreferences(mActivity).getAutoAdvanceDirection();
if ((autoAdvanceDir == Preferences.AUTO_ADVANCE_MESSAGE_LIST) || (mOrderManager == null)) {
if (affectedMessages.contains(getMessageId())) {
goBackToMailbox();
}
return;
}
// Navigate to the first unselected item in the appropriate direction.
switch (autoAdvanceDir) {
case Preferences.AUTO_ADVANCE_NEWER:
while (affectedMessages.contains(mOrderManager.getCurrentMessageId())) {
if (!mOrderManager.moveToNewer()) {
goBackToMailbox();
return;
}
}
updateMessageView(mOrderManager.getCurrentMessageId());
break;
case Preferences.AUTO_ADVANCE_OLDER:
while (affectedMessages.contains(mOrderManager.getCurrentMessageId())) {
if (!mOrderManager.moveToOlder()) {
goBackToMailbox();
return;
}
}
updateMessageView(mOrderManager.getCurrentMessageId());
break;
}
}
// MessageListFragment$Callback
@Override
public void onListLoaded() {
}
// MessageListFragment$Callback
@Override
public boolean onDragStarted() {
Log.w(Logging.LOG_TAG, "Drag started");
if ((mThreePane.getVisiblePanes() & ThreePaneLayout.PANE_LEFT) == 0) {
// Mailbox list hidden. D&D not allowed.
return false;
}
// STOPSHIP Save the current mailbox list
return true;
}
// MessageListFragment$Callback
@Override
public void onDragEnded() {
Log.w(Logging.LOG_TAG, "Drag ended");
// STOPSHIP Restore the saved mailbox list
}
// MessageViewFragment$Callback
@Override
public void onMessageViewShown(int mailboxType) {
updateMessageOrderManager();
updateNavigationArrows();
}
// MessageViewFragment$Callback
@Override
public void onMessageViewGone() {
stopMessageOrderManager();
}
// MessageViewFragment$Callback
@Override
public boolean onUrlInMessageClicked(String url) {
return ActivityHelper.openUrlInMessage(mActivity, url, getActualAccountId());
}
// MessageViewFragment$Callback
@Override
public void onMessageSetUnread() {
goBackToMailbox();
}
// MessageViewFragment$Callback
@Override
public void onMessageNotExists() {
goBackToMailbox();
}
// MessageViewFragment$Callback
@Override
public void onLoadMessageStarted() {
}
// MessageViewFragment$Callback
@Override
public void onLoadMessageFinished() {
}
// MessageViewFragment$Callback
@Override
public void onLoadMessageError(String errorMessage) {
}
// MessageViewFragment$Callback
@Override
public void onRespondedToInvite(int response) {
onCurrentMessageGone();
}
// MessageViewFragment$Callback
@Override
public void onCalendarLinkClicked(long epochEventStartTime) {
ActivityHelper.openCalendar(mActivity, epochEventStartTime);
}
// MessageViewFragment$Callback
@Override
public void onBeforeMessageGone() {
onCurrentMessageGone();
}
// MessageViewFragment$Callback
@Override
public void onForward() {
MessageCompose.actionForward(mActivity, getMessageId());
}
// MessageViewFragment$Callback
@Override
public void onReply() {
MessageCompose.actionReply(mActivity, getMessageId(), false);
}
// MessageViewFragment$Callback
@Override
public void onReplyAll() {
MessageCompose.actionReply(mActivity, getMessageId(), true);
}
/**
* Must be called just after the activity sets up the content view.
*/
@Override
public void onActivityViewReady() {
super.onActivityViewReady();
mActionBarController = new ActionBarController(mActivity, mActivity.getLoaderManager(),
mActivity.getActionBar(), mActionBarControllerCallback);
// Set up content
mThreePane = (ThreePaneLayout) mActivity.findViewById(R.id.three_pane);
mThreePane.setCallback(this);
mMessageCommandButtons = mThreePane.getMessageCommandButtons();
mMessageCommandButtons.setCallback(new CommandButtonCallback());
}
/**
* @return the currently selected account ID, *or* {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
*
* @see #getActualAccountId()
*/
@Override
public long getUIAccountId() {
return isMailboxListInstalled() ? mMailboxListFragment.getAccountId()
:Account.NO_ACCOUNT;
}
/**
* Returns the id of the parent mailbox used for the mailbox list fragment.
*
* IMPORTANT: Do not confuse {@link #getMailboxListMailboxId()} with
* {@link #getMessageListMailboxId()}
*/
private long getMailboxListMailboxId() {
return isMailboxListInstalled() ? mMailboxListFragment.getParentMailboxId()
: Mailbox.NO_MAILBOX;
}
/**
* Returns the id of the mailbox used for the message list fragment.
*
* IMPORTANT: Do not confuse {@link #getMailboxListMailboxId()} with
* {@link #getMessageListMailboxId()}
*/
private long getMessageListMailboxId() {
return isMessageListInstalled() ? mMessageListFragment.getMailboxId()
: Message.NO_MESSAGE;
}
/*
* STOPSHIP Remove this -- see the base class method.
*/
@Override
public long getMailboxSettingsMailboxId() {
return getMessageListMailboxId();
}
/*
* STOPSHIP Remove this -- see the base class method.
*/
@Override
public long getSearchMailboxId() {
return getMessageListMailboxId();
}
private long getMessageId() {
return isMessageViewInstalled() ? mMessageViewFragment.getMessageId()
: Message.NO_MESSAGE;
}
private boolean isMailboxListInstalled() {
return mMailboxListFragment != null;
}
private boolean isMessageListInstalled() {
return mMessageListFragment != null;
}
private boolean isMessageViewInstalled() {
return mMessageViewFragment != null;
}
/**
* @return true if refresh is in progress for the current mailbox.
*/
@Override
protected boolean isRefreshInProgress() {
long messageListMailboxId = getMessageListMailboxId();
return (messageListMailboxId >= 0)
&& mRefreshManager.isMessageListRefreshing(messageListMailboxId);
}
/**
* @return true if the UI should enable the "refresh" command.
*/
@Override
protected boolean isRefreshEnabled() {
// - Don't show for combined inboxes, but
// - Show even for non-refreshable mailboxes, in which case we refresh the mailbox list
return getActualAccountId() != Account.NO_ACCOUNT;
}
/**
* Called by the host activity at the end of {@link Activity#onCreate}.
*/
@Override
public void onActivityCreated() {
super.onActivityCreated();
mActionBarController.onActivityCreated();
}
/** {@inheritDoc} */
@Override
public void onActivityStart() {
super.onActivityStart();
if (isMessageViewInstalled()) {
updateMessageOrderManager();
}
}
/** {@inheritDoc} */
@Override
public void onActivityResume() {
super.onActivityResume();
refreshActionBar();
}
/** {@inheritDoc} */
@Override
public void onActivityPause() {
super.onActivityPause();
}
/** {@inheritDoc} */
@Override
public void onActivityStop() {
stopMessageOrderManager();
super.onActivityStop();
}
/** {@inheritDoc} */
@Override
public void onActivityDestroy() {
closeMailboxFinder();
super.onActivityDestroy();
}
/** {@inheritDoc} */
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// STOPSHIP If MailboxFinder is still running, it needs restarting after loadState().
}
/** {@inheritDoc} */
@Override
public void restoreInstanceState(Bundle savedInstanceState) {
super.restoreInstanceState(savedInstanceState);
// STOPSHIP If MailboxFinder is still running, it needs restarting after loadState().
}
@Override
protected void installMailboxListFragment(MailboxListFragment fragment) {
mMailboxListFragment = fragment;
mMailboxListFragment.setCallback(this);
}
@Override
protected void installMessageListFragment(MessageListFragment fragment) {
mMessageListFragment = fragment;
mMessageListFragment.setCallback(this);
}
@Override
protected void installMessageViewFragment(MessageViewFragment fragment) {
mMessageViewFragment = fragment;
mMessageViewFragment.setCallback(this);
}
private FragmentTransaction uninstallMailboxListFragment(FragmentTransaction ft) {
if (isMailboxListInstalled()) {
ft.remove(mMailboxListFragment);
mMailboxListFragment.setCallback(null);
mMailboxListFragment = null;
}
return ft;
}
private FragmentTransaction uninstallMessageListFragment(FragmentTransaction ft) {
if (isMessageListInstalled()) {
ft.remove(mMessageListFragment);
mMessageListFragment.setCallback(null);
mMessageListFragment = null;
}
return ft;
}
private FragmentTransaction uninstallMessageViewFragment(FragmentTransaction ft) {
if (isMessageViewInstalled()) {
ft.remove(mMessageViewFragment);
mMessageViewFragment.setCallback(null);
mMessageViewFragment = null;
}
return ft;
}
/**
* {@inheritDoc}
*/
@Override
public void open(long accountId, long mailboxId, long messageId) {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, this + " open accountId=" + accountId
+ " mailboxId=" + mailboxId + " messageId=" + messageId);
}
if (accountId == Account.NO_ACCOUNT) {
throw new IllegalArgumentException();
} else if (mailboxId == Mailbox.NO_MAILBOX) {
updateMailboxList(accountId, Mailbox.NO_MAILBOX, true);
// Show the appropriate message list
if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) {
// When opening the Combined view, the right pane will be "combined inbox".
updateMessageList(accountId, Mailbox.QUERY_ALL_INBOXES, true);
} else {
// Try to find the inbox for the account
closeMailboxFinder();
mMailboxFinder = new MailboxFinder(mActivity, accountId, Mailbox.TYPE_INBOX, this);
mMailboxFinder.startLookup();
}
mThreePane.showLeftPane();
} else if (messageId == Message.NO_MESSAGE) {
// STOPSHIP Use the appropriate parent mailbox ID
updateMailboxList(accountId, mailboxId, true);
updateMessageList(accountId, mailboxId, true);
mThreePane.showLeftPane();
} else {
// STOPSHIP Use the appropriate parent mailbox ID
updateMailboxList(accountId, mailboxId, true);
updateMessageList(accountId, mailboxId, true);
updateMessageView(messageId);
mThreePane.showRightPane();
}
}
/**
* Pre-fragment transaction check.
*
* @throw IllegalStateException if updateXxx methods can't be called in the current state.
*/
private void preFragmentTransactionCheck() {
if (!isFragmentInstallable()) {
// Code assumes mMailboxListFragment/etc are set right within the
// commitFragmentTransaction() call (because we use synchronous transaction),
// so updateXxx() can't be called if fragments are not installable yet.
throw new IllegalStateException();
}
}
/**
* Loads the given account and optionally selects the given mailbox and message. If the
* specified account is already selected, no actions will be performed unless
* <code>forceReload</code> is <code>true</code>.
*
* @param accountId ID of the account to load. Must never be {@link Account#NO_ACCOUNT}.
* @param parentMailboxId ID of the mailbox to use as the parent mailbox. Pass
* {@link Mailbox#NO_MAILBOX} to show the root mailboxes.
* @param clearDependentPane if true, the message list and the message view will be cleared
*/
private void updateMailboxList(long accountId, long parentMailboxId,
boolean clearDependentPane) {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, this + " updateMailboxList accountId=" + accountId
+ " parentMailboxId=" + parentMailboxId);
}
preFragmentTransactionCheck();
if (accountId == Account.NO_ACCOUNT) {
throw new IllegalArgumentException();
}
final FragmentManager fm = mActivity.getFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
if ((getUIAccountId() != accountId)
|| (getMailboxListMailboxId() != parentMailboxId)) {
uninstallMailboxListFragment(ft);
ft.add(mThreePane.getLeftPaneId(),
MailboxListFragment.newInstance(accountId, parentMailboxId));
}
if (clearDependentPane) {
uninstallMessageListFragment(ft);
uninstallMessageViewFragment(ft);
}
commitFragmentTransaction(ft);
// Update action bar / menu
updateRefreshProgress();
refreshActionBar();
}
/**
* Go back to a mailbox list view. If a message view is currently active, it will
* be hidden.
*/
private void goBackToMailbox() {
if (isMessageViewInstalled()) {
mThreePane.showLeftPane(); // Show mailbox list
}
}
/**
* Show the message list fragment for the given mailbox.
*
* @param accountId ID of the owner account for the mailbox. Must never be
* {@link Account#NO_ACCOUNT}.
* @param mailboxId ID of the mailbox to load. Must never be {@link Mailbox#NO_MAILBOX}.
* @param clearDependentPane if true, the message view will be cleared
*
* STOPSHIP Need to stop mailbox finder if it's still running
*/
private void updateMessageList(long accountId, long mailboxId, boolean clearDependentPane) {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, this + " updateMessageList mMailboxId=" + mailboxId);
}
preFragmentTransactionCheck();
if (mailboxId == Mailbox.NO_MAILBOX) {
throw new IllegalArgumentException();
}
final FragmentManager fm = mActivity.getFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
if (mailboxId != getMessageListMailboxId()) {
uninstallMessageListFragment(ft);
ft.add(mThreePane.getMiddlePaneId(), MessageListFragment.newInstance(
accountId, mailboxId));
}
if (clearDependentPane) {
uninstallMessageViewFragment(ft);
}
commitFragmentTransaction(ft);
mMailboxListFragment.setSelectedMailbox(mailboxId);
// Update action bar / menu
updateRefreshProgress();
refreshActionBar();
}
/**
* Show a message on the message view.
*
* @param messageId ID of the mailbox to load. Must never be {@link Message#NO_MESSAGE}.
*/
private void updateMessageView(long messageId) {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, this + " updateMessageView messageId=" + messageId);
}
preFragmentTransactionCheck();
if (messageId == Message.NO_MESSAGE) {
throw new IllegalArgumentException();
}
if (messageId == getMessageId()) {
return; // nothing to do.
}
// Open message
final FragmentManager fm = mActivity.getFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
uninstallMessageViewFragment(ft);
ft.add(mThreePane.getRightPaneId(), MessageViewFragment.newInstance(messageId));
commitFragmentTransaction(ft);
mMessageListFragment.setSelectedMessage(messageId);
}
/**
* Remove the message view if shown.
*/
private void unselectMessage() {
commitFragmentTransaction(uninstallMessageViewFragment(
mActivity.getFragmentManager().beginTransaction()));
if (mMessageListFragment != null) {
mMessageListFragment.setSelectedMessage(Message.NO_MESSAGE);
}
}
private void closeMailboxFinder() {
if (mMailboxFinder != null) {
mMailboxFinder.cancel();
mMailboxFinder = null;
}
}
private class CommandButtonCallback implements MessageCommandButtonView.Callback {
@Override
public void onMoveToNewer() {
moveToNewer();
}
@Override
public void onMoveToOlder() {
moveToOlder();
}
}
private void onCurrentMessageGone() {
switch (Preferences.getPreferences(mActivity).getAutoAdvanceDirection()) {
case Preferences.AUTO_ADVANCE_NEWER:
if (moveToNewer()) return;
break;
case Preferences.AUTO_ADVANCE_OLDER:
if (moveToOlder()) return;
break;
}
// Last message in the box or AUTO_ADVANCE_MESSAGE_LIST. Go back to message list.
goBackToMailbox();
}
/**
* Potentially create a new {@link MessageOrderManager}; if it's not already started or if
* the account has changed, and sync it to the current message.
*/
private void updateMessageOrderManager() {
if (!isMessageViewInstalled()) {
return;
}
final long mailboxId = getMessageListMailboxId();
if (mOrderManager == null || mOrderManager.getMailboxId() != mailboxId) {
stopMessageOrderManager();
mOrderManager =
new MessageOrderManager(mActivity, mailboxId, mMessageOrderManagerCallback);
}
mOrderManager.moveTo(getMessageId());
}
private class MessageOrderManagerCallback implements MessageOrderManager.Callback {
@Override
public void onMessagesChanged() {
updateNavigationArrows();
}
@Override
public void onMessageNotFound() {
// Current message gone.
goBackToMailbox();
}
}
/**
* Stop {@link MessageOrderManager}.
*/
private void stopMessageOrderManager() {
if (mOrderManager != null) {
mOrderManager.close();
mOrderManager = null;
}
}
/**
* Disable/enable the move-to-newer/older buttons.
*/
private void updateNavigationArrows() {
if (mOrderManager == null) {
// shouldn't happen, but just in case
mMessageCommandButtons.enableNavigationButtons(false, false, 0, 0);
} else {
mMessageCommandButtons.enableNavigationButtons(
mOrderManager.canMoveToNewer(), mOrderManager.canMoveToOlder(),
mOrderManager.getCurrentPosition(), mOrderManager.getTotalMessageCount());
}
}
private boolean moveToOlder() {
if ((mOrderManager != null) && mOrderManager.moveToOlder()) {
updateMessageView(mOrderManager.getCurrentMessageId());
return true;
}
return false;
}
private boolean moveToNewer() {
if ((mOrderManager != null) && mOrderManager.moveToNewer()) {
updateMessageView(mOrderManager.getCurrentMessageId());
return true;
}
return false;
}
/** {@inheritDoc} */
@Override
public boolean onBackPressed(boolean isSystemBackKey) {
if (mThreePane.onBackPressed(isSystemBackKey)) {
return true;
} else if (navigateToParentMailboxList()) {
return true;
}
return false;
}
private boolean navigateToParentMailboxList() {
if (!isMailboxListInstalled() || mMailboxListFragment.isRoot()) {
return false;
}
super.navigateToParentMailboxList(mMailboxListFragment.getParentMailboxId());
return true;
}
/**
* Handles the "refresh" option item. Opens the settings activity.
* TODO used by experimental code in the activity -- otherwise can be private.
*/
@Override
public void onRefresh() {
// Cancel previously running instance if any.
new RefreshTask(mTaskTracker, mActivity, getActualAccountId(),
getMessageListMailboxId()).cancelPreviousAndExecuteParallel();
}
/**
* Class to handle refresh.
*
* When the user press "refresh",
* <ul>
* <li>Refresh the current mailbox, if it's refreshable. (e.g. don't refresh combined inbox,
* drafts, etc.
* <li>Refresh the mailbox list, if it hasn't been refreshed in the last
* {@link #MAILBOX_REFRESH_MIN_INTERVAL}.
* <li>Refresh inbox, if it's not the current mailbox and it hasn't been refreshed in the last
* {@link #INBOX_AUTO_REFRESH_MIN_INTERVAL}.
* </ul>
*/
@VisibleForTesting
static class RefreshTask extends EmailAsyncTask<Void, Void, Boolean> {
private final Clock mClock;
private final Context mContext;
private final long mAccountId;
private final long mMailboxId;
private final RefreshManager mRefreshManager;
@VisibleForTesting
long mInboxId;
public RefreshTask(EmailAsyncTask.Tracker tracker, Context context, long accountId,
long mailboxId) {
this(tracker, context, accountId, mailboxId, Clock.INSTANCE,
RefreshManager.getInstance(context));
}
@VisibleForTesting
RefreshTask(EmailAsyncTask.Tracker tracker, Context context, long accountId,
long mailboxId, Clock clock, RefreshManager refreshManager) {
super(tracker);
mClock = clock;
mContext = context;
mRefreshManager = refreshManager;
mAccountId = accountId;
mMailboxId = mailboxId;
}
/**
* Do DB access on a worker thread.
*/
@Override
protected Boolean doInBackground(Void... params) {
mInboxId = Account.getInboxId(mContext, mAccountId);
return Mailbox.isRefreshable(mContext, mMailboxId);
}
/**
* Do the actual refresh.
*/
@Override
protected void onPostExecute(Boolean isCurrentMailboxRefreshable) {
if (isCancelled() || isCurrentMailboxRefreshable == null) {
return;
}
if (isCurrentMailboxRefreshable) {
mRefreshManager.refreshMessageList(mAccountId, mMailboxId, false);
}
// Refresh mailbox list
if (mAccountId != Account.NO_ACCOUNT) {
if (shouldRefreshMailboxList()) {
mRefreshManager.refreshMailboxList(mAccountId);
}
}
// Refresh inbox
if (shouldAutoRefreshInbox()) {
mRefreshManager.refreshMessageList(mAccountId, mInboxId, false);
}
}
/**
* @return true if the mailbox list of the current account hasn't been refreshed
* in the last {@link #MAILBOX_REFRESH_MIN_INTERVAL}.
*/
@VisibleForTesting
boolean shouldRefreshMailboxList() {
if (mRefreshManager.isMailboxListRefreshing(mAccountId)) {
return false;
}
final long nextRefreshTime = mRefreshManager.getLastMailboxListRefreshTime(mAccountId)
+ MAILBOX_REFRESH_MIN_INTERVAL;
if (nextRefreshTime > mClock.getTime()) {
return false;
}
return true;
}
/**
* @return true if the inbox of the current account hasn't been refreshed
* in the last {@link #INBOX_AUTO_REFRESH_MIN_INTERVAL}.
*/
@VisibleForTesting
boolean shouldAutoRefreshInbox() {
if (mInboxId == mMailboxId) {
return false; // Current ID == inbox. No need to auto-refresh.
}
if (mRefreshManager.isMessageListRefreshing(mInboxId)) {
return false;
}
final long nextRefreshTime = mRefreshManager.getLastMessageListRefreshTime(mInboxId)
+ INBOX_AUTO_REFRESH_MIN_INTERVAL;
if (nextRefreshTime > mClock.getTime()) {
return false;
}
return true;
}
}
private class ActionBarControllerCallback implements ActionBarController.Callback {
@Override
public String getCurrentMailboxName() {
return mCurrentMailboxName;
}
@Override
public int getCurrentMailboxUnreadCount() {
return mCurrentMailboxUnreadCount;
}
@Override
public long getUIAccountId() {
return UIControllerTwoPane.this.getUIAccountId();
}
@Override
public boolean isAccountSelected() {
return UIControllerTwoPane.this.isAccountSelected();
}
@Override
public void onAccountSelected(long accountId) {
switchAccount(accountId);
}
@Override
public void onNoAccountsFound() {
Welcome.actionStart(mActivity);
mActivity.finish();
}
@Override
public boolean shouldShowMailboxName() {
// Show when the left pane is hidden.
return (mThreePane.getVisiblePanes() & ThreePaneLayout.PANE_LEFT) == 0;
}
@Override
public boolean shouldShowUp() {
final int visiblePanes = mThreePane.getVisiblePanes();
final boolean leftPaneHidden = ((visiblePanes & ThreePaneLayout.PANE_LEFT) == 0);
return leftPaneHidden || (isMailboxListInstalled() && !mMailboxListFragment.isRoot());
}
}
}