Loading app/core/src/main/java/com/fsck/k9/Account.kt +0 −5 Original line number Diff line number Diff line Loading @@ -490,11 +490,6 @@ class Account(override val uuid: String) : BaseAccount { (oldSyncMode != FolderMode.NONE && syncMode == FolderMode.NONE) } @Synchronized fun incrementMessagesNotificationChannelVersion() { messagesNotificationChannelVersion++ } @Synchronized fun isSortAscending(sortType: SortType): Boolean { return sortAscending.getOrPut(sortType) { sortType.isDefaultAscending } Loading app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt +9 −9 Original line number Diff line number Diff line Loading @@ -142,9 +142,11 @@ class AccountPreferenceSerializer( isRingEnabled = storage.getBoolean("$accountUuid.ring", true), ringtone = storage.getString("$accountUuid.ringtone", DEFAULT_RINGTONE_URI), light = getEnumStringPref(storage, "$accountUuid.notificationLight", NotificationLight.Disabled), isVibrateEnabled = storage.getBoolean("$accountUuid.vibrate", false), vibratePattern = VibratePattern.deserialize(storage.getInt("$accountUuid.vibratePattern", 0)), vibrateTimes = storage.getInt("$accountUuid.vibrateTimes", 5) vibration = NotificationVibration( isEnabled = storage.getBoolean("$accountUuid.vibrate", false), pattern = VibratePattern.deserialize(storage.getInt("$accountUuid.vibratePattern", 0)), repeatCount = storage.getInt("$accountUuid.vibrateTimes", 5) ) ) } Loading Loading @@ -322,9 +324,9 @@ class AccountPreferenceSerializer( editor.putBoolean("$accountUuid.markMessageAsReadOnDelete", isMarkMessageAsReadOnDelete) editor.putBoolean("$accountUuid.alwaysShowCcBcc", isAlwaysShowCcBcc) editor.putBoolean("$accountUuid.vibrate", notificationSettings.isVibrateEnabled) editor.putInt("$accountUuid.vibratePattern", notificationSettings.vibratePattern.serialize()) editor.putInt("$accountUuid.vibrateTimes", notificationSettings.vibrateTimes) editor.putBoolean("$accountUuid.vibrate", notificationSettings.vibration.isEnabled) editor.putInt("$accountUuid.vibratePattern", notificationSettings.vibration.pattern.serialize()) editor.putInt("$accountUuid.vibrateTimes", notificationSettings.vibration.repeatCount) editor.putBoolean("$accountUuid.ring", notificationSettings.isRingEnabled) editor.putString("$accountUuid.ringtone", notificationSettings.ringtone) editor.putString("$accountUuid.notificationLight", notificationSettings.light.name) Loading Loading @@ -607,9 +609,7 @@ class AccountPreferenceSerializer( isRingEnabled = true, ringtone = DEFAULT_RINGTONE_URI, light = NotificationLight.Disabled, isVibrateEnabled = false, vibratePattern = VibratePattern.Default, vibrateTimes = 5 vibration = NotificationVibration.DEFAULT ) } Loading app/core/src/main/java/com/fsck/k9/NotificationSettings.kt +2 −57 Original line number Diff line number Diff line Loading @@ -7,60 +7,5 @@ data class NotificationSettings( val isRingEnabled: Boolean = false, val ringtone: String? = null, val light: NotificationLight = NotificationLight.Disabled, val isVibrateEnabled: Boolean = false, val vibratePattern: VibratePattern = VibratePattern.Default, val vibrateTimes: Int = 0 ) { val vibrationPattern: LongArray get() = getVibrationPattern(vibratePattern, vibrateTimes) companion object { fun getVibrationPattern(vibratePattern: VibratePattern, times: Int): LongArray { val selectedPattern = vibratePattern.vibrationPattern val repeatedPattern = LongArray(selectedPattern.size * times) for (n in 0 until times) { System.arraycopy(selectedPattern, 0, repeatedPattern, n * selectedPattern.size, selectedPattern.size) } // Do not wait before starting the vibration pattern. repeatedPattern[0] = 0 return repeatedPattern } } } enum class VibratePattern( /** * These are "off, on" patterns, specified in milliseconds. */ val vibrationPattern: LongArray ) { Default(vibrationPattern = longArrayOf(300, 200)), Pattern1(vibrationPattern = longArrayOf(100, 200)), Pattern2(vibrationPattern = longArrayOf(100, 500)), Pattern3(vibrationPattern = longArrayOf(200, 200)), Pattern4(vibrationPattern = longArrayOf(200, 500)), Pattern5(vibrationPattern = longArrayOf(500, 500)); fun serialize(): Int = when (this) { Default -> 0 Pattern1 -> 1 Pattern2 -> 2 Pattern3 -> 3 Pattern4 -> 4 Pattern5 -> 5 } companion object { fun deserialize(value: Int): VibratePattern = when (value) { 0 -> Default 1 -> Pattern1 2 -> Pattern2 3 -> Pattern3 4 -> Pattern4 5 -> Pattern5 else -> error("Unknown VibratePattern value: $value") } } } val vibration: NotificationVibration = NotificationVibration.DEFAULT ) app/core/src/main/java/com/fsck/k9/NotificationVibration.kt 0 → 100644 +62 −0 Original line number Diff line number Diff line package com.fsck.k9 data class NotificationVibration( val isEnabled: Boolean, val pattern: VibratePattern, val repeatCount: Int ) { val systemPattern: LongArray get() = getSystemPattern(pattern, repeatCount) companion object { val DEFAULT = NotificationVibration(isEnabled = false, pattern = VibratePattern.Default, repeatCount = 5) fun getSystemPattern(vibratePattern: VibratePattern, repeatCount: Int): LongArray { val selectedPattern = vibratePattern.vibrationPattern val repeatedPattern = LongArray(selectedPattern.size * repeatCount) for (n in 0 until repeatCount) { System.arraycopy(selectedPattern, 0, repeatedPattern, n * selectedPattern.size, selectedPattern.size) } // Do not wait before starting the vibration pattern. repeatedPattern[0] = 0 return repeatedPattern } } } enum class VibratePattern( /** * These are "off, on" patterns, specified in milliseconds. */ val vibrationPattern: LongArray ) { Default(vibrationPattern = longArrayOf(300, 200)), Pattern1(vibrationPattern = longArrayOf(100, 200)), Pattern2(vibrationPattern = longArrayOf(100, 500)), Pattern3(vibrationPattern = longArrayOf(200, 200)), Pattern4(vibrationPattern = longArrayOf(200, 500)), Pattern5(vibrationPattern = longArrayOf(500, 500)); fun serialize(): Int = when (this) { Default -> 0 Pattern1 -> 1 Pattern2 -> 2 Pattern3 -> 3 Pattern4 -> 4 Pattern5 -> 5 } companion object { fun deserialize(value: Int): VibratePattern = when (value) { 0 -> Default 1 -> Pattern1 2 -> Pattern2 3 -> Pattern3 4 -> Pattern4 5 -> Pattern5 else -> error("Unknown VibratePattern value: $value") } } } app/core/src/main/java/com/fsck/k9/controller/MessagingController.java +43 −105 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -575,7 +540,7 @@ public class MessagingController { if (localFolder.getVisibleLimit() > 0) { localFolder.setVisibleLimit(localFolder.getVisibleLimit() + account.getDisplayCount()); } synchronizeMailbox(account, folderId, listener); synchronizeMailbox(account, folderId, false, listener); } catch (MessagingException me) { throw new RuntimeException("Unable to set visible limit on folder", me); } Loading @@ -584,9 +549,9 @@ public class MessagingController { /** * Start background synchronization of the specified folder. */ public void synchronizeMailbox(Account account, long folderId, MessagingListener listener) { public void synchronizeMailbox(Account account, long folderId, boolean notify, MessagingListener listener) { putBackground("synchronizeMailbox", listener, () -> synchronizeMailboxSynchronous(account, folderId, listener, new NotificationState()) synchronizeMailboxSynchronous(account, folderId, notify, listener, new NotificationState()) ); } Loading @@ -596,7 +561,7 @@ public class MessagingController { final CountDownLatch latch = new CountDownLatch(1); putBackground("synchronizeMailbox", null, () -> { try { synchronizeMailboxSynchronous(account, folderId, null, new NotificationState()); synchronizeMailboxSynchronous(account, folderId, true, null, new NotificationState()); } finally { latch.countDown(); } Loading @@ -609,19 +574,12 @@ public class MessagingController { } } /** * Start foreground synchronization of the specified folder. This is generally only called * by synchronizeMailbox. * <p> * TODO Break this method up into smaller chunks. */ @VisibleForTesting void synchronizeMailboxSynchronous(Account account, long folderId, MessagingListener listener, NotificationState notificationState) { private void synchronizeMailboxSynchronous(Account account, long folderId, boolean notify, MessagingListener listener, NotificationState notificationState) { refreshFolderListIfStale(account); Backend backend = getBackend(account); syncFolder(account, folderId, listener, backend, notificationState); syncFolder(account, folderId, notify, listener, backend, notificationState); } private void refreshFolderListIfStale(Account account) { Loading @@ -636,7 +594,7 @@ public class MessagingController { } } private void syncFolder(Account account, long folderId, MessagingListener listener, Backend backend, private void syncFolder(Account account, long folderId, boolean notify, MessagingListener listener, Backend backend, NotificationState notificationState) { ServerSettings serverSettings = account.getIncomingServerSettings(); if (serverSettings.isMissingCredentials()) { Loading Loading @@ -667,9 +625,14 @@ public class MessagingController { return; } final boolean suppressNotifications; if (notify) { MessageStore messageStore = messageStoreManager.getMessageStore(account); Long lastChecked = messageStore.getFolder(folderId, FolderDetailsAccessor::getLastChecked); boolean suppressNotifications = lastChecked == null; suppressNotifications = lastChecked == null; } else { suppressNotifications = true; } String folderServerId = localFolder.getServerId(); SyncConfig syncConfig = createSyncConfig(account); Loading Loading @@ -1072,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); Loading Loading @@ -1541,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()) { Loading Loading @@ -2204,7 +2167,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) { Loading Loading @@ -2283,7 +2246,7 @@ public class MessagingController { public boolean performPeriodicMailSync(Account account) { final CountDownLatch latch = new CountDownLatch(1); MutableBoolean syncError = new MutableBoolean(false); checkMail(account, false, false, new SimpleMessagingListener() { checkMail(account, false, false, true, new SimpleMessagingListener() { @Override public void checkMailFinished(Context context, Account account) { latch.countDown(); Loading Loading @@ -2319,10 +2282,8 @@ public class MessagingController { * Checks mail for one or multiple accounts. If account is null all accounts * are checked. */ public void checkMail(final Account account, final boolean ignoreLastCheckedTime, final boolean useManualWakeLock, final MessagingListener listener) { public void checkMail(Account account, boolean ignoreLastCheckedTime, boolean useManualWakeLock, boolean notify, MessagingListener listener) { final WakeLock wakeLock; if (useManualWakeLock) { Loading Loading @@ -2354,7 +2315,7 @@ public class MessagingController { } for (final Account account : accounts) { checkMailForAccount(context, account, ignoreLastCheckedTime, listener); checkMailForAccount(account, ignoreLastCheckedTime, notify, listener); } } catch (Exception e) { Loading @@ -2381,9 +2342,8 @@ public class MessagingController { } private void checkMailForAccount(final Context context, final Account account, final boolean ignoreLastCheckedTime, final MessagingListener listener) { private void checkMailForAccount(Account account, boolean ignoreLastCheckedTime, boolean notify, MessagingListener listener) { Timber.i("Synchronizing account %s", account); NotificationState notificationState = new NotificationState(); Loading @@ -2405,28 +2365,14 @@ public class MessagingController { if (LocalFolder.isModeMismatch(aDisplayMode, fDisplayClass)) { // Never sync a folder that isn't displayed /* if (K9.DEBUG) { Log.v(K9.LOG_TAG, "Not syncing folder " + folder.getName() + " which is in display mode " + fDisplayClass + " while account is in display mode " + aDisplayMode); } */ continue; } if (LocalFolder.isModeMismatch(aSyncMode, fSyncClass)) { // Do not sync folders in the wrong class /* if (K9.DEBUG) { Log.v(K9.LOG_TAG, "Not syncing folder " + folder.getName() + " which is in sync mode " + fSyncClass + " while account is in sync mode " + aSyncMode); } */ continue; } synchronizeFolder(account, folder, ignoreLastCheckedTime, listener, notificationState); synchronizeFolder(account, folder, ignoreLastCheckedTime, notify, listener, notificationState); } } catch (MessagingException e) { Timber.e(e, "Unable to synchronize account %s", account); Loading @@ -2450,14 +2396,14 @@ public class MessagingController { } private void synchronizeFolder(Account account, LocalFolder folder, boolean ignoreLastCheckedTime, MessagingListener listener, NotificationState notificationState) { boolean notify, MessagingListener listener, NotificationState notificationState) { putBackground("sync" + folder.getServerId(), null, () -> { synchronizeFolderInBackground(account, folder, ignoreLastCheckedTime, listener, notificationState); synchronizeFolderInBackground(account, folder, ignoreLastCheckedTime, notify, listener, notificationState); }); } private void synchronizeFolderInBackground(Account account, LocalFolder folder, boolean ignoreLastCheckedTime, MessagingListener listener, NotificationState notificationState) { boolean notify, MessagingListener listener, NotificationState notificationState) { Timber.v("Folder %s was last synced @ %tc", folder.getServerId(), folder.getLastChecked()); if (!ignoreLastCheckedTime) { Loading @@ -2480,7 +2426,7 @@ public class MessagingController { try { showFetchingMailNotificationIfNecessary(account, folder); try { synchronizeMailboxSynchronous(account, folder.getDatabaseId(), listener, notificationState); synchronizeMailboxSynchronous(account, folder.getDatabaseId(), notify, listener, notificationState); } finally { showEmptyFetchingMailNotificationIfNecessary(account); } Loading @@ -2505,22 +2451,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); } } }); } Loading Loading
app/core/src/main/java/com/fsck/k9/Account.kt +0 −5 Original line number Diff line number Diff line Loading @@ -490,11 +490,6 @@ class Account(override val uuid: String) : BaseAccount { (oldSyncMode != FolderMode.NONE && syncMode == FolderMode.NONE) } @Synchronized fun incrementMessagesNotificationChannelVersion() { messagesNotificationChannelVersion++ } @Synchronized fun isSortAscending(sortType: SortType): Boolean { return sortAscending.getOrPut(sortType) { sortType.isDefaultAscending } Loading
app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt +9 −9 Original line number Diff line number Diff line Loading @@ -142,9 +142,11 @@ class AccountPreferenceSerializer( isRingEnabled = storage.getBoolean("$accountUuid.ring", true), ringtone = storage.getString("$accountUuid.ringtone", DEFAULT_RINGTONE_URI), light = getEnumStringPref(storage, "$accountUuid.notificationLight", NotificationLight.Disabled), isVibrateEnabled = storage.getBoolean("$accountUuid.vibrate", false), vibratePattern = VibratePattern.deserialize(storage.getInt("$accountUuid.vibratePattern", 0)), vibrateTimes = storage.getInt("$accountUuid.vibrateTimes", 5) vibration = NotificationVibration( isEnabled = storage.getBoolean("$accountUuid.vibrate", false), pattern = VibratePattern.deserialize(storage.getInt("$accountUuid.vibratePattern", 0)), repeatCount = storage.getInt("$accountUuid.vibrateTimes", 5) ) ) } Loading Loading @@ -322,9 +324,9 @@ class AccountPreferenceSerializer( editor.putBoolean("$accountUuid.markMessageAsReadOnDelete", isMarkMessageAsReadOnDelete) editor.putBoolean("$accountUuid.alwaysShowCcBcc", isAlwaysShowCcBcc) editor.putBoolean("$accountUuid.vibrate", notificationSettings.isVibrateEnabled) editor.putInt("$accountUuid.vibratePattern", notificationSettings.vibratePattern.serialize()) editor.putInt("$accountUuid.vibrateTimes", notificationSettings.vibrateTimes) editor.putBoolean("$accountUuid.vibrate", notificationSettings.vibration.isEnabled) editor.putInt("$accountUuid.vibratePattern", notificationSettings.vibration.pattern.serialize()) editor.putInt("$accountUuid.vibrateTimes", notificationSettings.vibration.repeatCount) editor.putBoolean("$accountUuid.ring", notificationSettings.isRingEnabled) editor.putString("$accountUuid.ringtone", notificationSettings.ringtone) editor.putString("$accountUuid.notificationLight", notificationSettings.light.name) Loading Loading @@ -607,9 +609,7 @@ class AccountPreferenceSerializer( isRingEnabled = true, ringtone = DEFAULT_RINGTONE_URI, light = NotificationLight.Disabled, isVibrateEnabled = false, vibratePattern = VibratePattern.Default, vibrateTimes = 5 vibration = NotificationVibration.DEFAULT ) } Loading
app/core/src/main/java/com/fsck/k9/NotificationSettings.kt +2 −57 Original line number Diff line number Diff line Loading @@ -7,60 +7,5 @@ data class NotificationSettings( val isRingEnabled: Boolean = false, val ringtone: String? = null, val light: NotificationLight = NotificationLight.Disabled, val isVibrateEnabled: Boolean = false, val vibratePattern: VibratePattern = VibratePattern.Default, val vibrateTimes: Int = 0 ) { val vibrationPattern: LongArray get() = getVibrationPattern(vibratePattern, vibrateTimes) companion object { fun getVibrationPattern(vibratePattern: VibratePattern, times: Int): LongArray { val selectedPattern = vibratePattern.vibrationPattern val repeatedPattern = LongArray(selectedPattern.size * times) for (n in 0 until times) { System.arraycopy(selectedPattern, 0, repeatedPattern, n * selectedPattern.size, selectedPattern.size) } // Do not wait before starting the vibration pattern. repeatedPattern[0] = 0 return repeatedPattern } } } enum class VibratePattern( /** * These are "off, on" patterns, specified in milliseconds. */ val vibrationPattern: LongArray ) { Default(vibrationPattern = longArrayOf(300, 200)), Pattern1(vibrationPattern = longArrayOf(100, 200)), Pattern2(vibrationPattern = longArrayOf(100, 500)), Pattern3(vibrationPattern = longArrayOf(200, 200)), Pattern4(vibrationPattern = longArrayOf(200, 500)), Pattern5(vibrationPattern = longArrayOf(500, 500)); fun serialize(): Int = when (this) { Default -> 0 Pattern1 -> 1 Pattern2 -> 2 Pattern3 -> 3 Pattern4 -> 4 Pattern5 -> 5 } companion object { fun deserialize(value: Int): VibratePattern = when (value) { 0 -> Default 1 -> Pattern1 2 -> Pattern2 3 -> Pattern3 4 -> Pattern4 5 -> Pattern5 else -> error("Unknown VibratePattern value: $value") } } } val vibration: NotificationVibration = NotificationVibration.DEFAULT )
app/core/src/main/java/com/fsck/k9/NotificationVibration.kt 0 → 100644 +62 −0 Original line number Diff line number Diff line package com.fsck.k9 data class NotificationVibration( val isEnabled: Boolean, val pattern: VibratePattern, val repeatCount: Int ) { val systemPattern: LongArray get() = getSystemPattern(pattern, repeatCount) companion object { val DEFAULT = NotificationVibration(isEnabled = false, pattern = VibratePattern.Default, repeatCount = 5) fun getSystemPattern(vibratePattern: VibratePattern, repeatCount: Int): LongArray { val selectedPattern = vibratePattern.vibrationPattern val repeatedPattern = LongArray(selectedPattern.size * repeatCount) for (n in 0 until repeatCount) { System.arraycopy(selectedPattern, 0, repeatedPattern, n * selectedPattern.size, selectedPattern.size) } // Do not wait before starting the vibration pattern. repeatedPattern[0] = 0 return repeatedPattern } } } enum class VibratePattern( /** * These are "off, on" patterns, specified in milliseconds. */ val vibrationPattern: LongArray ) { Default(vibrationPattern = longArrayOf(300, 200)), Pattern1(vibrationPattern = longArrayOf(100, 200)), Pattern2(vibrationPattern = longArrayOf(100, 500)), Pattern3(vibrationPattern = longArrayOf(200, 200)), Pattern4(vibrationPattern = longArrayOf(200, 500)), Pattern5(vibrationPattern = longArrayOf(500, 500)); fun serialize(): Int = when (this) { Default -> 0 Pattern1 -> 1 Pattern2 -> 2 Pattern3 -> 3 Pattern4 -> 4 Pattern5 -> 5 } companion object { fun deserialize(value: Int): VibratePattern = when (value) { 0 -> Default 1 -> Pattern1 2 -> Pattern2 3 -> Pattern3 4 -> Pattern4 5 -> Pattern5 else -> error("Unknown VibratePattern value: $value") } } }
app/core/src/main/java/com/fsck/k9/controller/MessagingController.java +43 −105 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -575,7 +540,7 @@ public class MessagingController { if (localFolder.getVisibleLimit() > 0) { localFolder.setVisibleLimit(localFolder.getVisibleLimit() + account.getDisplayCount()); } synchronizeMailbox(account, folderId, listener); synchronizeMailbox(account, folderId, false, listener); } catch (MessagingException me) { throw new RuntimeException("Unable to set visible limit on folder", me); } Loading @@ -584,9 +549,9 @@ public class MessagingController { /** * Start background synchronization of the specified folder. */ public void synchronizeMailbox(Account account, long folderId, MessagingListener listener) { public void synchronizeMailbox(Account account, long folderId, boolean notify, MessagingListener listener) { putBackground("synchronizeMailbox", listener, () -> synchronizeMailboxSynchronous(account, folderId, listener, new NotificationState()) synchronizeMailboxSynchronous(account, folderId, notify, listener, new NotificationState()) ); } Loading @@ -596,7 +561,7 @@ public class MessagingController { final CountDownLatch latch = new CountDownLatch(1); putBackground("synchronizeMailbox", null, () -> { try { synchronizeMailboxSynchronous(account, folderId, null, new NotificationState()); synchronizeMailboxSynchronous(account, folderId, true, null, new NotificationState()); } finally { latch.countDown(); } Loading @@ -609,19 +574,12 @@ public class MessagingController { } } /** * Start foreground synchronization of the specified folder. This is generally only called * by synchronizeMailbox. * <p> * TODO Break this method up into smaller chunks. */ @VisibleForTesting void synchronizeMailboxSynchronous(Account account, long folderId, MessagingListener listener, NotificationState notificationState) { private void synchronizeMailboxSynchronous(Account account, long folderId, boolean notify, MessagingListener listener, NotificationState notificationState) { refreshFolderListIfStale(account); Backend backend = getBackend(account); syncFolder(account, folderId, listener, backend, notificationState); syncFolder(account, folderId, notify, listener, backend, notificationState); } private void refreshFolderListIfStale(Account account) { Loading @@ -636,7 +594,7 @@ public class MessagingController { } } private void syncFolder(Account account, long folderId, MessagingListener listener, Backend backend, private void syncFolder(Account account, long folderId, boolean notify, MessagingListener listener, Backend backend, NotificationState notificationState) { ServerSettings serverSettings = account.getIncomingServerSettings(); if (serverSettings.isMissingCredentials()) { Loading Loading @@ -667,9 +625,14 @@ public class MessagingController { return; } final boolean suppressNotifications; if (notify) { MessageStore messageStore = messageStoreManager.getMessageStore(account); Long lastChecked = messageStore.getFolder(folderId, FolderDetailsAccessor::getLastChecked); boolean suppressNotifications = lastChecked == null; suppressNotifications = lastChecked == null; } else { suppressNotifications = true; } String folderServerId = localFolder.getServerId(); SyncConfig syncConfig = createSyncConfig(account); Loading Loading @@ -1072,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); Loading Loading @@ -1541,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()) { Loading Loading @@ -2204,7 +2167,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) { Loading Loading @@ -2283,7 +2246,7 @@ public class MessagingController { public boolean performPeriodicMailSync(Account account) { final CountDownLatch latch = new CountDownLatch(1); MutableBoolean syncError = new MutableBoolean(false); checkMail(account, false, false, new SimpleMessagingListener() { checkMail(account, false, false, true, new SimpleMessagingListener() { @Override public void checkMailFinished(Context context, Account account) { latch.countDown(); Loading Loading @@ -2319,10 +2282,8 @@ public class MessagingController { * Checks mail for one or multiple accounts. If account is null all accounts * are checked. */ public void checkMail(final Account account, final boolean ignoreLastCheckedTime, final boolean useManualWakeLock, final MessagingListener listener) { public void checkMail(Account account, boolean ignoreLastCheckedTime, boolean useManualWakeLock, boolean notify, MessagingListener listener) { final WakeLock wakeLock; if (useManualWakeLock) { Loading Loading @@ -2354,7 +2315,7 @@ public class MessagingController { } for (final Account account : accounts) { checkMailForAccount(context, account, ignoreLastCheckedTime, listener); checkMailForAccount(account, ignoreLastCheckedTime, notify, listener); } } catch (Exception e) { Loading @@ -2381,9 +2342,8 @@ public class MessagingController { } private void checkMailForAccount(final Context context, final Account account, final boolean ignoreLastCheckedTime, final MessagingListener listener) { private void checkMailForAccount(Account account, boolean ignoreLastCheckedTime, boolean notify, MessagingListener listener) { Timber.i("Synchronizing account %s", account); NotificationState notificationState = new NotificationState(); Loading @@ -2405,28 +2365,14 @@ public class MessagingController { if (LocalFolder.isModeMismatch(aDisplayMode, fDisplayClass)) { // Never sync a folder that isn't displayed /* if (K9.DEBUG) { Log.v(K9.LOG_TAG, "Not syncing folder " + folder.getName() + " which is in display mode " + fDisplayClass + " while account is in display mode " + aDisplayMode); } */ continue; } if (LocalFolder.isModeMismatch(aSyncMode, fSyncClass)) { // Do not sync folders in the wrong class /* if (K9.DEBUG) { Log.v(K9.LOG_TAG, "Not syncing folder " + folder.getName() + " which is in sync mode " + fSyncClass + " while account is in sync mode " + aSyncMode); } */ continue; } synchronizeFolder(account, folder, ignoreLastCheckedTime, listener, notificationState); synchronizeFolder(account, folder, ignoreLastCheckedTime, notify, listener, notificationState); } } catch (MessagingException e) { Timber.e(e, "Unable to synchronize account %s", account); Loading @@ -2450,14 +2396,14 @@ public class MessagingController { } private void synchronizeFolder(Account account, LocalFolder folder, boolean ignoreLastCheckedTime, MessagingListener listener, NotificationState notificationState) { boolean notify, MessagingListener listener, NotificationState notificationState) { putBackground("sync" + folder.getServerId(), null, () -> { synchronizeFolderInBackground(account, folder, ignoreLastCheckedTime, listener, notificationState); synchronizeFolderInBackground(account, folder, ignoreLastCheckedTime, notify, listener, notificationState); }); } private void synchronizeFolderInBackground(Account account, LocalFolder folder, boolean ignoreLastCheckedTime, MessagingListener listener, NotificationState notificationState) { boolean notify, MessagingListener listener, NotificationState notificationState) { Timber.v("Folder %s was last synced @ %tc", folder.getServerId(), folder.getLastChecked()); if (!ignoreLastCheckedTime) { Loading @@ -2480,7 +2426,7 @@ public class MessagingController { try { showFetchingMailNotificationIfNecessary(account, folder); try { synchronizeMailboxSynchronous(account, folder.getDatabaseId(), listener, notificationState); synchronizeMailboxSynchronous(account, folder.getDatabaseId(), notify, listener, notificationState); } finally { showEmptyFetchingMailNotificationIfNecessary(account); } Loading @@ -2505,22 +2451,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); } } }); } Loading