Merge "MailboxListFragment: In-place nested mailbox navigation"
This commit is contained in:
commit
3bfd5734b8
|
@ -20,7 +20,6 @@ import com.android.email.Email;
|
|||
import com.android.email.FolderProperties;
|
||||
import com.android.email.R;
|
||||
import com.android.email.data.ClosingMatrixCursor;
|
||||
import com.android.email.data.CursorWithExtras;
|
||||
import com.android.email.data.ThrottlingCursorLoader;
|
||||
import com.android.emailcommon.Logging;
|
||||
import com.android.emailcommon.provider.EmailContent;
|
||||
|
@ -34,10 +33,10 @@ import com.android.emailcommon.utility.Utility;
|
|||
import android.content.Context;
|
||||
import android.content.Loader;
|
||||
import android.database.Cursor;
|
||||
import android.database.CursorWrapper;
|
||||
import android.database.MatrixCursor;
|
||||
import android.database.MatrixCursor.RowBuilder;
|
||||
import android.database.MergeCursor;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -61,6 +60,24 @@ import android.widget.TextView;
|
|||
/*package*/ class MailboxFragmentAdapter extends MailboxesAdapter {
|
||||
private static final String MAILBOX_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?" +
|
||||
" AND " + MailboxColumns.ID + "=?";
|
||||
|
||||
/**
|
||||
* {@link Cursor} with extra information which is returned by the loader created by
|
||||
* {@link MailboxFragmentAdapter#createMailboxesLoader}.
|
||||
*/
|
||||
public static class CursorWithExtras extends CursorWrapper {
|
||||
/**
|
||||
* The number of mailboxes in the cursor if the cursor contains top-level mailboxes.
|
||||
* Otherwise, the number of *child* mailboxes.
|
||||
*/
|
||||
public final int mChildCount;
|
||||
|
||||
CursorWithExtras(Cursor cursor, int childCount) {
|
||||
super(cursor);
|
||||
mChildCount = childCount;
|
||||
}
|
||||
}
|
||||
|
||||
public MailboxFragmentAdapter(Context context, Callback callback) {
|
||||
super(context, callback);
|
||||
}
|
||||
|
@ -169,19 +186,32 @@ import android.widget.TextView;
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor loader for the mailboxes of the given account. If <code>parentKey</code>
|
||||
* Returns a cursor loader for the mailboxes of the given account. If <code>parentKey</code>
|
||||
* refers to a valid mailbox ID [e.g. non-zero], restrict the loader to only those mailboxes
|
||||
* contained by this parent mailbox.
|
||||
*
|
||||
* Note the returned loader always returns a {@link CursorWithExtras}.
|
||||
*/
|
||||
public static Loader<Cursor> createLoader(Context context, long accountId, long parentKey) {
|
||||
public static Loader<Cursor> createMailboxesLoader(Context context, long accountId,
|
||||
long parentMailboxId) {
|
||||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, "MailboxFragmentAdapter#createLoader accountId=" + accountId);
|
||||
Log.d(Logging.LOG_TAG, "MailboxFragmentAdapter#CursorWithExtras accountId=" + accountId
|
||||
+ " parentMailboxId=" + parentMailboxId);
|
||||
}
|
||||
if (accountId != Account.ACCOUNT_ID_COMBINED_VIEW) {
|
||||
return new MailboxFragmentLoader(context, accountId, parentKey);
|
||||
} else {
|
||||
return new CombinedMailboxLoader(context);
|
||||
if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new MailboxFragmentLoader(context, accountId, parentMailboxId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor loader for the combined view.
|
||||
*/
|
||||
public static Loader<Cursor> createCombinedViewLoader(Context context) {
|
||||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, "MailboxFragmentAdapter#createCombinedViewLoader");
|
||||
}
|
||||
return new CombinedMailboxLoader(context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,6 +250,8 @@ import android.widget.TextView;
|
|||
|
||||
/**
|
||||
* Loads mailboxes that are the children of a given mailbox ID.
|
||||
*
|
||||
* The returned {@link Cursor} is always a {@link CursorWithExtras}.
|
||||
*/
|
||||
private static class MailboxFragmentLoader extends ThrottlingCursorLoader {
|
||||
private final Context mContext;
|
||||
|
@ -248,25 +280,20 @@ import android.widget.TextView;
|
|||
|
||||
@Override
|
||||
public Cursor loadInBackground() {
|
||||
boolean parentRemoved = false;
|
||||
|
||||
final Cursor childMailboxCursor = super.loadInBackground();
|
||||
final Cursor returnCursor;
|
||||
final Bundle extras = new Bundle();
|
||||
|
||||
// Setup the extras to return along with the cursor
|
||||
int cursorCount = childMailboxCursor.getCount();
|
||||
extras.putInt(CursorWithExtras.EXTRA_MAILBOX_CHILD_COUNT, cursorCount);
|
||||
long nextParentKey = findParentWithChildren(mParentKey);
|
||||
extras.putLong(CursorWithExtras.EXTRA_MAILBOX_NEXT_PARENT_ID, nextParentKey);
|
||||
Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, mParentKey);
|
||||
long grandParentKey = mailbox == null ? Mailbox.NO_MAILBOX : mailbox.mParentKey;
|
||||
extras.putLong(CursorWithExtras.EXTRA_MAILBOX_PARENT_ID, grandParentKey);
|
||||
final int childCount = childMailboxCursor.getCount();
|
||||
|
||||
// If we're not showing the top level mailboxes, add the "parent" mailbox.
|
||||
if (mParentKey != Mailbox.NO_MAILBOX) {
|
||||
// If we're not showing the top level mailboxes, add the "parent" mailbox.
|
||||
final Cursor parentCursor = getContext().getContentResolver().query(
|
||||
Mailbox.CONTENT_URI, CURMAILBOX_PROJECTION, MAILBOX_SELECTION,
|
||||
new String[] { Long.toString(mAccountId), Long.toString(mParentKey) },
|
||||
null);
|
||||
|
||||
returnCursor = new MergeCursor(new Cursor[] { parentCursor, childMailboxCursor });
|
||||
} else {
|
||||
// Add "Starred", only if the account has at least one starred message.
|
||||
|
@ -286,28 +313,8 @@ import android.widget.TextView;
|
|||
}
|
||||
}
|
||||
|
||||
return new CursorWithExtras(Utility.CloseTraceCursorWrapper.get(returnCursor), extras);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next parent mailbox with at least one child mailbox. If the given
|
||||
* mailbox does not exist in the database, returns {@link Mailbox#NO_MAILBOX}. If
|
||||
* we reach the root parent and we still don't have children, returns
|
||||
* {@link Mailbox#NO_MAILBOX}.
|
||||
*/
|
||||
private long findParentWithChildren(long mailboxId) {
|
||||
int childCount = Mailbox.count(mContext, Mailbox.CONTENT_URI,
|
||||
MAILBOX_SELECTION_WITH_PARENT,
|
||||
new String[] { Long.toString(mAccountId), Long.toString(mailboxId) });
|
||||
if (childCount == 0 && mailboxId != Mailbox.NO_MAILBOX) {
|
||||
// There are no children; select parent
|
||||
Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, mailboxId);
|
||||
if (mailbox == null) {
|
||||
return Mailbox.NO_MAILBOX;
|
||||
}
|
||||
return findParentWithChildren(mailbox.mParentKey);
|
||||
}
|
||||
return mailboxId;
|
||||
return new CursorWithExtras(Utility.CloseTraceCursorWrapper.get(returnCursor),
|
||||
childCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,12 +20,13 @@ import com.android.email.Controller;
|
|||
import com.android.email.Email;
|
||||
import com.android.email.R;
|
||||
import com.android.email.RefreshManager;
|
||||
import com.android.email.data.CursorWithExtras;
|
||||
import com.android.email.provider.EmailProvider;
|
||||
import com.android.emailcommon.Logging;
|
||||
import com.android.emailcommon.provider.EmailContent.Account;
|
||||
import com.android.emailcommon.provider.Mailbox;
|
||||
import com.android.emailcommon.utility.EmailAsyncTask;
|
||||
import com.android.emailcommon.utility.Utility;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ListFragment;
|
||||
|
@ -33,6 +34,7 @@ import android.app.LoaderManager;
|
|||
import android.app.LoaderManager.LoaderCallbacks;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipDescription;
|
||||
import android.content.Context;
|
||||
import android.content.Loader;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
|
@ -55,7 +57,90 @@ import java.util.Timer;
|
|||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* This fragment presents a list of mailboxes for a given account.
|
||||
* This fragment presents a list of mailboxes for a given account or the combined mailboxes.
|
||||
*
|
||||
* This fragment has several parameters that determine the current view.
|
||||
*
|
||||
* <pre>
|
||||
* Parameters:
|
||||
* - Account ID.
|
||||
* - Set via {@link #newInstance}.
|
||||
* - Can be obtained with {@link #getAccountId()}.
|
||||
* - Will not change throughout fragment lifecycle.
|
||||
* - Either an actual account ID, or {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
|
||||
*
|
||||
* - "Highlight enabled?" flag
|
||||
* - Set via {@link #newInstance}.
|
||||
* - Can be obtained with {@link #getEnableHighlight()}.
|
||||
* - Will not change throughout fragment lifecycle.
|
||||
* - If {@code true}, we highlight the "selected" mailbox (used only on 2-pane).
|
||||
* - Note even if it's {@code true}, there may be no highlighted mailbox.
|
||||
* (This usually happens on 2-pane before the UI controller finds the Inbox to highlight.)
|
||||
*
|
||||
* - "Parent" mailbox ID
|
||||
* - Stored in {@link #mParentMailboxId}
|
||||
* - Changes as the user navigates through nested mailboxes.
|
||||
* - Initialized using the {@code mailboxId} parameter for {@link #newInstance}
|
||||
* in {@link #setInitialParentAndHighlight()}.
|
||||
*
|
||||
* - "Highlighted" mailbox
|
||||
* - Only used when highlighting is enabled. (Otherwise always {@link Mailbox#NO_MAILBOX}.)
|
||||
* i.e. used only on two-pane.
|
||||
* - Stored in {@link #mHighlightedMailboxId}
|
||||
* - Initialized using the {@code mailboxId} parameter for {@link #newInstance}
|
||||
* in {@link #setInitialParentAndHighlight()}.
|
||||
*
|
||||
* - Can be changed any time, using {@link #setHighlightedMailbox(long)}.
|
||||
*
|
||||
* - If set, it's considered "selected", and we highlight the list item.
|
||||
*
|
||||
* - (It should always be the ID of the list item selected in the list view, but we store it in
|
||||
* a member for efficiency.)
|
||||
*
|
||||
* - Sometimes, we need to set the highlighted mailbox while we're still loading data.
|
||||
* In this case, we can't update {@link #mHighlightedMailboxId} right away, but need to do so
|
||||
* in when the next data set arrives, in
|
||||
* {@link MailboxListFragment.MailboxListLoaderCallbacks#onLoadFinished}. For this, we use
|
||||
* we store the mailbox ID in {@link #mNextHighlightedMailboxId} and update
|
||||
* {@link #mHighlightedMailboxId} in onLoadFinished.
|
||||
*
|
||||
*
|
||||
* The "selected" is defined using the "parent" and "highlighted" mailboxes.
|
||||
* - "Selected" mailbox (also sometimes called "current".)
|
||||
* - This is what the user thinks it's now selected.
|
||||
*
|
||||
* - Can be obtained with {@link #getSelectedMailboxId()}
|
||||
* - If the "highlighted" mailbox exists, it's the "selected." Otherwise, the "parent"
|
||||
* is considered "selected."
|
||||
* - This is what is passed to {@link Callback#onMailboxSelected}.
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* This fragment shows the content in one of the three following views, depending on the
|
||||
* parameters above.
|
||||
*
|
||||
* <pre>
|
||||
* 1. Combined view
|
||||
* - Used if the account ID == {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
|
||||
* - Parent mailbox is always {@link Mailbox#NO_MAILBOX}.
|
||||
* - List contains:
|
||||
* - combined mailboxes
|
||||
* - all accounts
|
||||
*
|
||||
* 2. Root view for an account
|
||||
* - Used if the account ID != {@link Account#ACCOUNT_ID_COMBINED_VIEW} and
|
||||
* Parent mailbox == {@link Mailbox#NO_MAILBOX}
|
||||
* - List contains
|
||||
* - all the top level mailboxes for the selected account.
|
||||
*
|
||||
* 3. Root view for a mailbox. (nested view)
|
||||
* - Used if the account ID != {@link Account#ACCOUNT_ID_COMBINED_VIEW} and
|
||||
* Parent mailbox != {@link Mailbox#NO_MAILBOX}
|
||||
* - List contains:
|
||||
* - parent mailbox (determined by "parent" mailbox ID)
|
||||
* - all child mailboxes of the parent mailbox.
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* Note that when a fragment is put in the back stack, it'll lose the content view but the fragment
|
||||
* itself is not destroyed. If you call {@link #getListView()} in this state it'll throw
|
||||
|
@ -65,14 +150,20 @@ import java.util.TimerTask;
|
|||
* no views.
|
||||
* - Otherwise, make sure to check if the fragment has views with {@link #isViewCreated()}
|
||||
* before touching any views.
|
||||
*
|
||||
* TODO Remove the nested folder navigation code during drag&drop.
|
||||
*/
|
||||
public class MailboxListFragment extends ListFragment implements OnItemClickListener,
|
||||
OnDragListener {
|
||||
private static final String TAG = "MailboxListFragment";
|
||||
private static final String BUNDLE_KEY_SELECTED_MAILBOX_ID
|
||||
|
||||
private static final String BUNDLE_KEY_PARENT_MAILBOX_ID
|
||||
= "MailboxListFragment.state.parent_mailbox_id";
|
||||
private static final String BUNDLE_KEY_HIGHLIGHTED_MAILBOX_ID
|
||||
= "MailboxListFragment.state.selected_mailbox_id";
|
||||
private static final String BUNDLE_LIST_STATE = "MailboxListFragment.state.listState";
|
||||
private static final boolean DEBUG_DRAG_DROP = false; // MUST NOT SUBMIT SET TO TRUE
|
||||
|
||||
/** While in drag-n-drop, amount of time before it auto expands; in ms */
|
||||
private static final long AUTO_EXPAND_DELAY = 750L;
|
||||
|
||||
|
@ -88,7 +179,10 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
|
||||
/** Argument name(s) */
|
||||
private static final String ARG_ACCOUNT_ID = "accountId";
|
||||
private static final String ARG_PARENT_MAILBOX_ID = "parentMailboxId";
|
||||
private static final String ARG_ENABLE_HIGHLIGHT = "enablehighlight";
|
||||
private static final String ARG_INITIAL_CURRENT_MAILBOX_ID = "initialParentMailboxId";
|
||||
|
||||
private final EmailAsyncTask.Tracker mTaskTracker = new EmailAsyncTask.Tracker();
|
||||
|
||||
/** Timer to auto-expand folder lists during drag-n-drop */
|
||||
private static final Timer sDragTimer = new Timer();
|
||||
|
@ -106,8 +200,14 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
private static Integer sDropTrashColor;
|
||||
private static Drawable sDropActiveDrawable;
|
||||
|
||||
/** ID of the mailbox to hightlight. */
|
||||
private long mSelectedMailboxId = -1;
|
||||
// See the class javadoc
|
||||
private long mParentMailboxId;
|
||||
private long mHighlightedMailboxId;
|
||||
|
||||
/**
|
||||
* ID of the mailbox that should be highlighted when the next cursor is loaded.
|
||||
*/
|
||||
private long mNextHighlightedMailboxId = Mailbox.NO_MAILBOX;
|
||||
|
||||
// True if a drag is currently in progress
|
||||
private boolean mDragInProgress;
|
||||
|
@ -147,28 +247,20 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
* @param mailboxId
|
||||
* The ID of the selected mailbox. This may be real mailbox ID [e.g. a number > 0],
|
||||
* or a combined mailbox ID [e.g. {@link Mailbox#QUERY_ALL_INBOXES}].
|
||||
* @param navigate navigate to the mailbox.
|
||||
* @param nestedNavigation {@code true} if the event is caused by nested mailbox navigation,
|
||||
* that is, going up or drilling-in to a child mailbox.
|
||||
*/
|
||||
public void onMailboxSelected(long accountId, long mailboxId, boolean navigate);
|
||||
|
||||
/**
|
||||
* Called if the mailbox ID is being requested to change. This could occur for several
|
||||
* reasons; such as if the current, navigated mailbox has no more children.
|
||||
* @param newMailboxId The new mailbox ID to use for displaying in the mailbox list
|
||||
* @param selectedMailboxId The new mailbox ID to highlight. If {@link Mailbox#NO_MAILBOX},
|
||||
* the receiver may select any mailbox it chooses.
|
||||
*/
|
||||
public void requestMailboxChange(long newMailboxId, long selectedMailboxId);
|
||||
|
||||
/**
|
||||
* Called when a mailbox is selected during D&D.
|
||||
*/
|
||||
public void onMailboxSelectedForDnD(long mailboxId);
|
||||
public void onMailboxSelected(long accountId, long mailboxId, boolean nestedNavigation);
|
||||
|
||||
/** Called when an account is selected on the combined view. */
|
||||
public void onAccountSelected(long accountId);
|
||||
|
||||
/**
|
||||
* TODO Remove it. The behavior is not well-defined. (Won't get called when highlight is
|
||||
* disabled.)
|
||||
* It was added only to update the action bar with the current mailbox name and the
|
||||
* message count. Remove it and make the action bar watch the mailbox by itself.
|
||||
*
|
||||
* Called when the list updates to propagate the current mailbox name and the unread count
|
||||
* for it.
|
||||
*
|
||||
|
@ -180,17 +272,22 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
* {@link MailboxListFragment#getAccountId()}.
|
||||
*/
|
||||
public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, int unreadCount);
|
||||
|
||||
/**
|
||||
* Called when the parent mailbox is changing.
|
||||
*/
|
||||
public void onParentMailboxChanged();
|
||||
}
|
||||
|
||||
private static class EmptyCallback implements Callback {
|
||||
public static final Callback INSTANCE = new EmptyCallback();
|
||||
@Override public void onMailboxSelected(long accountId, long mailboxId, boolean navigate) {
|
||||
}
|
||||
@Override public void onMailboxSelectedForDnD(long mailboxId) { }
|
||||
@Override public void onMailboxSelected(long accountId, long mailboxId,
|
||||
boolean nestedNavigation) { }
|
||||
@Override public void onAccountSelected(long accountId) { }
|
||||
@Override public void onCurrentMailboxUpdated(long mailboxId, String mailboxName,
|
||||
int unreadCount) { }
|
||||
@Override public void requestMailboxChange(long newMailboxId, long selectedMailboxId) { }
|
||||
@Override
|
||||
public void onParentMailboxChanged() { }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,17 +314,18 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
* This fragment should be created only with this method. (Arguments should always be set.)
|
||||
*
|
||||
* @param accountId The ID of the account we want to view
|
||||
* @param parentMailboxId The ID of the parent mailbox. Use {@link Mailbox#NO_MAILBOX}
|
||||
* to open the root.
|
||||
* @param initialCurrentMailboxId ID of the mailbox of interest.
|
||||
* Pass {@link Mailbox#NO_MAILBOX} to show top-level mailboxes.
|
||||
* @param enableHighlight {@code true} if highlighting is enabled on the current screen
|
||||
* configuration. (We don't highlight mailboxes on one-pane.)
|
||||
*/
|
||||
public static MailboxListFragment newInstance(long accountId, long parentMailboxId) {
|
||||
if (accountId == Account.NO_ACCOUNT) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
public static MailboxListFragment newInstance(long accountId, long initialCurrentMailboxId,
|
||||
boolean enableHighlight) {
|
||||
final MailboxListFragment instance = new MailboxListFragment();
|
||||
final Bundle args = new Bundle();
|
||||
args.putLong(ARG_ACCOUNT_ID, accountId);
|
||||
args.putLong(ARG_PARENT_MAILBOX_ID, parentMailboxId);
|
||||
args.putLong(ARG_INITIAL_CURRENT_MAILBOX_ID, initialCurrentMailboxId);
|
||||
args.putBoolean(ARG_ENABLE_HIGHLIGHT, enableHighlight);
|
||||
instance.setArguments(args);
|
||||
return instance;
|
||||
}
|
||||
|
@ -239,25 +337,32 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
* constructs, this <em>must</em> be considered immutable.
|
||||
*/
|
||||
private Long mImmutableAccountId;
|
||||
|
||||
/**
|
||||
* We will display the children of this mailbox. May be {@link Mailbox#NO_MAILBOX} to display
|
||||
* all of the top-level mailboxes. Do NOT use directly; instead, use
|
||||
* {@link #getParentMailboxId()}.
|
||||
* {@code initialCurrentMailboxId} passed to {@link #newInstance}.
|
||||
* Do not use directly; instead, use {@link #getInitialCurrentMailboxId()}.
|
||||
* <p><em>NOTE:</em> Although we cannot force these to be immutable using Java language
|
||||
* constructs, this <em>must</em> be considered immutable.
|
||||
*/
|
||||
private Long mImmutableParentMailboxId;
|
||||
private long mImmutableInitialCurrentMailboxId;
|
||||
|
||||
/**
|
||||
* {@code enableHighlight} passed to {@link #newInstance}.
|
||||
* Do not use directly; instead, use {@link #getEnableHighlight()}.
|
||||
* <p><em>NOTE:</em> Although we cannot force these to be immutable using Java language
|
||||
* constructs, this <em>must</em> be considered immutable.
|
||||
*/
|
||||
private boolean mImmutableEnableHighlight;
|
||||
|
||||
private void initializeArgCache() {
|
||||
if (mImmutableAccountId != null) return;
|
||||
mImmutableAccountId
|
||||
= getArguments().getLong(ARG_ACCOUNT_ID, Account.NO_ACCOUNT);
|
||||
mImmutableParentMailboxId
|
||||
= getArguments().getLong(ARG_PARENT_MAILBOX_ID, Mailbox.NO_MAILBOX);
|
||||
mImmutableAccountId = getArguments().getLong(ARG_ACCOUNT_ID);
|
||||
mImmutableInitialCurrentMailboxId = getArguments().getLong(ARG_INITIAL_CURRENT_MAILBOX_ID);
|
||||
mImmutableEnableHighlight = getArguments().getBoolean(ARG_ENABLE_HIGHLIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the account ID passed to {@link #newInstance}. Safe to call even before onCreate.
|
||||
* @return {@code accountId} passed to {@link #newInstance}. Safe to call even before onCreate.
|
||||
*/
|
||||
public long getAccountId() {
|
||||
initializeArgCache();
|
||||
|
@ -265,20 +370,21 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the mailbox ID passed to {@link #newInstance}. Safe to call even before onCreate.
|
||||
* @return {@code initialCurrentMailboxId} passed to {@link #newInstance}.
|
||||
* Safe to call even before onCreate.
|
||||
*/
|
||||
public long getParentMailboxId() {
|
||||
public long getInitialCurrentMailboxId() {
|
||||
initializeArgCache();
|
||||
return mImmutableParentMailboxId;
|
||||
return mImmutableInitialCurrentMailboxId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the top level mailboxes are shown. Safe to call even before onCreate.
|
||||
* @return {@code enableHighlight} passed to {@link #newInstance}.
|
||||
* Safe to call even before onCreate.
|
||||
*/
|
||||
public boolean isRoot() {
|
||||
// TODO if we add meta-mailboxes to the database, remove special test for account ID
|
||||
return getParentMailboxId() == Mailbox.NO_MAILBOX
|
||||
|| getAccountId() == Account.ACCOUNT_ID_COMBINED_VIEW;
|
||||
public boolean getEnableHighlight() {
|
||||
initializeArgCache();
|
||||
return mImmutableEnableHighlight;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -304,9 +410,13 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
mRefreshManager = RefreshManager.getInstance(mActivity);
|
||||
mListAdapter = new MailboxFragmentAdapter(mActivity, mMailboxesAdapterCallback);
|
||||
setListAdapter(mListAdapter); // It's safe to do even before the list view is created.
|
||||
if (savedInstanceState != null) {
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
setInitialParentAndHighlight();
|
||||
} else {
|
||||
restoreInstanceState(savedInstanceState);
|
||||
}
|
||||
|
||||
if (sDropTrashColor == null) {
|
||||
Resources res = getResources();
|
||||
sDropTrashColor = res.getColor(R.color.mailbox_drop_destructive_bg_color);
|
||||
|
@ -314,6 +424,24 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set {@link #mParentMailboxId} and {@link #mHighlightedMailboxId} from the fragment arguments.
|
||||
*/
|
||||
private void setInitialParentAndHighlight() {
|
||||
if (getAccountId() == Account.ACCOUNT_ID_COMBINED_VIEW) {
|
||||
// For the combined view, always show the top-level, but highlight the "current".
|
||||
mParentMailboxId = Mailbox.NO_MAILBOX;
|
||||
} else {
|
||||
// Otherwise, try using the "current" as the "parent" (and also highlight it).
|
||||
// If it has no children, we go up in onLoadFinished().
|
||||
mParentMailboxId = getInitialCurrentMailboxId();
|
||||
}
|
||||
// Highlight the mailbox of interest
|
||||
if (getEnableHighlight()) {
|
||||
mHighlightedMailboxId = getInitialCurrentMailboxId();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
@ -345,7 +473,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
|
||||
lv.setOnDragListener(this);
|
||||
|
||||
startLoading();
|
||||
startLoading(mParentMailboxId, mHighlightedMailboxId);
|
||||
}
|
||||
|
||||
public void setCallback(Callback callback) {
|
||||
|
@ -368,15 +496,6 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected mailbox to the given ID. Sub-folders will not be loaded.
|
||||
* @param mailboxId The ID of the mailbox to select.
|
||||
*/
|
||||
public void setSelectedMailbox(long mailboxId) {
|
||||
mSelectedMailboxId = mailboxId;
|
||||
highlightSelectedMailbox(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Fragment is visible to the user.
|
||||
*/
|
||||
|
@ -442,6 +561,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " onDestroy");
|
||||
}
|
||||
mTaskTracker.cancellAllInterrupt();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
@ -459,7 +579,8 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
Log.d(Logging.LOG_TAG, this + " onSaveInstanceState");
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putLong(BUNDLE_KEY_SELECTED_MAILBOX_ID, mSelectedMailboxId);
|
||||
outState.putLong(BUNDLE_KEY_PARENT_MAILBOX_ID, mParentMailboxId);
|
||||
outState.putLong(BUNDLE_KEY_HIGHLIGHTED_MAILBOX_ID, mHighlightedMailboxId);
|
||||
if (isViewCreated()) {
|
||||
outState.putParcelable(BUNDLE_LIST_STATE, getListView().onSaveInstanceState());
|
||||
}
|
||||
|
@ -469,23 +590,197 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " restoreInstanceState");
|
||||
}
|
||||
mSelectedMailboxId = savedInstanceState.getLong(BUNDLE_KEY_SELECTED_MAILBOX_ID);
|
||||
mParentMailboxId = savedInstanceState.getLong(BUNDLE_KEY_PARENT_MAILBOX_ID);
|
||||
mHighlightedMailboxId = savedInstanceState.getLong(BUNDLE_KEY_HIGHLIGHTED_MAILBOX_ID);
|
||||
mSavedListState = savedInstanceState.getParcelable(BUNDLE_LIST_STATE);
|
||||
}
|
||||
|
||||
private void startLoading() {
|
||||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " startLoading");
|
||||
/**
|
||||
* @return "Selected" mailbox ID.
|
||||
*/
|
||||
public long getSelectedMailboxId() {
|
||||
return (mHighlightedMailboxId != Mailbox.NO_MAILBOX) ? mHighlightedMailboxId
|
||||
: mParentMailboxId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if top-level mailboxes are shown. {@code false} otherwise.
|
||||
*/
|
||||
public boolean isRoot() {
|
||||
return mParentMailboxId == Mailbox.NO_MAILBOX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate one level up in the mailbox hierarchy. Does nothing if at the root account view.
|
||||
*/
|
||||
public boolean navigateUp() {
|
||||
if (isRoot()) {
|
||||
return false;
|
||||
}
|
||||
FindParentMailboxTask.ResultCallback callback = new FindParentMailboxTask.ResultCallback() {
|
||||
@Override public void onResult(long nextParentMailboxId,
|
||||
long nextHighlightedMailboxId, long nextSelectedMailboxId) {
|
||||
|
||||
startLoading(nextParentMailboxId, nextHighlightedMailboxId);
|
||||
|
||||
if (nextSelectedMailboxId != Mailbox.NO_MAILBOX) {
|
||||
mCallback.onMailboxSelected(getAccountId(), nextSelectedMailboxId, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
new FindParentMailboxTask(
|
||||
getActivity().getApplicationContext(), mTaskTracker, getAccountId(),
|
||||
getEnableHighlight(), mParentMailboxId, mHighlightedMailboxId, callback
|
||||
).cancelPreviousAndExecuteParallel((Void[]) null);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A task to determine what parent mailbox ID/highlighted mailbox ID to use for the "UP"
|
||||
* navigation, given the current parent mailbox ID, the highlighted mailbox ID, and {@link
|
||||
* #mEnableHighlight}.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static class FindParentMailboxTask extends EmailAsyncTask<Void, Void, Long[]> {
|
||||
public interface ResultCallback {
|
||||
/**
|
||||
* Callback to get the result.
|
||||
*
|
||||
* @param nextParentMailboxId ID of the mailbox to use
|
||||
* @param nextHighlightedMailboxId ID of the mailbox to highlight
|
||||
* @param nextSelectedMailboxId ID of the mailbox to notify with
|
||||
* {@link Callback#onMailboxSelected}.
|
||||
*/
|
||||
public void onResult(long nextParentMailboxId, long nextHighlightedMailboxId,
|
||||
long nextSelectedMailboxId);
|
||||
}
|
||||
|
||||
private final Context mContext;
|
||||
private final long mAccountId;
|
||||
private final boolean mEnableHighlight;
|
||||
private final long mParentMailboxId;
|
||||
private final long mHighlightedMailboxId;
|
||||
private final ResultCallback mCallback;
|
||||
|
||||
public FindParentMailboxTask(Context context, EmailAsyncTask.Tracker taskTracker,
|
||||
long accountId, boolean enableHighlight, long parentMailboxId,
|
||||
long highlightedMailboxId, ResultCallback callback) {
|
||||
super(taskTracker);
|
||||
mContext = context;
|
||||
mAccountId = accountId;
|
||||
mEnableHighlight = enableHighlight;
|
||||
mParentMailboxId = parentMailboxId;
|
||||
mHighlightedMailboxId = highlightedMailboxId;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Long[] doInBackground(Void... params) {
|
||||
Mailbox parentMailbox = Mailbox.restoreMailboxWithId(mContext, mParentMailboxId);
|
||||
final long nextParentId = (parentMailbox == null) ? Mailbox.NO_MAILBOX
|
||||
: parentMailbox.mParentKey;
|
||||
final long nextHighlightedId;
|
||||
final long nextSelectedId;
|
||||
if (mEnableHighlight) {
|
||||
// If the "parent" is highlighted before the transition, it should still be
|
||||
// highlighted after the upper level view.
|
||||
if (mParentMailboxId == mHighlightedMailboxId) {
|
||||
nextHighlightedId = mParentMailboxId;
|
||||
} else {
|
||||
// Otherwise, the next parent will be highlighted, unless we're going up to
|
||||
// the root, in which case Inbox should be highlighted.
|
||||
if (nextParentId == Mailbox.NO_MAILBOX) {
|
||||
nextHighlightedId = Mailbox.findMailboxOfType(mContext, mAccountId,
|
||||
Mailbox.TYPE_INBOX);
|
||||
} else {
|
||||
nextHighlightedId = nextParentId;
|
||||
}
|
||||
}
|
||||
|
||||
// Highlighted one will be "selected".
|
||||
nextSelectedId = nextHighlightedId;
|
||||
|
||||
} else { // !mEnableHighlight
|
||||
nextHighlightedId = Mailbox.NO_MAILBOX;
|
||||
|
||||
// Parent will be selected.
|
||||
nextSelectedId = nextParentId;
|
||||
}
|
||||
return new Long[]{nextParentId, nextHighlightedId, nextSelectedId};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Long[] result) {
|
||||
mCallback.onResult(result[0], result[1], result[2]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the loader.
|
||||
*
|
||||
* @param parentMailboxId Mailbox ID to be used as the "parent" mailbox
|
||||
* @param highlightedMailboxId Mailbox ID that should be highlighted when the data is loaded.
|
||||
*/
|
||||
private void startLoading(long parentMailboxId, long highlightedMailboxId
|
||||
) {
|
||||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " startLoading parent=" + parentMailboxId
|
||||
+ " highlighted=" + highlightedMailboxId);
|
||||
}
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
boolean parentMailboxChanging = false;
|
||||
|
||||
// Parent mailbox changing -- destroy the current loader to force reload.
|
||||
if (mParentMailboxId != parentMailboxId) {
|
||||
lm.destroyLoader(MAILBOX_LOADER_ID);
|
||||
setListShown(false);
|
||||
parentMailboxChanging = true;
|
||||
}
|
||||
mParentMailboxId = parentMailboxId;
|
||||
if (getEnableHighlight()) {
|
||||
mNextHighlightedMailboxId = highlightedMailboxId;
|
||||
}
|
||||
|
||||
lm.initLoader(MAILBOX_LOADER_ID, null, new MailboxListLoaderCallbacks());
|
||||
|
||||
if (parentMailboxChanging) {
|
||||
mCallback.onParentMailboxChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight the given mailbox.
|
||||
*
|
||||
* If data is already loaded, it just sets {@link #mHighlightedMailboxId} and highlight the
|
||||
* corresponding list item. (And if the corresponding list item is not found,
|
||||
* {@link #mHighlightedMailboxId} is set to {@link Mailbox#NO_MAILBOX})
|
||||
*
|
||||
* If we're still loading data, it sets {@link #mNextHighlightedMailboxId} instead, and then
|
||||
* it'll be set to {@link #mHighlightedMailboxId} in
|
||||
* {@link MailboxListLoaderCallbacks#onLoadFinished}.
|
||||
*
|
||||
* @param mailboxId The ID of the mailbox to highlight.
|
||||
*/
|
||||
public void setHighlightedMailbox(long mailboxId) {
|
||||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " setHighlightedMailbox mailbox=" + mailboxId);
|
||||
}
|
||||
if (!getEnableHighlight()) {
|
||||
return;
|
||||
}
|
||||
if (mListAdapter.getCursor() == null) {
|
||||
// List not loaded yet. Just remember the ID here and let onLoadFinished() update
|
||||
// mHighlightedMailboxId.
|
||||
mNextHighlightedMailboxId = mailboxId;
|
||||
return;
|
||||
}
|
||||
mHighlightedMailboxId = mailboxId;
|
||||
updateHighlightedMailbox(true);
|
||||
}
|
||||
|
||||
// TODO This class probably should be made static. There are many calls into the enclosing
|
||||
// class and we need to be cautious about what we call while in these callbacks
|
||||
private class MailboxListLoaderCallbacks implements LoaderCallbacks<Cursor> {
|
||||
/** Whether or not the loader has finished at least once */
|
||||
private boolean mIsFirstLoad;
|
||||
|
||||
@Override
|
||||
|
@ -494,8 +789,12 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
Log.d(Logging.LOG_TAG, MailboxListFragment.this + " onCreateLoader");
|
||||
}
|
||||
mIsFirstLoad = true;
|
||||
return MailboxFragmentAdapter.createLoader(getActivity(), getAccountId(),
|
||||
getParentMailboxId());
|
||||
if (getAccountId() == Account.ACCOUNT_ID_COMBINED_VIEW) {
|
||||
return MailboxFragmentAdapter.createCombinedViewLoader(getActivity());
|
||||
} else {
|
||||
return MailboxFragmentAdapter.createMailboxesLoader(getActivity(), getAccountId(),
|
||||
mParentMailboxId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -504,44 +803,43 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
Log.d(Logging.LOG_TAG, MailboxListFragment.this + " onLoadFinished count="
|
||||
+ cursor.getCount());
|
||||
}
|
||||
// Note at this point we can assume the view is created.
|
||||
// Note in onLoadFinished we can assume the view is created.
|
||||
// The loader manager doesn't deliver results when a fragment is stopped.
|
||||
|
||||
// Validate the cursor and make sure we're showing the "right thing"
|
||||
if (cursor instanceof CursorWithExtras) {
|
||||
CursorWithExtras c = (CursorWithExtras) cursor;
|
||||
int childCount = c.getInt(CursorWithExtras.EXTRA_MAILBOX_CHILD_COUNT, -1);
|
||||
if (childCount == 0) {
|
||||
long nextParentId = c.getLong(CursorWithExtras.EXTRA_MAILBOX_NEXT_PARENT_ID);
|
||||
long grandParentId = c.getLong(CursorWithExtras.EXTRA_MAILBOX_PARENT_ID);
|
||||
long highlightId;
|
||||
// Only set a mailbox highlight if we're choosing our immediate parent
|
||||
if (grandParentId == nextParentId) {
|
||||
highlightId = getParentMailboxId();
|
||||
} else {
|
||||
highlightId = Mailbox.NO_MAILBOX;
|
||||
}
|
||||
// If the next parent w/ children isn't us, request a change
|
||||
if (nextParentId != getParentMailboxId()) {
|
||||
mCallback.requestMailboxChange(nextParentId, highlightId);
|
||||
return;
|
||||
}
|
||||
// If we're showing a nested mailboxes, and the current parent mailbox has no children,
|
||||
// go up.
|
||||
if (getAccountId() != Account.ACCOUNT_ID_COMBINED_VIEW) {
|
||||
MailboxFragmentAdapter.CursorWithExtras c =
|
||||
(MailboxFragmentAdapter.CursorWithExtras) cursor;
|
||||
if ((c.mChildCount == 0) && !isRoot()) {
|
||||
navigateUp();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor.getCount() == 0) {
|
||||
// If there's no row, don't set it to the ListView.
|
||||
// Instead use setListShown(false) to make ListFragment show progress icon.
|
||||
// There's no row -- call setListShown(false) to make ListFragment show progress
|
||||
// icon.
|
||||
mListAdapter.swapCursor(null);
|
||||
setListShown(false);
|
||||
} else {
|
||||
// Set the adapter.
|
||||
mListAdapter.swapCursor(cursor);
|
||||
setListShown(true);
|
||||
|
||||
// Update the highlighted mailbox
|
||||
if (mNextHighlightedMailboxId != Mailbox.NO_MAILBOX) {
|
||||
mHighlightedMailboxId = mNextHighlightedMailboxId;
|
||||
mNextHighlightedMailboxId = Mailbox.NO_MAILBOX;
|
||||
}
|
||||
|
||||
// We want to make visible the selection only for the first load.
|
||||
// Re-load caused by content changed events shouldn't scroll the list.
|
||||
highlightSelectedMailbox(mIsFirstLoad);
|
||||
if (!updateHighlightedMailbox(mIsFirstLoad)) {
|
||||
|
||||
// TODO We should just select the parent mailbox, or Inbox if it's already
|
||||
// top-level. Make sure to call onMailboxSelected().
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// List has been reloaded; clear any drop target information
|
||||
|
@ -580,33 +878,50 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
if (mListAdapter.isAccountRow(position)) {
|
||||
mCallback.onAccountSelected(id);
|
||||
} else {
|
||||
// STOPSHIP On phone, we need a way to open a message list without navigating to the
|
||||
// mailbox.
|
||||
mCallback.onMailboxSelected(mListAdapter.getAccountId(position), id,
|
||||
isNavigable(id));
|
||||
// Save account-id. (Need to do this before startLoading() below, which will destroy
|
||||
// the current loader and make the mListAdapter lose the cursor.
|
||||
// Note, don't just use getAccountId(). A mailbox may tied to a different account ID
|
||||
// from getAccountId(). (Currently "Starred" does so.)
|
||||
final long accountId = mListAdapter.getAccountId(position);
|
||||
boolean nestedNavigation = false;
|
||||
if (isNavigable(id) && (id != mParentMailboxId)) {
|
||||
// Drill-in. Selected one will be the next parent, and it'll also be highlighted.
|
||||
startLoading(id, id);
|
||||
nestedNavigation = true;
|
||||
}
|
||||
mCallback.onMailboxSelected(accountId, id, nestedNavigation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight the selected mailbox.
|
||||
* Really highlight the mailbox for {@link #mHighlightedMailboxId} on the list view.
|
||||
*
|
||||
* Note if a list item for {@link #mHighlightedMailboxId} is not found,
|
||||
* {@link #mHighlightedMailboxId} will be set to {@link Mailbox#NO_MAILBOX}.
|
||||
*
|
||||
* @return false when the highlighted mailbox seems to be gone; i.e. if
|
||||
* {@link #mHighlightedMailboxId} is set but not found in the list.
|
||||
*/
|
||||
private void highlightSelectedMailbox(boolean ensureSelectionVisible) {
|
||||
if (!isViewCreated()) {
|
||||
return; // Nothing to highlight
|
||||
private boolean updateHighlightedMailbox(boolean ensureSelectionVisible) {
|
||||
if (!getEnableHighlight() || !isViewCreated()) {
|
||||
return true; // Nothing to highlight
|
||||
}
|
||||
final ListView lv = getListView();
|
||||
boolean found = false;
|
||||
String mailboxName = "";
|
||||
int unreadCount = 0;
|
||||
if (mSelectedMailboxId == -1) {
|
||||
if (mHighlightedMailboxId == Mailbox.NO_MAILBOX) {
|
||||
// No mailbox selected
|
||||
lv.clearChoices();
|
||||
found = true;
|
||||
} else {
|
||||
// TODO Don't mix list view & list adapter indices. This is a recipe for disaster.
|
||||
final int count = lv.getCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (mListAdapter.getId(i) != mSelectedMailboxId) {
|
||||
if (mListAdapter.getId(i) != mHighlightedMailboxId) {
|
||||
continue;
|
||||
}
|
||||
found = true;
|
||||
lv.setItemChecked(i, true);
|
||||
if (ensureSelectionVisible) {
|
||||
Utility.listViewSmoothScrollToPosition(getActivity(), lv, i);
|
||||
|
@ -616,7 +931,12 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
break;
|
||||
}
|
||||
}
|
||||
mCallback.onCurrentMailboxUpdated(mSelectedMailboxId, mailboxName, unreadCount);
|
||||
if (found) {
|
||||
mCallback.onCurrentMailboxUpdated(mHighlightedMailboxId, mailboxName, unreadCount);
|
||||
} else {
|
||||
mHighlightedMailboxId = Mailbox.NO_MAILBOX;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
// Drag & Drop handling
|
||||
|
@ -659,7 +979,6 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
@Override
|
||||
public void run() {
|
||||
stopDragTimer();
|
||||
mCallback.onMailboxSelectedForDnD(newTarget.mMailboxId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -74,17 +74,16 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onMailboxSelected(long accountId, long mailboxId, boolean navigate) {
|
||||
public void onMailboxSelected(long accountId, long mailboxId, boolean nestedNavigation) {
|
||||
if (nestedNavigation) {
|
||||
return; // Nothing to do on 1-pane.
|
||||
}
|
||||
openMailbox(accountId, mailboxId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMailboxSelectedForDnD(long mailboxId) {
|
||||
// No drag&drop on 1-pane
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestMailboxChange(long newMailboxId, long selectedMailboxId) {
|
||||
public void onParentMailboxChanged() {
|
||||
refreshActionBar();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -98,7 +97,6 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
@Override
|
||||
public void onEnterSelectionMode(boolean enter) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -345,6 +343,8 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
open(getUIAccountId(), Mailbox.NO_MAILBOX, Message.NO_MESSAGE);
|
||||
return true;
|
||||
} else {
|
||||
// TODO Call MailboxListFragment.navigateUp().
|
||||
|
||||
// STOPSHIP Remove this and return false. This is so that the app can be closed
|
||||
// with the UP press. (usuful when the device doesn't have a HW back key.)
|
||||
mActivity.finish();
|
||||
|
@ -402,7 +402,7 @@ class UIControllerOnePane extends UIControllerBase {
|
|||
|
||||
} else {
|
||||
ft.replace(R.id.fragment_placeholder,
|
||||
MailboxListFragment.newInstance(accountId, Mailbox.NO_MAILBOX));
|
||||
MailboxListFragment.newInstance(accountId, Mailbox.NO_MAILBOX, false));
|
||||
}
|
||||
|
||||
mCurrentAccountId = accountId;
|
||||
|
|
|
@ -169,48 +169,15 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
|
||||
// MailboxListFragment$Callback
|
||||
@Override
|
||||
public void onMailboxSelected(long accountId, long mailboxId, boolean navigate) {
|
||||
public void onMailboxSelected(long accountId, long mailboxId, boolean nestedNavigation) {
|
||||
if ((accountId == Account.NO_ACCOUNT) || (mailboxId == Mailbox.NO_MAILBOX)) {
|
||||
throw new IllegalArgumentException(); // Shouldn't happen.
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
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.
|
||||
if (getMessageListMailboxId() != mailboxId) {
|
||||
updateMessageList(accountId, mailboxId, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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 */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestMailboxChange(final long newMailboxId, final long selectedMailboxId) {
|
||||
// Unfortunately if the screen rotates while the task is running, we just cancel the task
|
||||
// so mailbox change request will be gone. But we'll live with it as it's not too critical.
|
||||
new EmailAsyncTask<Void, Void, Void>(mTaskTracker) {
|
||||
@Override protected Void doInBackground(Void... params) { return null; }
|
||||
@Override protected void onPostExecute(Void mailboxId) {
|
||||
if (selectedMailboxId == getMailboxListMailboxId()) {
|
||||
// We're not changing selections; just the contents of the mailbox list
|
||||
updateMailboxList(getActualAccountId(), newMailboxId, false);
|
||||
mMailboxListFragment.setSelectedMailbox(selectedMailboxId);
|
||||
} else {
|
||||
// Select a whole new mailbox
|
||||
openMailbox(getActualAccountId(), newMailboxId);
|
||||
}
|
||||
}
|
||||
}.cancelPreviousAndExecuteSerial();
|
||||
}
|
||||
|
||||
// MailboxListFragment$Callback
|
||||
@Override
|
||||
public void onAccountSelected(long accountId) {
|
||||
|
@ -225,6 +192,12 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
refreshActionBar();
|
||||
}
|
||||
|
||||
// MailboxListFragment$Callback
|
||||
@Override
|
||||
public void onParentMailboxChanged() {
|
||||
refreshActionBar();
|
||||
}
|
||||
|
||||
// MessageListFragment$Callback
|
||||
@Override
|
||||
public void onMessageOpen(long messageId, long messageMailboxId, long listMailboxId,
|
||||
|
@ -232,8 +205,10 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
if (type == MessageListFragment.Callback.TYPE_DRAFT) {
|
||||
MessageCompose.actionEditDraft(mActivity, messageId);
|
||||
} else {
|
||||
updateMessageView(messageId);
|
||||
mThreePane.showRightPane();
|
||||
if (getMessageId() != messageId) {
|
||||
updateMessageView(messageId);
|
||||
mThreePane.showRightPane();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,7 +406,7 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
* {@link #getMessageListMailboxId()}
|
||||
*/
|
||||
private long getMailboxListMailboxId() {
|
||||
return isMailboxListInstalled() ? mMailboxListFragment.getParentMailboxId()
|
||||
return isMailboxListInstalled() ? mMailboxListFragment.getSelectedMailboxId()
|
||||
: Mailbox.NO_MAILBOX;
|
||||
}
|
||||
|
||||
|
@ -634,13 +609,11 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
}
|
||||
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);
|
||||
|
@ -669,15 +642,15 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
* <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
|
||||
* @param mailboxId ID of the mailbox to use as the "selected". 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,
|
||||
private void updateMailboxList(long accountId, long mailboxId,
|
||||
boolean clearDependentPane) {
|
||||
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
|
||||
Log.d(Logging.LOG_TAG, this + " updateMailboxList accountId=" + accountId
|
||||
+ " parentMailboxId=" + parentMailboxId);
|
||||
+ " mailboxId=" + mailboxId);
|
||||
}
|
||||
preFragmentTransactionCheck();
|
||||
if (accountId == Account.NO_ACCOUNT) {
|
||||
|
@ -686,11 +659,11 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
|
||||
final FragmentManager fm = mActivity.getFragmentManager();
|
||||
final FragmentTransaction ft = fm.beginTransaction();
|
||||
if ((getUIAccountId() != accountId)
|
||||
|| (getMailboxListMailboxId() != parentMailboxId)) {
|
||||
|
||||
if ((getUIAccountId() != accountId) || (getMailboxListMailboxId() != mailboxId)) {
|
||||
uninstallMailboxListFragment(ft);
|
||||
ft.add(mThreePane.getLeftPaneId(),
|
||||
MailboxListFragment.newInstance(accountId, parentMailboxId));
|
||||
MailboxListFragment.newInstance(accountId, mailboxId, true));
|
||||
}
|
||||
if (clearDependentPane) {
|
||||
uninstallMessageListFragment(ft);
|
||||
|
@ -744,7 +717,7 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
}
|
||||
commitFragmentTransaction(ft);
|
||||
|
||||
mMailboxListFragment.setSelectedMailbox(mailboxId);
|
||||
mMailboxListFragment.setHighlightedMailbox(mailboxId);
|
||||
|
||||
// Update action bar / menu
|
||||
updateRefreshProgress();
|
||||
|
@ -896,20 +869,12 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
public boolean onBackPressed(boolean isSystemBackKey) {
|
||||
if (mThreePane.onBackPressed(isSystemBackKey)) {
|
||||
return true;
|
||||
} else if (navigateToParentMailboxList()) {
|
||||
} else if (isMailboxListInstalled() && mMailboxListFragment.navigateUp()) {
|
||||
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.
|
||||
|
@ -1073,7 +1038,8 @@ class UIControllerTwoPane extends UIControllerBase implements
|
|||
public boolean shouldShowUp() {
|
||||
final int visiblePanes = mThreePane.getVisiblePanes();
|
||||
final boolean leftPaneHidden = ((visiblePanes & ThreePaneLayout.PANE_LEFT) == 0);
|
||||
return leftPaneHidden || (isMailboxListInstalled() && !mMailboxListFragment.isRoot());
|
||||
return leftPaneHidden
|
||||
|| (isMailboxListInstalled() && !mMailboxListFragment.isRoot());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,8 +64,12 @@ public class Welcome extends Activity {
|
|||
* Open a message (account id=1, mailbox id=2, message id=3)
|
||||
adb shell am start -a android.intent.action.MAIN \
|
||||
-d '"content://ui.email.android.com/view/mailbox?ACCOUNT_ID=1&MAILBOX_ID=2&MESSAGE_ID=3"' \
|
||||
-e DEBUG_PANE_MODE 2 \
|
||||
-e DEBUG_PANE_MODE 2
|
||||
|
||||
* Open the combined starred on the combined view
|
||||
adb shell am start -a android.intent.action.MAIN \
|
||||
-d '"content://ui.email.android.com/view/mailbox?ACCOUNT_ID=1152921504606846976&MAILBOX_ID=-4"' \
|
||||
-e DEBUG_PANE_MODE 2
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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.data;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.database.CursorWrapper;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* A special cursor that contains additional data.
|
||||
*
|
||||
* <p>TODO Use this instead of EmailWidgetLoader$CursorWithCounts.
|
||||
*/
|
||||
public class CursorWithExtras extends CursorWrapper {
|
||||
/** The number of children in a mailbox. If set, must be a positive value. */
|
||||
public final static String EXTRA_MAILBOX_CHILD_COUNT = "mailboxChildCount";
|
||||
/** The ID of the next, immediate parent mailbox */
|
||||
public final static String EXTRA_MAILBOX_PARENT_ID = "mailboxParentId";
|
||||
/** The ID of the next mailbox in the hierarchy with at least one child */
|
||||
public final static String EXTRA_MAILBOX_NEXT_PARENT_ID = "mailboxNextParentId";
|
||||
|
||||
private final Bundle mExtras;
|
||||
|
||||
public CursorWithExtras(Cursor cursor, Bundle extras) {
|
||||
super(cursor);
|
||||
mExtras = extras;
|
||||
}
|
||||
|
||||
public int getInt(String key) {
|
||||
return getInt(key, 0);
|
||||
}
|
||||
|
||||
public int getInt(String key, int defaultValue) {
|
||||
return mExtras == null ? defaultValue : mExtras.getInt(key);
|
||||
}
|
||||
|
||||
public long getLong(String key) {
|
||||
return getLong(key, 0L);
|
||||
}
|
||||
|
||||
public long getLong(String key, long defaultValue) {
|
||||
return mExtras == null ? defaultValue : mExtras.getLong(key);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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.DBTestHelper;
|
||||
import com.android.email.provider.ProviderTestUtils;
|
||||
import com.android.emailcommon.provider.EmailContent.Account;
|
||||
import com.android.emailcommon.provider.Mailbox;
|
||||
|
||||
import android.content.Context;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MailboxListFragment.FindParentMailboxTask}.
|
||||
*/
|
||||
public class FindParentMailboxTaskTest extends AndroidTestCase {
|
||||
private Context mProviderContext;
|
||||
|
||||
/** ID of the account created by {@link #setUpMailboxes}. */
|
||||
private long mAccountId;
|
||||
|
||||
/**
|
||||
* IDs for the mailboxes created by {@link #setUpMailboxes}.
|
||||
*
|
||||
* Mailbox hierarchy:
|
||||
* <pre>
|
||||
* |-Inbox
|
||||
* |-Parent
|
||||
* |-Child1
|
||||
* |-Child2
|
||||
* |-GrandChild1
|
||||
* |-GrandChild2
|
||||
* </pre>
|
||||
*/
|
||||
private long mIdInbox;
|
||||
private long mIdParent;
|
||||
private long mIdChild1;
|
||||
private long mIdChild2;
|
||||
private long mIdGrandChild1;
|
||||
private long mIdGrandChild2;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
mProviderContext = DBTestHelper.ProviderContextSetupHelper.getProviderContext(
|
||||
getContext());
|
||||
setUpMailboxes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up a test account and mailboxes.
|
||||
*/
|
||||
private void setUpMailboxes() {
|
||||
Account a = ProviderTestUtils.setupAccount("a", true, mProviderContext);
|
||||
mAccountId = a.mId;
|
||||
|
||||
mIdInbox = createMailboxAndGetId("Inbox", a, Mailbox.TYPE_INBOX, Mailbox.NO_MAILBOX);
|
||||
mIdParent = createMailboxAndGetId("P", a, Mailbox.TYPE_MAIL, Mailbox.NO_MAILBOX);
|
||||
mIdChild1 = createMailboxAndGetId("C1", a, Mailbox.TYPE_MAIL, mIdParent);
|
||||
mIdChild2 = createMailboxAndGetId("C2", a, Mailbox.TYPE_MAIL, mIdParent);
|
||||
mIdGrandChild1 = createMailboxAndGetId("G1", a, Mailbox.TYPE_MAIL, mIdChild2);
|
||||
mIdGrandChild2 = createMailboxAndGetId("G2", a, Mailbox.TYPE_MAIL, mIdChild2);
|
||||
}
|
||||
|
||||
private long createMailboxAndGetId(String name, Account account, int type,
|
||||
long parentMailboxId) {
|
||||
Mailbox m = ProviderTestUtils.setupMailbox(name, account.mId, false, mProviderContext,
|
||||
type);
|
||||
m.mParentKey = parentMailboxId;
|
||||
m.save(mProviderContext);
|
||||
return m.mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for two-pane. (highlighting is enabled)
|
||||
*/
|
||||
public void testWithHighlight() {
|
||||
/*
|
||||
* In the comments below, [MAILBOX] indicates "highlighted", and MAILBOX* indicates
|
||||
* "selected".
|
||||
*/
|
||||
/*
|
||||
* from:
|
||||
* - [Child2]
|
||||
* - GChild1
|
||||
* - GChild2
|
||||
*
|
||||
* to:
|
||||
* - Parent
|
||||
* - Child1
|
||||
* - [Child2]*
|
||||
*/
|
||||
doCheckWithHighlight(
|
||||
mIdChild2, // Current parent
|
||||
mIdChild2, // Current highlighted
|
||||
|
||||
mIdParent, // Next root
|
||||
mIdChild2, // Next highlighted
|
||||
mIdChild2 // Next selected
|
||||
);
|
||||
|
||||
/*
|
||||
* from:
|
||||
* - Child2
|
||||
* - [GChild1]
|
||||
* - GChild2
|
||||
*
|
||||
* to:
|
||||
* - [Parent]*
|
||||
* - Child1
|
||||
* - Child2
|
||||
*/
|
||||
doCheckWithHighlight(
|
||||
mIdChild2, // Current parent
|
||||
mIdGrandChild1, // Current highlighted
|
||||
|
||||
mIdParent, // Next root
|
||||
mIdParent, // Next highlighted
|
||||
mIdParent // Next selected
|
||||
);
|
||||
|
||||
/*
|
||||
* from:
|
||||
* - [Parent]
|
||||
* - Child1
|
||||
* - Child2
|
||||
*
|
||||
* to:
|
||||
* - Inbox
|
||||
* - [Parent]*
|
||||
*/
|
||||
doCheckWithHighlight(
|
||||
mIdParent, // Current parent
|
||||
mIdParent, // Current highlighted
|
||||
|
||||
Mailbox.NO_MAILBOX, // Next root
|
||||
mIdParent, // Next highlighted
|
||||
mIdParent // Next selected
|
||||
);
|
||||
|
||||
/*
|
||||
* from:
|
||||
* - Parent
|
||||
* - [Child1]
|
||||
* - Child2
|
||||
*
|
||||
* to:
|
||||
* - [Inbox]*
|
||||
* - Parent
|
||||
*/
|
||||
doCheckWithHighlight(
|
||||
mIdParent, // Current parent
|
||||
mIdChild1, // Current highlighted
|
||||
|
||||
Mailbox.NO_MAILBOX, // Next root
|
||||
mIdInbox, // Next highlighted
|
||||
mIdInbox // Next selected
|
||||
);
|
||||
|
||||
/*
|
||||
* Special case.
|
||||
* Up from root view, with "Parent" highlighted. "Up" will be disabled in this case, but
|
||||
* if we were to run the task, it'd work as if the current parent mailbox is gone.
|
||||
* i.e. just show the top level mailboxes, with Inbox highlighted.
|
||||
*
|
||||
* from:
|
||||
* - Inbox
|
||||
* - [Parent]
|
||||
*
|
||||
* to:
|
||||
* - [Inbox]
|
||||
* - Parent
|
||||
*/
|
||||
doCheckWithHighlight(
|
||||
Mailbox.NO_MAILBOX, // Current parent
|
||||
mIdParent, // Current highlighted
|
||||
|
||||
Mailbox.NO_MAILBOX, // Next root
|
||||
mIdInbox, // Next highlighted
|
||||
mIdInbox // Next selected
|
||||
);
|
||||
|
||||
/*
|
||||
* Special case.
|
||||
* Current parent mailbox is gone. The result should be same as the above.
|
||||
*
|
||||
* from:
|
||||
* (current mailbox just removed)
|
||||
*
|
||||
* to:
|
||||
* - [Inbox]
|
||||
* - Parent
|
||||
*/
|
||||
doCheckWithHighlight(
|
||||
12312234234L, // Current parent
|
||||
mIdParent, // Current highlighted
|
||||
|
||||
Mailbox.NO_MAILBOX, // Next root
|
||||
mIdInbox, // Next highlighted
|
||||
mIdInbox // Next selected
|
||||
);
|
||||
}
|
||||
|
||||
private void doCheckWithHighlight(
|
||||
long parentMailboxId, long highlightedMailboxId,
|
||||
long expectedNextParent, long expectedNextHighlighted, long expectedNextSelected) {
|
||||
doCheck(true, parentMailboxId, highlightedMailboxId,
|
||||
expectedNextParent, expectedNextHighlighted, expectedNextSelected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for one-pane. (highlighting is disable)
|
||||
*/
|
||||
public void testWithNoHighlight() {
|
||||
/*
|
||||
* from:
|
||||
* - Child2
|
||||
* - GChild1
|
||||
* - GChild2
|
||||
*
|
||||
* to:
|
||||
* - Parent
|
||||
* - Child1
|
||||
* - Child2
|
||||
*/
|
||||
doCheckWithNoHighlight(
|
||||
mIdChild2, // Current parent
|
||||
mIdParent // Next root
|
||||
);
|
||||
/*
|
||||
* from:
|
||||
* - Parent
|
||||
* - Child1
|
||||
* - Child2
|
||||
*
|
||||
* to:
|
||||
* - Inbox
|
||||
* - Parent
|
||||
*/
|
||||
doCheckWithNoHighlight(
|
||||
mIdParent, // Current parent
|
||||
Mailbox.NO_MAILBOX // Next root
|
||||
);
|
||||
|
||||
/*
|
||||
* Special case.
|
||||
* Current parent mailbox is gone. The top-level mailboxes should be shown.
|
||||
*
|
||||
* from:
|
||||
* (current mailbox just removed)
|
||||
*
|
||||
* to:
|
||||
* - Inbox
|
||||
* - Parent
|
||||
*/
|
||||
doCheckWithNoHighlight(
|
||||
12312234234L, // Current parent
|
||||
Mailbox.NO_MAILBOX // Next root
|
||||
);
|
||||
}
|
||||
|
||||
private void doCheckWithNoHighlight(long parentMailboxId, long expectedNextParent) {
|
||||
doCheck(false, parentMailboxId, Mailbox.NO_MAILBOX,
|
||||
expectedNextParent, Mailbox.NO_MAILBOX,
|
||||
expectedNextParent /* parent should always be selected */);
|
||||
}
|
||||
|
||||
private void doCheck(boolean enableHighlight,
|
||||
long parentMailboxId, long highlightedMailboxId,
|
||||
long expectedNextParent, long expectedNextHighlighted, long expectedNextSelected) {
|
||||
ResultCallback result = new ResultCallback();
|
||||
|
||||
MailboxListFragment.FindParentMailboxTask task
|
||||
= new MailboxListFragment.FindParentMailboxTask(
|
||||
mProviderContext, null, mAccountId, enableHighlight, parentMailboxId,
|
||||
highlightedMailboxId, result);
|
||||
|
||||
// Can't execute an async task on the test thread, so emulate execution...
|
||||
task.onPostExecute(task.doInBackground((Void[]) null));
|
||||
|
||||
assertEquals("parent", expectedNextParent, result.mNextParentMailboxId);
|
||||
assertEquals("highlighted", expectedNextHighlighted, result.mNextHighlightedMailboxId);
|
||||
assertEquals("selected", expectedNextSelected, result.mNextSelectedMailboxId);
|
||||
}
|
||||
|
||||
private static class ResultCallback
|
||||
implements MailboxListFragment.FindParentMailboxTask.ResultCallback {
|
||||
public long mNextParentMailboxId;
|
||||
public long mNextHighlightedMailboxId;
|
||||
public long mNextSelectedMailboxId;
|
||||
|
||||
@Override
|
||||
public void onResult(long nextParentMailboxId, long nextHighlightedMailboxId,
|
||||
long nextSelectedMailboxId) {
|
||||
mNextParentMailboxId = nextParentMailboxId;
|
||||
mNextHighlightedMailboxId = nextHighlightedMailboxId;
|
||||
mNextSelectedMailboxId = nextSelectedMailboxId;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue