@Test public void searchRemoteMessagesSynchronous_shouldTryAndGetNewMessages() throws Exception { setupRemoteSearch(); controller.searchRemoteMessagesSynchronous("1", FOLDER_ID, FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener); verify(localFolder).getMessage("newMessageUid1"); }
@VisibleForTesting void searchRemoteMessagesSynchronous(final String acctUuid, final String folderId, final String folderName, final String query, final Set<Flag> requiredFlags, final Set<Flag> forbiddenFlags, final MessagingListener listener) { final Account acct = Preferences.getPreferences(context).getAccount(acctUuid); if (listener != null) { listener.remoteSearchStarted(folderId, folderName); } List<Message> extraResults = new ArrayList<>(); try { Store remoteStore = acct.getRemoteStore(); LocalStore localStore = acct.getLocalStore(); if (remoteStore == null || localStore == null) { throw new MessagingException("Could not get store"); } Folder remoteFolder = remoteStore.getFolder(folderId); LocalFolder localFolder = localStore.getFolder(folderId); if (remoteFolder == null || localFolder == null) { throw new MessagingException("Folder not found"); } List<Message> messages = remoteFolder.search(query, requiredFlags, forbiddenFlags); Timber.i("Remote search got %d results", messages.size()); List<Message> remoteMessages = localFolder.extractNewMessages(messages); messages.clear(); if (listener != null) { listener.remoteSearchServerQueryComplete(folderId, folderName, remoteMessages.size(), acct.getRemoteSearchNumResults()); } Collections.sort(remoteMessages, new UidReverseComparator()); int resultLimit = acct.getRemoteSearchNumResults(); if (resultLimit > 0 && remoteMessages.size() > resultLimit) { extraResults = remoteMessages.subList(resultLimit, remoteMessages.size()); remoteMessages = remoteMessages.subList(0, resultLimit); } loadSearchResultsSynchronous(remoteMessages, localFolder, remoteFolder, listener); } catch (Exception e) { if (Thread.currentThread().isInterrupted()) { Timber.i(e, "Caught exception on aborted remote search; safe to ignore."); } else { Timber.e(e, "Could not complete remote search"); if (listener != null) { listener.remoteSearchFailed(null, null, e.getMessage()); } Timber.e(e); } } finally { if (listener != null) { listener.remoteSearchFinished(folderId, folderName, 0, acct.getRemoteSearchNumResults(), extraResults); } } }
MessagingController { @VisibleForTesting void searchRemoteMessagesSynchronous(final String acctUuid, final String folderId, final String folderName, final String query, final Set<Flag> requiredFlags, final Set<Flag> forbiddenFlags, final MessagingListener listener) { final Account acct = Preferences.getPreferences(context).getAccount(acctUuid); if (listener != null) { listener.remoteSearchStarted(folderId, folderName); } List<Message> extraResults = new ArrayList<>(); try { Store remoteStore = acct.getRemoteStore(); LocalStore localStore = acct.getLocalStore(); if (remoteStore == null || localStore == null) { throw new MessagingException("Could not get store"); } Folder remoteFolder = remoteStore.getFolder(folderId); LocalFolder localFolder = localStore.getFolder(folderId); if (remoteFolder == null || localFolder == null) { throw new MessagingException("Folder not found"); } List<Message> messages = remoteFolder.search(query, requiredFlags, forbiddenFlags); Timber.i("Remote search got %d results", messages.size()); List<Message> remoteMessages = localFolder.extractNewMessages(messages); messages.clear(); if (listener != null) { listener.remoteSearchServerQueryComplete(folderId, folderName, remoteMessages.size(), acct.getRemoteSearchNumResults()); } Collections.sort(remoteMessages, new UidReverseComparator()); int resultLimit = acct.getRemoteSearchNumResults(); if (resultLimit > 0 && remoteMessages.size() > resultLimit) { extraResults = remoteMessages.subList(resultLimit, remoteMessages.size()); remoteMessages = remoteMessages.subList(0, resultLimit); } loadSearchResultsSynchronous(remoteMessages, localFolder, remoteFolder, listener); } catch (Exception e) { if (Thread.currentThread().isInterrupted()) { Timber.i(e, "Caught exception on aborted remote search; safe to ignore."); } else { Timber.e(e, "Could not complete remote search"); if (listener != null) { listener.remoteSearchFailed(null, null, e.getMessage()); } Timber.e(e); } } finally { if (listener != null) { listener.remoteSearchFinished(folderId, folderName, 0, acct.getRemoteSearchNumResults(), extraResults); } } } }
MessagingController { @VisibleForTesting void searchRemoteMessagesSynchronous(final String acctUuid, final String folderId, final String folderName, final String query, final Set<Flag> requiredFlags, final Set<Flag> forbiddenFlags, final MessagingListener listener) { final Account acct = Preferences.getPreferences(context).getAccount(acctUuid); if (listener != null) { listener.remoteSearchStarted(folderId, folderName); } List<Message> extraResults = new ArrayList<>(); try { Store remoteStore = acct.getRemoteStore(); LocalStore localStore = acct.getLocalStore(); if (remoteStore == null || localStore == null) { throw new MessagingException("Could not get store"); } Folder remoteFolder = remoteStore.getFolder(folderId); LocalFolder localFolder = localStore.getFolder(folderId); if (remoteFolder == null || localFolder == null) { throw new MessagingException("Folder not found"); } List<Message> messages = remoteFolder.search(query, requiredFlags, forbiddenFlags); Timber.i("Remote search got %d results", messages.size()); List<Message> remoteMessages = localFolder.extractNewMessages(messages); messages.clear(); if (listener != null) { listener.remoteSearchServerQueryComplete(folderId, folderName, remoteMessages.size(), acct.getRemoteSearchNumResults()); } Collections.sort(remoteMessages, new UidReverseComparator()); int resultLimit = acct.getRemoteSearchNumResults(); if (resultLimit > 0 && remoteMessages.size() > resultLimit) { extraResults = remoteMessages.subList(resultLimit, remoteMessages.size()); remoteMessages = remoteMessages.subList(0, resultLimit); } loadSearchResultsSynchronous(remoteMessages, localFolder, remoteFolder, listener); } catch (Exception e) { if (Thread.currentThread().isInterrupted()) { Timber.i(e, "Caught exception on aborted remote search; safe to ignore."); } else { Timber.e(e, "Could not complete remote search"); if (listener != null) { listener.remoteSearchFailed(null, null, e.getMessage()); } Timber.e(e); } } finally { if (listener != null) { listener.remoteSearchFinished(folderId, folderName, 0, acct.getRemoteSearchNumResults(), extraResults); } } } @VisibleForTesting  MessagingController(Context context, NotificationController notificationController,
            Contacts contacts, TransportProvider transportProvider); }
