Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51457a68 authored by cketti's avatar cketti
Browse files

Simplify `LocalStore.searchForMessages()`

parent 4bed7a59
Loading
Loading
Loading
Loading
+6 −33
Original line number Diff line number Diff line
@@ -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,48 +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 messageFinished(LocalMessage message) {
                    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,
+3 −5
Original line number Diff line number Diff line
@@ -359,9 +359,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,7 +380,7 @@ public class LocalStore {

        Timber.d("Query = %s", sqlQuery);

        return getMessages(retrievalListener, null, sqlQuery, selectionArgs);
        return getMessages(null, null, sqlQuery, selectionArgs);
    }

    /*
@@ -443,7 +441,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 {
+5 −19
Original line number Diff line number Diff line
@@ -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);
        verify(listener).listLocalMessagesAddMessages(eq(account),
                eq((String) null), eq(Collections.singletonList(localMessage)));
        assertThat(messages).isEmpty();
    }

    private void setupRemoteSearch() throws Exception {
+16 −40
Original line number Diff line number Diff line
@@ -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");
            }
        }
    }
}