Set mailbox flags for message contents

For IMAP, it's possible for a mailbox to exist on the server, but, to be
unselectable. Previously, these folders were never added to the folder list.
However, with nested folder support, we need to have these folders in the
UX so the user can get to its sub-folders (which may be selectable).

Change-Id: I11135fafbb14b40660983804fb86bd223e180d5e
This commit is contained in:
Todd Kennedy 2011-04-26 14:51:29 -07:00
parent 79b97da58c
commit 019341af98
8 changed files with 51 additions and 43 deletions

View File

@ -328,6 +328,11 @@ public class MessagingController implements Runnable {
private void synchronizeMailboxSynchronous(final EmailContent.Account account,
final EmailContent.Mailbox folder) {
mListeners.synchronizeMailboxStarted(account.mId, folder.mId);
if ((folder.mFlags & Mailbox.FLAG_HOLDS_MAIL) == 0) {
// We don't hold messages, so, nothing to synchronize
mListeners.synchronizeMailboxFinished(account.mId, folder.mId, 0, 0);
return;
}
NotificationController nc = NotificationController.getInstance(mContext);
try {
processPendingActionsSynchronous(account);
@ -335,14 +340,7 @@ public class MessagingController implements Runnable {
StoreSynchronizer.SyncResults results;
// Select generic sync or store-specific sync
Store remoteStore = Store.getInstance(account, mContext, null);
StoreSynchronizer customSync = remoteStore.getMessageSynchronizer();
if (customSync == null) {
results = synchronizeMailboxGeneric(account, folder);
} else {
results = customSync.SynchronizeMessagesSynchronous(
account, folder, mListeners, mContext);
}
results = synchronizeMailboxGeneric(account, folder);
mListeners.synchronizeMailboxFinished(account.mId, folder.mId,
results.mTotalMessages,
results.mNewMessages);

View File

@ -76,8 +76,9 @@ import android.widget.TextView;
MailboxListItem listItem = (MailboxListItem)view;
listItem.mMailboxId = id;
listItem.mMailboxType = type;
listItem.mIsValidDropTarget = (id >= 0 || rowType == ROW_TYPE_ALLMAILBOX) &&
!Utility.arrayContains(Mailbox.INVALID_DROP_TARGETS, type);
listItem.mIsValidDropTarget = (id >= 0 || rowType == ROW_TYPE_ALLMAILBOX)
&& !Utility.arrayContains(Mailbox.INVALID_DROP_TARGETS, type)
&& (flags & Mailbox.FLAG_ACCEPTS_MOVED_MAIL) != 0;
listItem.mIsNavigable = hasVisibleChildren || rowType == ROW_TYPE_ALLMAILBOX;
listItem.mAdapter = this;

View File

@ -46,7 +46,8 @@ class MailboxMoveToAdapter extends CursorAdapter {
" AND " + Mailbox.USER_VISIBLE_MAILBOX_SELECTION;
private static final String MOVE_TO_TARGET_MAILBOX_SELECTION =
MailboxColumns.TYPE + " NOT IN (" + Mailbox.TYPE_DRAFTS + "," +
Mailbox.TYPE_OUTBOX + "," + Mailbox.TYPE_SENT + "," + Mailbox.TYPE_TRASH + ")";
Mailbox.TYPE_OUTBOX + "," + Mailbox.TYPE_SENT + "," + Mailbox.TYPE_TRASH + ") AND (" +
MailboxColumns.FLAGS + " & " + Mailbox.FLAG_ACCEPTS_MOVED_MAIL + " != 0)";
/** The main selection to populate the "move to" dialog */
private static final String MOVE_TO_SELECTION =
ALL_MAILBOX_SELECTION + " AND " + MOVE_TO_TARGET_MAILBOX_SELECTION;

View File

@ -21,6 +21,7 @@ import com.android.email.ResourceHelper;
import com.android.email.data.ThrottlingCursorLoader;
import com.android.emailcommon.Logging;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.Mailbox;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
import com.android.emailcommon.utility.TextUtilities;
@ -29,6 +30,7 @@ import com.android.emailcommon.utility.Utility;
import android.content.Context;
import android.content.Loader;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
@ -236,11 +238,19 @@ import java.util.Set;
@Override
public Cursor loadInBackground() {
// Determine the where clause. (Can't do this on the UI thread.)
setSelection(Utility.buildMailboxIdSelection(mContext, mMailboxId));
// Then do a query.
return Utility.CloseTraceCursorWrapper.get(super.loadInBackground());
Cursor returnCursor;
Mailbox box = Mailbox.restoreMailboxWithId(mContext, mMailboxId);
// Only perform a load if the selected mailbox can hold messages
if ((box.mFlags & Mailbox.FLAG_HOLDS_MAIL) != 0) {
// Determine the where clause. (Can't do this on the UI thread.)
setSelection(Utility.buildMailboxIdSelection(mContext, mMailboxId));
// Then do a query to get the cursor
returnCursor = super.loadInBackground();
} else {
// return an empty cursor
returnCursor = new MatrixCursor(getProjection());
}
return Utility.CloseTraceCursorWrapper.get(returnCursor);
}
}
}

View File

@ -355,7 +355,7 @@ public abstract class Store {
* non-EAS accounts are modified.
*/
protected static void updateMailbox(Mailbox mailbox, long accountId, String mailboxPath,
char delimiter, int type) {
char delimiter, boolean selectable, int type) {
mailbox.mAccountKey = accountId;
mailbox.mDelimiter = delimiter;
String displayPath = mailboxPath;
@ -364,7 +364,9 @@ public abstract class Store {
displayPath = mailboxPath.substring(pathIndex + 1);
}
mailbox.mDisplayName = displayPath;
//mailbox.mFlags;
if (selectable) {
mailbox.mFlags = Mailbox.FLAG_HOLDS_MAIL | Mailbox.FLAG_ACCEPTS_MOVED_MAIL;
}
mailbox.mFlagVisible = true;
//mailbox.mParentKey;
//mailbox.mParentServerId;

View File

@ -397,9 +397,10 @@ public class ImapStore extends Store {
* @param accountId The ID of the account the mailbox is to be associated with
* @param mailboxPath The path of the mailbox to add
* @param delimiter A path delimiter. May be {@code null} if there is no delimiter.
* @param selectable If {@code true}, the mailbox can be selected and used to store messages.
*/
private ImapFolder addMailbox(Context context, long accountId, String mailboxPath,
char delimiter) {
char delimiter, boolean selectable) {
ImapFolder folder = (ImapFolder) getFolder(mailboxPath);
Mailbox mailbox = getMailboxForPath(context, accountId, mailboxPath);
if (mailbox.isSaved()) {
@ -407,7 +408,7 @@ public class ImapStore extends Store {
// mailbox retrieved from database; save hash _before_ updating fields
folder.mHash = mailbox.getHashes();
}
updateMailbox(mailbox, accountId, mailboxPath, delimiter,
updateMailbox(mailbox, accountId, mailboxPath, delimiter, selectable,
LegacyConversions.inferMailboxTypeFromName(context, mailboxPath));
if (folder.mHash == null) {
// new mailbox
@ -446,33 +447,28 @@ public class ImapStore extends Store {
for (ImapResponse response : responses) {
// S: * LIST (\Noselect) "/" ~/Mail/foo
if (response.isDataResponse(0, ImapConstants.LIST)) {
boolean includeFolder = true;
// Get folder name.
ImapString encodedFolder = response.getStringOrEmpty(3);
if (encodedFolder.isEmpty()) continue;
String folderName = decodeFolderName(encodedFolder.getString(), mPathPrefix);
if (ImapConstants.INBOX.equalsIgnoreCase(folderName)) {
continue;
}
if (ImapConstants.INBOX.equalsIgnoreCase(folderName)) continue;
// Parse attributes.
if (response.getListOrEmpty(1).contains(ImapConstants.FLAG_NO_SELECT)) {
includeFolder = false;
}
if (includeFolder) {
String delimiter = response.getStringOrEmpty(2).getString();
char delimiterChar = '\0';
if (!TextUtils.isEmpty(delimiter)) {
delimiterChar = delimiter.charAt(0);
}
ImapFolder folder =
addMailbox(mContext, mAccount.mId, folderName, delimiterChar);
mailboxes.put(folderName, folder);
boolean selectable =
!response.getListOrEmpty(1).contains(ImapConstants.FLAG_NO_SELECT);
String delimiter = response.getStringOrEmpty(2).getString();
char delimiterChar = '\0';
if (!TextUtils.isEmpty(delimiter)) {
delimiterChar = delimiter.charAt(0);
}
ImapFolder folder =
addMailbox(mContext, mAccount.mId, folderName, delimiterChar, selectable);
mailboxes.put(folderName, folder);
}
}
Folder newFolder = addMailbox(mContext, mAccount.mId, ImapConstants.INBOX, '\0');
Folder newFolder =
addMailbox(mContext, mAccount.mId, ImapConstants.INBOX, '\0', true /*selectable*/);
mailboxes.put(ImapConstants.INBOX, (ImapFolder)newFolder);
createHierarchy(mailboxes);
saveMailboxList(mContext, mailboxes);

View File

@ -158,7 +158,7 @@ public class Pop3Store extends Store {
@Override
public Folder[] updateFolders() {
Mailbox mailbox = getMailboxForPath(mContext, mAccount.mId, POP3_MAILBOX_NAME);
updateMailbox(mailbox, mAccount.mId, POP3_MAILBOX_NAME, '\0', Mailbox.TYPE_INBOX);
updateMailbox(mailbox, mAccount.mId, POP3_MAILBOX_NAME, '\0', true, Mailbox.TYPE_INBOX);
if (mailbox.isSaved()) {
mailbox.update(mContext, mailbox.toContentValues());
} else {

View File

@ -136,25 +136,25 @@ public class StoreTests extends AndroidTestCase {
public void testUpdateMailbox() {
Mailbox testMailbox = new Mailbox();
Store.updateMailbox(testMailbox, 1L, "inbox", '/', Mailbox.TYPE_MAIL);
Store.updateMailbox(testMailbox, 1L, "inbox", '/', true, Mailbox.TYPE_MAIL);
assertEquals(1L, testMailbox.mAccountKey);
assertEquals("inbox", testMailbox.mDisplayName);
assertEquals("inbox", testMailbox.mServerId);
assertEquals('/', testMailbox.mDelimiter);
Store.updateMailbox(testMailbox, 2L, "inbox/a", '/', Mailbox.TYPE_MAIL);
Store.updateMailbox(testMailbox, 2L, "inbox/a", '/', true, Mailbox.TYPE_MAIL);
assertEquals(2L, testMailbox.mAccountKey);
assertEquals("a", testMailbox.mDisplayName);
assertEquals("inbox/a", testMailbox.mServerId);
assertEquals('/', testMailbox.mDelimiter);
Store.updateMailbox(testMailbox, 3L, "inbox/a/b/c/d", '/', Mailbox.TYPE_MAIL);
Store.updateMailbox(testMailbox, 3L, "inbox/a/b/c/d", '/', true, Mailbox.TYPE_MAIL);
assertEquals(3L, testMailbox.mAccountKey);
assertEquals("d", testMailbox.mDisplayName);
assertEquals("inbox/a/b/c/d", testMailbox.mServerId);
assertEquals('/', testMailbox.mDelimiter);
Store.updateMailbox(testMailbox, 4L, "inbox/a/b/c", '\0', Mailbox.TYPE_MAIL);
Store.updateMailbox(testMailbox, 4L, "inbox/a/b/c", '\0', true, Mailbox.TYPE_MAIL);
assertEquals(4L, testMailbox.mAccountKey);
assertEquals("inbox/a/b/c", testMailbox.mDisplayName);
assertEquals("inbox/a/b/c", testMailbox.mServerId);