MessagingController { @VisibleForTesting void searchRemoteMessagesSynchronous(final String acctUuid, final String folderId, final String folderName, final String query, final Set<Flag> requiredFlags, final Set<Flag> forbiddenFlags, final MessagingListener listener) { final Account acct = Preferences.getPreferences(context).getAccount(acctUuid); if (listener != null) { listener.remoteSearchStarted(folderId, folderName); } List<Message> extraResults = new ArrayList<>(); try { Store remoteStore = acct.getRemoteStore(); LocalStore localStore = acct.getLocalStore(); if (remoteStore == null || localStore == null) { throw new MessagingException("Could not get store"); } Folder remoteFolder = remoteStore.getFolder(folderId); LocalFolder localFolder = localStore.getFolder(folderId); if (remoteFolder == null || localFolder == null) { throw new MessagingException("Folder not found"); } List<Message> messages = remoteFolder.search(query, requiredFlags, forbiddenFlags); Timber.i("Remote search got %d results", messages.size()); List<Message> remoteMessages = localFolder.extractNewMessages(messages); messages.clear(); if (listener != null) { listener.remoteSearchServerQueryComplete(folderId, folderName, remoteMessages.size(), acct.getRemoteSearchNumResults()); } Collections.sort(remoteMessages, new UidReverseComparator()); int resultLimit = acct.getRemoteSearchNumResults(); if (resultLimit > 0 && remoteMessages.size() > resultLimit) { extraResults = remoteMessages.subList(resultLimit, remoteMessages.size()); remoteMessages = remoteMessages.subList(0, resultLimit); } loadSearchResultsSynchronous(remoteMessages, localFolder, remoteFolder, listener); } catch (Exception e) { if (Thread.currentThread().isInterrupted()) { Timber.i(e, "Caught exception on aborted remote search; safe to ignore."); } else { Timber.e(e, "Could not complete remote search"); if (listener != null) { listener.remoteSearchFailed(null, null, e.getMessage()); } Timber.e(e); } } finally { if (listener != null) { listener.remoteSearchFinished(folderId, folderName, 0, acct.getRemoteSearchNumResults(), extraResults); } } } @VisibleForTesting  MessagingController(Context context, NotificationController notificationController,
            Contacts contacts, TransportProvider transportProvider); static synchronized MessagingController getInstance(Context context); void addListener(MessagingListener listener); void refreshListener(MessagingListener listener); void removeListener(MessagingListener listener); Set<MessagingListener> getListeners(); Set<MessagingListener> getListeners(MessagingListener listener); void listFolders(final Account account, final boolean refreshRemote, final MessagingListener listener); void listSubFolders(final Account account, final String parentFolderId, final boolean refreshRemote, final MessagingListener listener); void listFoldersSynchronous(final Account account, final boolean refreshRemote,
            final MessagingListener listener); void listSubFoldersSynchronous(final Account account, final String parentFolderId, final boolean refreshRemote,
            final MessagingListener listener); void searchLocalMessages(final LocalSearch search, final MessagingListener listener); Future<?> searchRemoteMessages(final String acctUuid, final String folderId, final String folderName, final String query,
            final Set<Flag> requiredFlags, final Set<Flag> forbiddenFlags, final MessagingListener listener); void loadSearchResults(final Account account, final String folderName, final List<Message> messages,
            final MessagingListener listener); void loadMoreMessages(Account account, String folderId, MessagingListener listener); void synchronizeMailbox(final Account account, final String folderId, final String folderName, final MessagingListener listener,
            final Folder providedRemoteFolder); void markAllMessagesRead(final Account account, final String folder); void setFlag(final Account account, final List<Long> messageIds, final Flag flag,
            final boolean newState); void setFlagForThreads(final Account account, final List<Long> threadRootIds,
            final Flag flag, final boolean newState); void setFlag(Account account, String folderId, List<? extends Message> messages, Flag flag,
            boolean newState); void setFlag(Account account, String folderName, String uid, Flag flag,
            boolean newState); void clearAllPending(final Account account); void loadMessageRemotePartial(final Account account, final String folderId,
            final String uid, final MessagingListener listener); void loadMessageRemote(final Account account, final String folderId,
            final String uid, final MessagingListener listener); LocalMessage loadMessage(Account account, String folderId, String uid); void loadAttachment(final Account account, final LocalMessage message, final Part part,
            final MessagingListener listener); void sendMessage(final Account account,
            final Message message,
            MessagingListener listener); void sendPendingMessages(MessagingListener listener); void sendPendingMessages(final Account account,
            MessagingListener listener); void getAccountStats(final Context context, final Account account,
            final MessagingListener listener); void getSearchAccountStats(final SearchAccount searchAccount,
            final MessagingListener listener); AccountStats getSearchAccountStatsSynchronous(final SearchAccount searchAccount,
            final MessagingListener listener); void getFolderUnreadMessageCount(final Account account, final String folderId,
            final MessagingListener l); boolean isMoveCapable(MessageReference messageReference); boolean isCopyCapable(MessageReference message); boolean isMoveCapable(final Account account); boolean isCopyCapable(final Account account); void moveMessages(final Account srcAccount, final String srcFolder,
            List<MessageReference> messageReferences, final String destFolder); void moveMessagesInThread(Account srcAccount, final String srcFolder,
            final List<MessageReference> messageReferences, final String destFolder); void moveMessage(final Account account, final String srcFolder, final MessageReference message,
            final String destFolder); void copyMessages(final Account srcAccount, final String srcFolder,
            final List<MessageReference> messageReferences, final String destFolder); void copyMessagesInThread(Account srcAccount, final String srcFolder,
            final List<MessageReference> messageReferences, final String destFolder); void copyMessage(final Account account, final String srcFolder, final MessageReference message,
            final String destFolder); void expunge(final Account account, final String folder); void deleteDraft(final Account account, long id); void deleteThreads(final List<MessageReference> messages); void deleteMessage(MessageReference message, final MessagingListener listener); void deleteMessages(List<MessageReference> messages, final MessagingListener listener); @SuppressLint("NewApi") // used for debugging only void debugClearMessagesLocally(final List<MessageReference> messages); void emptyTrash(final Account account, MessagingListener listener); void clearFolder(final Account account, final String folderId, final ActivityListener listener); void sendAlternate(Context context, Account account, LocalMessage message); void checkMail(final Context context, final Account account,
            final boolean ignoreLastCheckedTime,
            final boolean useManualWakeLock,
            final MessagingListener listener); void compact(final Account account, final MessagingListener ml); void clear(final Account account, final MessagingListener ml); void recreate(final Account account, final MessagingListener ml); void deleteAccount(Account account); Message saveDraft(final Account account, final Message message, long existingDraftId, boolean saveRemotely); long getId(Message message); MessagingListener getCheckMailListener(); void setCheckMailListener(MessagingListener checkMailListener); Collection<Pusher> getPushers(); boolean setupPushing(final Account account); void stopAllPushing(); void messagesArrived(final Account account, final Folder remoteFolder, final List<Message> messages,
            final boolean flagSyncOnly); void systemStatusChanged(); void cancelNotificationsForAccount(Account account); void cancelNotificationForMessage(Account account, MessageReference messageReference); void clearCertificateErrorNotifications(Account account, CheckDirection direction); void notifyUserIfCertificateProblem(Account account, Exception exception, boolean incoming); }
