commit
547a87381b
17 changed files with 86 additions and 298 deletions
|
@ -60,7 +60,6 @@ import com.fsck.k9.mail.Flag;
|
|||
import com.fsck.k9.mail.FolderClass;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.MessageDownloadState;
|
||||
import com.fsck.k9.mail.MessageRetrievalListener;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.mail.ServerSettings;
|
||||
|
@ -401,56 +400,22 @@ public class MessagingController {
|
|||
/**
|
||||
* Find all messages in any local account which match the query 'query'
|
||||
*/
|
||||
public void searchLocalMessages(final LocalSearch search, final MessagingListener listener) {
|
||||
threadPool.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
searchLocalMessagesSynchronous(search, listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void searchLocalMessagesSynchronous(final LocalSearch search, final MessagingListener listener) {
|
||||
public List<LocalMessage> searchLocalMessages(final LocalSearch search) {
|
||||
List<Account> searchAccounts = getAccountsFromLocalSearch(search, preferences);
|
||||
|
||||
for (final Account account : searchAccounts) {
|
||||
|
||||
// Collecting statistics of the search result
|
||||
MessageRetrievalListener<LocalMessage> retrievalListener = new MessageRetrievalListener<LocalMessage>() {
|
||||
@Override
|
||||
public void messageStarted(String message, int number, int ofTotal) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messagesFinished(int number) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageFinished(LocalMessage message, int number, int ofTotal) {
|
||||
if (!isMessageSuppressed(message)) {
|
||||
List<LocalMessage> messages = new ArrayList<>();
|
||||
|
||||
messages.add(message);
|
||||
if (listener != null) {
|
||||
listener.listLocalMessagesAddMessages(account, null, messages);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// build and do the query in the localstore
|
||||
for (final Account account : searchAccounts) {
|
||||
try {
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localStore.searchForMessages(retrievalListener, search);
|
||||
List<LocalMessage> localMessages = localStore.searchForMessages(search);
|
||||
|
||||
messages.addAll(localMessages);
|
||||
} catch (Exception e) {
|
||||
Timber.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (listener != null) {
|
||||
listener.listLocalMessagesFinished();
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
public Future<?> searchRemoteMessages(String acctUuid, long folderId, String query, Set<Flag> requiredFlags,
|
||||
|
@ -1070,7 +1035,7 @@ public class MessagingController {
|
|||
Timber.i("Marking all messages in %s:%s as read", account, folderServerId);
|
||||
|
||||
// TODO: Make this one database UPDATE operation
|
||||
List<LocalMessage> messages = localFolder.getMessages(null, false);
|
||||
List<LocalMessage> messages = localFolder.getMessages(false);
|
||||
for (Message message : messages) {
|
||||
if (!message.isSet(Flag.SEEN)) {
|
||||
message.setFlag(Flag.SEEN, true);
|
||||
|
@ -1539,7 +1504,7 @@ public class MessagingController {
|
|||
|
||||
long outboxFolderId = localFolder.getDatabaseId();
|
||||
|
||||
List<LocalMessage> localMessages = localFolder.getMessages(null);
|
||||
List<LocalMessage> localMessages = localFolder.getMessages();
|
||||
int progress = 0;
|
||||
int todo = localMessages.size();
|
||||
for (MessagingListener l : getListeners()) {
|
||||
|
@ -2198,7 +2163,7 @@ public class MessagingController {
|
|||
// Remove all messages marked as deleted
|
||||
folder.destroyDeletedMessages();
|
||||
|
||||
compact(account, null);
|
||||
compact(account);
|
||||
}
|
||||
|
||||
public void emptyTrash(final Account account, MessagingListener listener) {
|
||||
|
@ -2482,22 +2447,14 @@ public class MessagingController {
|
|||
notificationController.clearFetchingMailNotification(account);
|
||||
}
|
||||
|
||||
public void compact(final Account account, final MessagingListener ml) {
|
||||
putBackground("compact:" + account, ml, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
public void compact(Account account) {
|
||||
putBackground("compact:" + account, null, () -> {
|
||||
try {
|
||||
MessageStore messageStore = messageStoreManager.getMessageStore(account);
|
||||
long oldSize = messageStore.getSize();
|
||||
messageStore.compact();
|
||||
long newSize = messageStore.getSize();
|
||||
for (MessagingListener l : getListeners(ml)) {
|
||||
l.accountSizeChanged(account, oldSize, newSize);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Timber.e(e, "Failed to compact account %s", account);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -13,11 +13,6 @@ import com.fsck.k9.mailstore.LocalMessage;
|
|||
|
||||
|
||||
public interface MessagingListener {
|
||||
void accountSizeChanged(Account account, long oldSize, long newSize);
|
||||
|
||||
void listLocalMessagesAddMessages(Account account, String folderServerId, List<LocalMessage> messages);
|
||||
void listLocalMessagesFinished();
|
||||
|
||||
void synchronizeMailboxStarted(Account account, long folderId);
|
||||
void synchronizeMailboxHeadersStarted(Account account, String folderServerId);
|
||||
void synchronizeMailboxHeadersProgress(Account account, String folderServerId, int completed, int total);
|
||||
|
|
|
@ -9,22 +9,9 @@ import android.content.Context;
|
|||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.mailstore.LocalMessage;
|
||||
|
||||
|
||||
public abstract class SimpleMessagingListener implements MessagingListener {
|
||||
@Override
|
||||
public void accountSizeChanged(Account account, long oldSize, long newSize) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listLocalMessagesAddMessages(Account account, String folderServerId, List<LocalMessage> messages) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listLocalMessagesFinished() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void synchronizeMailboxStarted(Account account, long folderId) {
|
||||
}
|
||||
|
|
|
@ -576,17 +576,16 @@ public class LocalFolder {
|
|||
});
|
||||
}
|
||||
|
||||
public List<LocalMessage> getMessages(MessageRetrievalListener<LocalMessage> listener) throws MessagingException {
|
||||
return getMessages(listener, true);
|
||||
public List<LocalMessage> getMessages() throws MessagingException {
|
||||
return getMessages(true);
|
||||
}
|
||||
|
||||
public List<LocalMessage> getMessages(final MessageRetrievalListener<LocalMessage> listener,
|
||||
final boolean includeDeleted) throws MessagingException {
|
||||
public List<LocalMessage> getMessages(final boolean includeDeleted) throws MessagingException {
|
||||
return localStore.getDatabase().execute(false, new DbCallback<List<LocalMessage>>() {
|
||||
@Override
|
||||
public List<LocalMessage> doDbWork(final SQLiteDatabase db) throws MessagingException {
|
||||
open();
|
||||
return LocalFolder.this.localStore.getMessages(listener, LocalFolder.this,
|
||||
return LocalFolder.this.localStore.getMessages(LocalFolder.this,
|
||||
"SELECT " + LocalStore.GET_MESSAGES_COLS +
|
||||
"FROM messages " +
|
||||
"LEFT JOIN message_parts ON (message_parts.id = messages.message_part_id) " +
|
||||
|
@ -898,7 +897,7 @@ public class LocalFolder {
|
|||
public void setFlags(final Set<Flag> flags, boolean value)
|
||||
throws MessagingException {
|
||||
open();
|
||||
for (LocalMessage message : getMessages(null)) {
|
||||
for (LocalMessage message : getMessages()) {
|
||||
message.setFlags(flags, value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ import com.fsck.k9.mail.FetchProfile.Item;
|
|||
import com.fsck.k9.mail.Flag;
|
||||
import com.fsck.k9.mail.FolderClass;
|
||||
import com.fsck.k9.mail.FolderType;
|
||||
import com.fsck.k9.mail.MessageRetrievalListener;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.Multipart;
|
||||
import com.fsck.k9.mail.Part;
|
||||
|
@ -359,9 +358,7 @@ public class LocalStore {
|
|||
});
|
||||
}
|
||||
|
||||
public List<LocalMessage> searchForMessages(MessageRetrievalListener<LocalMessage> retrievalListener,
|
||||
LocalSearch search) throws MessagingException {
|
||||
|
||||
public List<LocalMessage> searchForMessages(LocalSearch search) throws MessagingException {
|
||||
StringBuilder query = new StringBuilder();
|
||||
List<String> queryArgs = new ArrayList<>();
|
||||
SqlQueryBuilder.buildWhereClause(account, search.getConditions(), query, queryArgs);
|
||||
|
@ -382,24 +379,20 @@ public class LocalStore {
|
|||
|
||||
Timber.d("Query = %s", sqlQuery);
|
||||
|
||||
return getMessages(retrievalListener, null, sqlQuery, selectionArgs);
|
||||
return getMessages(null, sqlQuery, selectionArgs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a query string, actually do the query for the messages and
|
||||
* call the MessageRetrievalListener for each one
|
||||
*/
|
||||
List<LocalMessage> getMessages(
|
||||
final MessageRetrievalListener<LocalMessage> listener,
|
||||
final LocalFolder folder,
|
||||
final String queryString, final String[] placeHolders
|
||||
) throws MessagingException {
|
||||
List<LocalMessage> getMessages(LocalFolder folder, String queryString, String[] placeHolders)
|
||||
throws MessagingException {
|
||||
final List<LocalMessage> messages = new ArrayList<>();
|
||||
final int j = database.execute(false, new DbCallback<Integer>() {
|
||||
database.execute(false, new DbCallback<Void>() {
|
||||
@Override
|
||||
public Integer doDbWork(final SQLiteDatabase db) {
|
||||
public Void doDbWork(final SQLiteDatabase db) {
|
||||
Cursor cursor = null;
|
||||
int i = 0;
|
||||
try {
|
||||
cursor = db.rawQuery(queryString + " LIMIT 10", placeHolders);
|
||||
|
||||
|
@ -408,10 +401,6 @@ public class LocalStore {
|
|||
message.populateFromGetMessageCursor(cursor);
|
||||
|
||||
messages.add(message);
|
||||
if (listener != null) {
|
||||
listener.messageFinished(message, i, -1);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
cursor.close();
|
||||
cursor = db.rawQuery(queryString + " LIMIT -1 OFFSET 10", placeHolders);
|
||||
|
@ -421,22 +410,16 @@ public class LocalStore {
|
|||
message.populateFromGetMessageCursor(cursor);
|
||||
|
||||
messages.add(message);
|
||||
if (listener != null) {
|
||||
listener.messageFinished(message, i, -1);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Timber.d(e, "Got an exception");
|
||||
} finally {
|
||||
Utility.closeQuietly(cursor);
|
||||
}
|
||||
return i;
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (listener != null) {
|
||||
listener.messagesFinished(j);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(messages);
|
||||
|
||||
|
@ -448,7 +431,7 @@ public class LocalStore {
|
|||
LocalSearch search = new LocalSearch();
|
||||
search.and(SearchField.THREAD_ID, rootIdString, Attribute.EQUALS);
|
||||
|
||||
return searchForMessages(null, search);
|
||||
return searchForMessages(search);
|
||||
}
|
||||
|
||||
public AttachmentInfo getAttachmentInfo(final String attachmentId) throws MessagingException {
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.mockito.stubbing.Answer;
|
|||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.shadows.ShadowLog;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
|
@ -178,32 +179,17 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void searchLocalMessagesSynchronous_shouldCallSearchForMessagesOnLocalStore()
|
||||
throws Exception {
|
||||
when(search.searchAllAccounts()).thenReturn(true);
|
||||
when(search.getAccountUuids()).thenReturn(new String[0]);
|
||||
|
||||
controller.searchLocalMessagesSynchronous(search, listener);
|
||||
|
||||
verify(localStore).searchForMessages(nullable(MessageRetrievalListener.class), eq(search));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void searchLocalMessagesSynchronous_shouldNotifyWhenStoreFinishesRetrievingAMessage()
|
||||
public void searchLocalMessages_shouldIgnoreExceptions()
|
||||
throws Exception {
|
||||
LocalMessage localMessage = mock(LocalMessage.class);
|
||||
when(localMessage.getFolder()).thenReturn(localFolder);
|
||||
when(search.searchAllAccounts()).thenReturn(true);
|
||||
when(search.getAccountUuids()).thenReturn(new String[0]);
|
||||
when(localStore.searchForMessages(nullable(MessageRetrievalListener.class), eq(search)))
|
||||
.thenThrow(new MessagingException("Test"));
|
||||
when(localStore.searchForMessages(search)).thenThrow(new MessagingException("Test"));
|
||||
|
||||
controller.searchLocalMessagesSynchronous(search, listener);
|
||||
List<LocalMessage> messages = controller.searchLocalMessages(search);
|
||||
|
||||
verify(localStore).searchForMessages(messageRetrievalListenerCaptor.capture(), eq(search));
|
||||
messageRetrievalListenerCaptor.getValue().messageFinished(localMessage, 1, 1);
|
||||
verify(listener).listLocalMessagesAddMessages(eq(account),
|
||||
eq((String) null), eq(Collections.singletonList(localMessage)));
|
||||
assertThat(messages).isEmpty();
|
||||
}
|
||||
|
||||
private void setupRemoteSearch() throws Exception {
|
||||
|
@ -419,7 +405,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
when(localStore.getFolder(SENT_FOLDER_ID)).thenReturn(sentFolder);
|
||||
when(sentFolder.getDatabaseId()).thenReturn(SENT_FOLDER_ID);
|
||||
when(localFolder.exists()).thenReturn(true);
|
||||
when(localFolder.getMessages(null)).thenReturn(Collections.singletonList(localMessageToSend1));
|
||||
when(localFolder.getMessages()).thenReturn(Collections.singletonList(localMessageToSend1));
|
||||
when(localMessageToSend1.getUid()).thenReturn("localMessageToSend1");
|
||||
when(localMessageToSend1.getDatabaseId()).thenReturn(42L);
|
||||
when(localMessageToSend1.getHeader(K9.IDENTITY_HEADER)).thenReturn(new String[]{});
|
||||
|
|
|
@ -478,16 +478,12 @@ public class MessageProvider extends ContentProvider {
|
|||
}
|
||||
|
||||
protected MatrixCursor getMessages(String[] projection) throws InterruptedException {
|
||||
BlockingQueue<List<MessageInfoHolder>> queue = new SynchronousQueue<>();
|
||||
|
||||
// new code for integrated inbox, only execute this once as it will be processed afterwards via the listener
|
||||
SearchAccount integratedInboxAccount = SearchAccount.createUnifiedInboxAccount();
|
||||
MessagingController msgController = MessagingController.getInstance(getContext());
|
||||
|
||||
msgController.searchLocalMessages(integratedInboxAccount.getRelatedSearch(),
|
||||
new MessageInfoHolderRetrieverListener(queue));
|
||||
|
||||
List<MessageInfoHolder> holders = queue.take();
|
||||
List<LocalMessage> messages = msgController.searchLocalMessages(integratedInboxAccount.getRelatedSearch());
|
||||
List<MessageInfoHolder> holders = convertToMessageInfoHolder(messages);
|
||||
|
||||
// TODO add sort order parameter
|
||||
Collections.sort(holders, new ReverseDateComparator());
|
||||
|
@ -521,6 +517,20 @@ public class MessageProvider extends ContentProvider {
|
|||
return cursor;
|
||||
}
|
||||
|
||||
private List<MessageInfoHolder> convertToMessageInfoHolder(List<LocalMessage> messages) {
|
||||
List<MessageInfoHolder> holders = new ArrayList<>();
|
||||
|
||||
Context context = getContext();
|
||||
for (LocalMessage message : messages) {
|
||||
Account messageAccount = message.getAccount();
|
||||
MessageInfoHolder messageInfoHolder = MessageInfoHolder.create(context, message, messageAccount);
|
||||
|
||||
holders.add(messageInfoHolder);
|
||||
}
|
||||
|
||||
return holders;
|
||||
}
|
||||
|
||||
protected LinkedHashMap<String, FieldExtractor<MessageInfoHolder, ?>> resolveMessageExtractors(
|
||||
String[] projection, int count) {
|
||||
LinkedHashMap<String, FieldExtractor<MessageInfoHolder, ?>> extractors = new LinkedHashMap<>();
|
||||
|
@ -1033,38 +1043,4 @@ public class MessageProvider extends ContentProvider {
|
|||
return wrapped;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronized listener used to retrieve {@link MessageInfoHolder}s using a given {@link BlockingQueue}.
|
||||
*/
|
||||
protected class MessageInfoHolderRetrieverListener extends SimpleMessagingListener {
|
||||
private final BlockingQueue<List<MessageInfoHolder>> queue;
|
||||
private List<MessageInfoHolder> holders = new ArrayList<>();
|
||||
|
||||
|
||||
public MessageInfoHolderRetrieverListener(BlockingQueue<List<MessageInfoHolder>> queue) {
|
||||
this.queue = queue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listLocalMessagesAddMessages(Account account, String folderServerId, List<LocalMessage> messages) {
|
||||
Context context = getContext();
|
||||
|
||||
for (LocalMessage message : messages) {
|
||||
Account messageAccount = message.getAccount();
|
||||
MessageInfoHolder messageInfoHolder = MessageInfoHolder.create(context, message, messageAccount);
|
||||
|
||||
holders.add(messageInfoHolder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void listLocalMessagesFinished() {
|
||||
try {
|
||||
queue.put(holders);
|
||||
} catch (InterruptedException e) {
|
||||
Timber.e(e, "Unable to return message list back to caller");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -483,7 +483,7 @@ internal class ImapSync(
|
|||
unsyncedMessages,
|
||||
fetchProfile,
|
||||
object : MessageRetrievalListener<ImapMessage> {
|
||||
override fun messageFinished(message: ImapMessage, number: Int, ofTotal: Int) {
|
||||
override fun messageFinished(message: ImapMessage) {
|
||||
try {
|
||||
if (message.isSet(Flag.DELETED)) {
|
||||
Timber.v(
|
||||
|
@ -509,9 +509,6 @@ internal class ImapSync(
|
|||
Timber.e(e, "Error while storing downloaded message.")
|
||||
}
|
||||
}
|
||||
|
||||
override fun messageStarted(uid: String, number: Int, ofTotal: Int) = Unit
|
||||
override fun messagesFinished(total: Int) = Unit
|
||||
},
|
||||
syncConfig.maximumAutoDownloadMessageSize
|
||||
)
|
||||
|
@ -536,7 +533,7 @@ internal class ImapSync(
|
|||
smallMessages,
|
||||
fetchProfile,
|
||||
object : MessageRetrievalListener<ImapMessage> {
|
||||
override fun messageFinished(message: ImapMessage, number: Int, ofTotal: Int) {
|
||||
override fun messageFinished(message: ImapMessage) {
|
||||
try {
|
||||
// Store the updated message locally
|
||||
backendFolder.saveMessage(message, MessageDownloadState.FULL)
|
||||
|
@ -562,9 +559,6 @@ internal class ImapSync(
|
|||
Timber.e(e, "SYNC: fetch small messages")
|
||||
}
|
||||
}
|
||||
|
||||
override fun messageStarted(uid: String, number: Int, ofTotal: Int) = Unit
|
||||
override fun messagesFinished(total: Int) = Unit
|
||||
},
|
||||
-1
|
||||
)
|
||||
|
|
|
@ -97,7 +97,7 @@ class TestImapFolder(override val serverId: String) : ImapFolder {
|
|||
) {
|
||||
if (messages.isEmpty()) return
|
||||
|
||||
messages.forEachIndexed { index, imapMessage ->
|
||||
for (imapMessage in messages) {
|
||||
val uid = imapMessage.uid.toLong()
|
||||
|
||||
val flags = messageFlags[uid].orEmpty().toSet()
|
||||
|
@ -109,7 +109,7 @@ class TestImapFolder(override val serverId: String) : ImapFolder {
|
|||
}
|
||||
imapMessage.body = storedMessage.body
|
||||
|
||||
listener?.messageFinished(imapMessage, index, messages.size)
|
||||
listener?.messageFinished(imapMessage)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -419,7 +419,7 @@ class Pop3Sync {
|
|||
remoteFolder.fetch(unsyncedMessages, fp,
|
||||
new MessageRetrievalListener<Pop3Message>() {
|
||||
@Override
|
||||
public void messageFinished(Pop3Message message, int number, int ofTotal) {
|
||||
public void messageFinished(Pop3Message message) {
|
||||
try {
|
||||
if (message.isSet(Flag.DELETED) || message.olderThan(earliestDate)) {
|
||||
if (message.isSet(Flag.DELETED)) {
|
||||
|
@ -447,16 +447,6 @@ class Pop3Sync {
|
|||
Timber.e(e, "Error while storing downloaded message.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageStarted(String uid, int number, int ofTotal) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messagesFinished(int total) {
|
||||
// FIXME this method is almost never invoked by various Stores! Don't rely on it unless fixed!!
|
||||
}
|
||||
|
||||
},
|
||||
syncConfig.getMaximumAutoDownloadMessageSize());
|
||||
}
|
||||
|
@ -477,7 +467,7 @@ class Pop3Sync {
|
|||
remoteFolder.fetch(smallMessages,
|
||||
fp, new MessageRetrievalListener<Pop3Message>() {
|
||||
@Override
|
||||
public void messageFinished(final Pop3Message message, int number, int ofTotal) {
|
||||
public void messageFinished(final Pop3Message message) {
|
||||
try {
|
||||
|
||||
// Store the updated message locally
|
||||
|
@ -503,14 +493,6 @@ class Pop3Sync {
|
|||
Timber.e(e, "SYNC: fetch small messages");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageStarted(String uid, int number, int ofTotal) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messagesFinished(int total) {
|
||||
}
|
||||
},
|
||||
-1);
|
||||
|
||||
|
|
|
@ -405,7 +405,7 @@ class WebDavSync {
|
|||
remoteFolder.fetch(unsyncedMessages, fp,
|
||||
new MessageRetrievalListener<WebDavMessage>() {
|
||||
@Override
|
||||
public void messageFinished(WebDavMessage message, int number, int ofTotal) {
|
||||
public void messageFinished(WebDavMessage message) {
|
||||
try {
|
||||
if (message.isSet(Flag.DELETED) || message.olderThan(earliestDate)) {
|
||||
if (message.isSet(Flag.DELETED)) {
|
||||
|
@ -433,16 +433,6 @@ class WebDavSync {
|
|||
Timber.e(e, "Error while storing downloaded message.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageStarted(String uid, int number, int ofTotal) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messagesFinished(int total) {
|
||||
// FIXME this method is almost never invoked by various Stores! Don't rely on it unless fixed!!
|
||||
}
|
||||
|
||||
},
|
||||
syncConfig.getMaximumAutoDownloadMessageSize());
|
||||
}
|
||||
|
@ -463,7 +453,7 @@ class WebDavSync {
|
|||
remoteFolder.fetch(smallMessages,
|
||||
fp, new MessageRetrievalListener<WebDavMessage>() {
|
||||
@Override
|
||||
public void messageFinished(final WebDavMessage message, int number, int ofTotal) {
|
||||
public void messageFinished(final WebDavMessage message) {
|
||||
try {
|
||||
|
||||
// Store the updated message locally
|
||||
|
@ -488,14 +478,6 @@ class WebDavSync {
|
|||
Timber.e(e, "SYNC: fetch small messages");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messageStarted(String uid, int number, int ofTotal) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void messagesFinished(int total) {
|
||||
}
|
||||
},
|
||||
-1);
|
||||
|
||||
|
|
|
@ -3,12 +3,5 @@ package com.fsck.k9.mail;
|
|||
|
||||
|
||||
public interface MessageRetrievalListener<T extends Message> {
|
||||
void messageStarted(String uid, int number, int ofTotal);
|
||||
|
||||
void messageFinished(T message, int number, int ofTotal);
|
||||
|
||||
/**
|
||||
* FIXME <strong>this method is almost never invoked by various Stores! Don't rely on it unless fixed!!</strong>
|
||||
*/
|
||||
void messagesFinished(int total);
|
||||
void messageFinished(T message);
|
||||
}
|
||||
|
|
|
@ -502,12 +502,10 @@ internal class RealImapFolder(
|
|||
// crazy adding stuff at the top.
|
||||
val uids = searchResponse.numbers.sortedDescending()
|
||||
|
||||
val count = uids.size
|
||||
return uids.mapIndexed { index, uidLong ->
|
||||
return uids.map { uidLong ->
|
||||
val uid = uidLong.toString()
|
||||
listener?.messageStarted(uid, index, count)
|
||||
val message = ImapMessage(uid)
|
||||
listener?.messageFinished(message, index, count)
|
||||
listener?.messageFinished(message)
|
||||
|
||||
message
|
||||
}
|
||||
|
@ -572,7 +570,6 @@ internal class RealImapFolder(
|
|||
val command = String.format("UID FETCH %s (%s)", commaSeparatedUids, spaceSeparatedFetchFields)
|
||||
connection!!.sendCommand(command, false)
|
||||
|
||||
var messageNumber = 0
|
||||
var callback: ImapResponseCallback? = null
|
||||
if (fetchProfile.contains(FetchProfile.Item.BODY) ||
|
||||
fetchProfile.contains(FetchProfile.Item.BODY_SANE)
|
||||
|
@ -596,8 +593,6 @@ internal class RealImapFolder(
|
|||
continue
|
||||
}
|
||||
|
||||
listener?.messageStarted(uid, messageNumber++, messageMap.size)
|
||||
|
||||
val literal = handleFetchResponse(message, fetchList)
|
||||
if (literal != null) {
|
||||
when (literal) {
|
||||
|
@ -615,7 +610,7 @@ internal class RealImapFolder(
|
|||
}
|
||||
}
|
||||
|
||||
listener?.messageFinished(message, messageNumber, messageMap.size)
|
||||
listener?.messageFinished(message)
|
||||
} else {
|
||||
handleUntaggedResponse(response)
|
||||
}
|
||||
|
@ -650,7 +645,6 @@ internal class RealImapFolder(
|
|||
val command = String.format("UID FETCH %s (UID %s)", message.uid, fetch)
|
||||
connection!!.sendCommand(command, false)
|
||||
|
||||
var messageNumber = 0
|
||||
val callback: ImapResponseCallback = FetchPartCallback(part, bodyFactory)
|
||||
|
||||
var response: ImapResponse
|
||||
|
@ -668,8 +662,6 @@ internal class RealImapFolder(
|
|||
continue
|
||||
}
|
||||
|
||||
listener?.messageStarted(uid, messageNumber++, 1)
|
||||
|
||||
val literal = handleFetchResponse(message, fetchList)
|
||||
if (literal != null) {
|
||||
when (literal) {
|
||||
|
@ -692,7 +684,7 @@ internal class RealImapFolder(
|
|||
}
|
||||
}
|
||||
|
||||
listener?.messageFinished(message, messageNumber, 1)
|
||||
listener?.messageFinished(message)
|
||||
} else {
|
||||
handleUntaggedResponse(response)
|
||||
}
|
||||
|
|
|
@ -475,8 +475,7 @@ class RealImapFolderTest {
|
|||
|
||||
val messages = folder.getMessages(1, 10, null, listener)
|
||||
|
||||
verify(listener).messageStarted("99", 0, 1)
|
||||
verify(listener).messageFinished(messages[0], 0, 1)
|
||||
verify(listener).messageFinished(messages[0])
|
||||
verifyNoMoreInteractions(listener)
|
||||
}
|
||||
|
||||
|
@ -563,8 +562,7 @@ class RealImapFolderTest {
|
|||
|
||||
val messages = folder.getMessages(setOf(1L), true, listener)
|
||||
|
||||
verify(listener).messageStarted("99", 0, 1)
|
||||
verify(listener).messageFinished(messages[0], 0, 1)
|
||||
verify(listener).messageFinished(messages[0])
|
||||
verifyNoMoreInteractions(listener)
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,6 @@ public class Pop3Folder {
|
|||
throw new MessagingException("getMessages", ioe);
|
||||
}
|
||||
List<Pop3Message> messages = new ArrayList<>();
|
||||
int i = 0;
|
||||
for (int msgNum = start; msgNum <= end; msgNum++) {
|
||||
Pop3Message message = msgNumToMsgMap.get(msgNum);
|
||||
if (message == null) {
|
||||
|
@ -133,12 +132,9 @@ public class Pop3Folder {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (listener != null) {
|
||||
listener.messageStarted(message.getUid(), i++, (end - start) + 1);
|
||||
}
|
||||
messages.add(message);
|
||||
if (listener != null) {
|
||||
listener.messageFinished(message, i++, (end - start) + 1);
|
||||
listener.messageFinished(message);
|
||||
}
|
||||
}
|
||||
return messages;
|
||||
|
@ -317,12 +313,8 @@ public class Pop3Folder {
|
|||
} catch (IOException ioe) {
|
||||
throw new MessagingException("fetch", ioe);
|
||||
}
|
||||
for (int i = 0, count = messages.size(); i < count; i++) {
|
||||
Pop3Message pop3Message = messages.get(i);
|
||||
for (Pop3Message pop3Message : messages) {
|
||||
try {
|
||||
if (listener != null && !fp.contains(FetchProfile.Item.ENVELOPE)) {
|
||||
listener.messageStarted(pop3Message.getUid(), i, count);
|
||||
}
|
||||
if (fp.contains(FetchProfile.Item.BODY)) {
|
||||
fetchBody(pop3Message, -1);
|
||||
} else if (fp.contains(FetchProfile.Item.BODY_SANE)) {
|
||||
|
@ -343,7 +335,7 @@ public class Pop3Folder {
|
|||
pop3Message.setBody(null);
|
||||
}
|
||||
if (listener != null && !(fp.contains(FetchProfile.Item.ENVELOPE) && fp.size() == 1)) {
|
||||
listener.messageFinished(pop3Message, i, count);
|
||||
listener.messageFinished(pop3Message);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
throw new MessagingException("Unable to fetch message", ioe);
|
||||
|
@ -367,11 +359,7 @@ public class Pop3Folder {
|
|||
* In extreme cases we'll do a command per message instead of a bulk request
|
||||
* to hopefully save some time and bandwidth.
|
||||
*/
|
||||
for (int i = 0, count = messages.size(); i < count; i++) {
|
||||
Pop3Message message = messages.get(i);
|
||||
if (listener != null) {
|
||||
listener.messageStarted(message.getUid(), i, count);
|
||||
}
|
||||
for (Pop3Message message : messages) {
|
||||
String response = connection.executeSimpleCommand(
|
||||
String.format(Locale.US, LIST_COMMAND + " %d",
|
||||
uidToMsgNumMap.get(message.getUid())));
|
||||
|
@ -380,7 +368,7 @@ public class Pop3Folder {
|
|||
int msgSize = Integer.parseInt(listParts[2]);
|
||||
message.setSize(msgSize);
|
||||
if (listener != null) {
|
||||
listener.messageFinished(message, i, count);
|
||||
listener.messageFinished(message);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -400,12 +388,9 @@ public class Pop3Folder {
|
|||
int msgSize = Integer.parseInt(listParts[1]);
|
||||
Pop3Message pop3Message = msgNumToMsgMap.get(msgNum);
|
||||
if (pop3Message != null && msgUidIndex.contains(pop3Message.getUid())) {
|
||||
if (listener != null) {
|
||||
listener.messageStarted(pop3Message.getUid(), i, count);
|
||||
}
|
||||
pop3Message.setSize(msgSize);
|
||||
if (listener != null) {
|
||||
listener.messageFinished(pop3Message, i, count);
|
||||
listener.messageFinished(pop3Message);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -207,7 +207,6 @@ public class WebDavFolder {
|
|||
List<WebDavMessage> messages = new ArrayList<>();
|
||||
String[] uids;
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
int uidsLength;
|
||||
|
||||
String messageBody;
|
||||
int prevStart = start;
|
||||
|
@ -232,18 +231,14 @@ public class WebDavFolder {
|
|||
DataSet dataset = store.processRequest(this.mFolderUrl, "SEARCH", messageBody, headers);
|
||||
uids = dataset.getUids();
|
||||
Map<String, String> uidToUrl = dataset.getUidToUrl();
|
||||
uidsLength = uids.length;
|
||||
|
||||
for (int i = 0; i < uidsLength; i++) {
|
||||
if (listener != null) {
|
||||
listener.messageStarted(uids[i], i, uidsLength);
|
||||
}
|
||||
WebDavMessage message = new WebDavMessage(uids[i], this);
|
||||
message.setUrl(uidToUrl.get(uids[i]));
|
||||
for (String uid : uids) {
|
||||
WebDavMessage message = new WebDavMessage(uid, this);
|
||||
message.setUrl(uidToUrl.get(uid));
|
||||
messages.add(message);
|
||||
|
||||
if (listener != null) {
|
||||
listener.messageFinished(message, i, uidsLength);
|
||||
listener.messageFinished(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,14 +304,9 @@ public class WebDavFolder {
|
|||
/**
|
||||
* We can't hand off to processRequest() since we need the stream to parse.
|
||||
*/
|
||||
for (int i = 0, count = messages.size(); i < count; i++) {
|
||||
WebDavMessage wdMessage = messages.get(i);
|
||||
for (WebDavMessage wdMessage : messages) {
|
||||
int statusCode = 0;
|
||||
|
||||
if (listener != null) {
|
||||
listener.messageStarted(wdMessage.getUid(), i, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* If fetch is called outside of the initial list (ie, a locally stored message), it may not have a URL
|
||||
* associated. Verify and fix that
|
||||
|
@ -405,7 +395,7 @@ public class WebDavFolder {
|
|||
}
|
||||
|
||||
if (listener != null) {
|
||||
listener.messageFinished(wdMessage, i, count);
|
||||
listener.messageFinished(wdMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -511,13 +501,7 @@ public class WebDavFolder {
|
|||
|
||||
Map<String, ParsedMessageEnvelope> envelopes = dataset.getMessageEnvelopes();
|
||||
|
||||
int count = messages.size();
|
||||
for (int i = messages.size() - 1; i >= 0; i--) {
|
||||
WebDavMessage message = messages.get(i);
|
||||
if (listener != null) {
|
||||
listener.messageStarted(messages.get(i).getUid(), i, count);
|
||||
}
|
||||
|
||||
for (WebDavMessage message : messages) {
|
||||
ParsedMessageEnvelope envelope = envelopes.get(message.getUid());
|
||||
if (envelope != null) {
|
||||
message.setNewHeaders(envelope);
|
||||
|
@ -527,7 +511,7 @@ public class WebDavFolder {
|
|||
}
|
||||
|
||||
if (listener != null) {
|
||||
listener.messageFinished(messages.get(i), i, count);
|
||||
listener.messageFinished(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -221,8 +221,7 @@ public class WebDavFolderTest {
|
|||
FetchProfile profile = new FetchProfile();
|
||||
profile.add(FetchProfile.Item.BODY_SANE);
|
||||
folder.fetch(messages, profile, listener, MAX_DOWNLOAD_SIZE);
|
||||
verify(listener, times(25)).messageStarted(any(String.class), anyInt(), eq(25));
|
||||
verify(listener, times(25)).messageFinished(any(WebDavMessage.class), anyInt(), eq(25));
|
||||
verify(listener, times(25)).messageFinished(any(WebDavMessage.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -252,8 +251,7 @@ public class WebDavFolderTest {
|
|||
profile.add(FetchProfile.Item.FLAGS);
|
||||
profile.add(FetchProfile.Item.BODY);
|
||||
folder.fetch(messages, profile, listener, MAX_DOWNLOAD_SIZE);
|
||||
verify(listener, times(25)).messageStarted(any(String.class), anyInt(), anyInt());
|
||||
verify(listener, times(25)).messageFinished(any(WebDavMessage.class), anyInt(), anyInt());
|
||||
verify(listener, times(25)).messageFinished(any(WebDavMessage.class));
|
||||
}
|
||||
|
||||
private void setupStoreForMessageFetching() {
|
||||
|
@ -293,8 +291,7 @@ public class WebDavFolderTest {
|
|||
FetchProfile profile = new FetchProfile();
|
||||
profile.add(FetchProfile.Item.BODY_SANE);
|
||||
folder.fetch(messages, profile, listener, MAX_DOWNLOAD_SIZE);
|
||||
verify(listener, times(25)).messageStarted(any(String.class), anyInt(), eq(25));
|
||||
verify(listener, times(25)).messageFinished(any(WebDavMessage.class), anyInt(), eq(25));
|
||||
verify(listener, times(25)).messageFinished(any(WebDavMessage.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -324,8 +321,7 @@ public class WebDavFolderTest {
|
|||
FetchProfile profile = new FetchProfile();
|
||||
profile.add(FetchProfile.Item.BODY_SANE);
|
||||
folder.fetch(messages, profile, listener, MAX_DOWNLOAD_SIZE);
|
||||
verify(listener, times(25)).messageStarted(any(String.class), anyInt(), eq(25));
|
||||
verify(listener, times(25)).messageFinished(any(WebDavMessage.class), anyInt(), eq(25));
|
||||
verify(listener, times(25)).messageFinished(any(WebDavMessage.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -391,8 +387,7 @@ public class WebDavFolderTest {
|
|||
|
||||
folder.getMessages(messageStart, messageEnd, listener);
|
||||
|
||||
verify(listener, times(5)).messageStarted(anyString(), anyInt(), eq(5));
|
||||
verify(listener, times(5)).messageFinished(any(WebDavMessage.class), anyInt(), eq(5));
|
||||
verify(listener, times(5)).messageFinished(any(WebDavMessage.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in a new issue