MessagingController { @VisibleForTesting void searchRemoteMessagesSynchronous(final String acctUuid, final String folderId, final String folderName, final String query, final Set<Flag> requiredFlags, final Set<Flag> forbiddenFlags, final MessagingListener listener) { final Account acct = Preferences.getPreferences(context).getAccount(acctUuid); if (listener != null) { listener.remoteSearchStarted(folderId, folderName); } List<Message> extraResults = new ArrayList<>(); try { Store remoteStore = acct.getRemoteStore(); LocalStore localStore = acct.getLocalStore(); if (remoteStore == null || localStore == null) { throw new MessagingException("Could not get store"); } Folder remoteFolder = remoteStore.getFolder(folderId); LocalFolder localFolder = localStore.getFolder(folderId); if (remoteFolder == null || localFolder == null) { throw new MessagingException("Folder not found"); } List<Message> messages = remoteFolder.search(query, requiredFlags, forbiddenFlags); Timber.i("Remote search got %d results", messages.size()); List<Message> remoteMessages = localFolder.extractNewMessages(messages); messages.clear(); if (listener != null) { listener.remoteSearchServerQueryComplete(folderId, folderName, remoteMessages.size(), acct.getRemoteSearchNumResults()); } Collections.sort(remoteMessages, new UidReverseComparator()); int resultLimit = acct.getRemoteSearchNumResults(); if (resultLimit > 0 && remoteMessages.size() > resultLimit) { extraResults = remoteMessages.subList(resultLimit, remoteMessages.size()); remoteMessages = remoteMessages.subList(0, resultLimit); } loadSearchResultsSynchronous(remoteMessages, localFolder, remoteFolder, listener); } catch (Exception e) { if (Thread.currentThread().isInterrupted()) { Timber.i(e, "Caught exception on aborted remote search; safe to ignore."); } else { Timber.e(e, "Could not complete remote search"); if (listener != null) { listener.remoteSearchFailed(null, null, e.getMessage()); } Timber.e(e); } } finally { if (listener != null) { listener.remoteSearchFinished(folderId, folderName, 0, acct.getRemoteSearchNumResults(), extraResults); } } } @VisibleForTesting  MessagingController(Context context, NotificationController notificationController,
            Contacts contacts, TransportProvider transportProvider); static synchronized MessagingController getInstance(Context context); void addListener(MessagingListener listener); void refreshListener(MessagingListener listener); void removeListener(MessagingListener listener); Set<MessagingListener> getListeners(); Set<MessagingListener> getListeners(MessagingListener listener); void listFolders(final Account account, final boolean refreshRemote, final MessagingListener listener); void listSubFolders(final Account account, final String parentFolderId, final boolean refreshRemote, final MessagingListener listener); void listFoldersSynchronous(final Account account, final boolean refreshRemote,
            final MessagingListener listener); void listSubFoldersSynchronous(final Account account, final String parentFolderId, final boolean refreshRemote,
            final MessagingListener listener); void searchLocalMessages(final LocalSearch search, final MessagingListener listener); Future<?> searchRemoteMessages(final String acctUuid, final String folderId, final String folderName, final String query,
            final Set<Flag> requiredFlags, final Set<Flag> forbiddenFlags, final MessagingListener listener); void loadSearchResults(final Account account, final String folderName, final List<Message> messages,
            final MessagingListener listener); void loadMoreMessages(Account account, String folderId, MessagingListener listener); void synchronizeMailbox(final Account account, final String folderId, final String folderName, final MessagingListener listener,
            final Folder providedRemoteFolder); void markAllMessagesRead(final Account account, final String folder); void setFlag(final Account account, final List<Long> messageIds, final Flag flag,
            final boolean newState); void setFlagForThreads(final Account account, final List<Long> threadRootIds,
            final Flag flag, final boolean newState); void setFlag(Account account, String folderId, List<? extends Message> messages, Flag flag,
            boolean newState); void setFlag(Account account, String folderName, String uid, Flag flag,
            boolean newState); void clearAllPending(final Account account); void loadMessageRemotePartial(final Account account, final String folderId,
            final String uid, final MessagingListener listener); void loadMessageRemote(final Account account, final String folderId,
            final String uid, final MessagingListener listener); LocalMessage loadMessage(Account account, String folderId, String uid); void loadAttachment(final Account account, final LocalMessage message, final Part part,
            final MessagingListener listener); void sendMessage(final Account account,
            final Message message,
            MessagingListener listener); void sendPendingMessages(MessagingListener listener); void sendPendingMessages(final Account account,
            MessagingListener listener); void getAccountStats(final Context context, final Account account,
            final MessagingListener listener); void getSearchAccountStats(final SearchAccount searchAccount,
            final MessagingListener listener); AccountStats getSearchAccountStatsSynchronous(final SearchAccount searchAccount,
            final MessagingListener listener); void getFolderUnreadMessageCount(final Account account, final String folderId,
            final MessagingListener l); boolean isMoveCapable(MessageReference messageReference); boolean isCopyCapable(MessageReference message); boolean isMoveCapable(final Account account); boolean isCopyCapable(final Account account); void moveMessages(final Account srcAccount, final String srcFolder,
            List<MessageReference> messageReferences, final String destFolder); void moveMessagesInThread(Account srcAccount, final String srcFolder,
            final List<MessageReference> messageReferences, final String destFolder); void moveMessage(final Account account, final String srcFolder, final MessageReference message,
            final String destFolder); void copyMessages(final Account srcAccount, final String srcFolder,
            final List<MessageReference> messageReferences, final String destFolder); void copyMessagesInThread(Account srcAccount, final String srcFolder,
            final List<MessageReference> messageReferences, final String destFolder); void copyMessage(final Account account, final String srcFolder, final MessageReference message,
            final String destFolder); void expunge(final Account account, final String folder); void deleteDraft(final Account account, long id); void deleteThreads(final List<MessageReference> messages); void deleteMessage(MessageReference message, final MessagingListener listener); void deleteMessages(List<MessageReference> messages, final MessagingListener listener); @SuppressLint("NewApi") // used for debugging only void debugClearMessagesLocally(final List<MessageReference> messages); void emptyTrash(final Account account, MessagingListener listener); void clearFolder(final Account account, final String folderId, final ActivityListener listener); void sendAlternate(Context context, Account account, LocalMessage message); void checkMail(final Context context, final Account account,
            final boolean ignoreLastCheckedTime,
            final boolean useManualWakeLock,
            final MessagingListener listener); void compact(final Account account, final MessagingListener ml); void clear(final Account account, final MessagingListener ml); void recreate(final Account account, final MessagingListener ml); void deleteAccount(Account account); Message saveDraft(final Account account, final Message message, long existingDraftId, boolean saveRemotely); long getId(Message message); MessagingListener getCheckMailListener(); void setCheckMailListener(MessagingListener checkMailListener); Collection<Pusher> getPushers(); boolean setupPushing(final Account account); void stopAllPushing(); void messagesArrived(final Account account, final Folder remoteFolder, final List<Message> messages,
            final boolean flagSyncOnly); void systemStatusChanged(); void cancelNotificationsForAccount(Account account); void cancelNotificationForMessage(Account account, MessageReference messageReference); void clearCertificateErrorNotifications(Account account, CheckDirection direction); void notifyUserIfCertificateProblem(Account account, Exception exception, boolean incoming); static final long INVALID_MESSAGE_ID; }