Merge pull request #3744 from k9mail/dumb-account-1
Move logic out of Account class (1)
This commit is contained in:
commit
bb6427cec0
69 changed files with 1293 additions and 1189 deletions
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,598 @@
|
|||
package com.fsck.k9
|
||||
|
||||
import com.fsck.k9.Account.*
|
||||
import com.fsck.k9.helper.Utility
|
||||
import com.fsck.k9.mail.NetworkType
|
||||
import com.fsck.k9.mail.filter.Base64
|
||||
import com.fsck.k9.mailstore.StorageManager
|
||||
import com.fsck.k9.preferences.Storage
|
||||
import com.fsck.k9.preferences.StorageEditor
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
class AccountPreferenceSerializer(
|
||||
private val storageManager: StorageManager,
|
||||
private val resourceProvider: CoreResourceProvider
|
||||
) {
|
||||
|
||||
@Synchronized
|
||||
fun loadAccount(account: Account, storage: Storage) {
|
||||
val accountUuid = account.uuid
|
||||
with (account) {
|
||||
storeUri = Base64.decode(storage.getString("$accountUuid.storeUri", null))
|
||||
localStorageProviderId = storage.getString("$accountUuid.localStorageProvider", storageManager.defaultProviderId)
|
||||
transportUri = Base64.decode(storage.getString("$accountUuid.transportUri", null))
|
||||
description = storage.getString("$accountUuid.description", null)
|
||||
alwaysBcc = storage.getString("$accountUuid.alwaysBcc", alwaysBcc)
|
||||
automaticCheckIntervalMinutes = storage.getInt("$accountUuid.automaticCheckIntervalMinutes", -1)
|
||||
idleRefreshMinutes = storage.getInt("$accountUuid.idleRefreshMinutes", 24)
|
||||
isPushPollOnConnect = storage.getBoolean("$accountUuid.pushPollOnConnect", true)
|
||||
displayCount = storage.getInt("$accountUuid.displayCount", K9.DEFAULT_VISIBLE_LIMIT)
|
||||
if (displayCount < 0) {
|
||||
displayCount = K9.DEFAULT_VISIBLE_LIMIT
|
||||
}
|
||||
latestOldMessageSeenTime = storage.getLong("$accountUuid.latestOldMessageSeenTime", 0)
|
||||
isNotifyNewMail = storage.getBoolean("$accountUuid.notifyNewMail", false)
|
||||
|
||||
folderNotifyNewMailMode = getEnumStringPref<FolderMode>(storage, "$accountUuid.folderNotifyNewMailMode", FolderMode.ALL)
|
||||
isNotifySelfNewMail = storage.getBoolean("$accountUuid.notifySelfNewMail", true)
|
||||
isNotifyContactsMailOnly = storage.getBoolean("$accountUuid.notifyContactsMailOnly", false)
|
||||
isNotifySync = storage.getBoolean("$accountUuid.notifyMailCheck", false)
|
||||
deletePolicy = DeletePolicy.fromInt(storage.getInt("$accountUuid.deletePolicy", DeletePolicy.NEVER.setting))
|
||||
inboxFolder = storage.getString("$accountUuid.inboxFolderName", INBOX)
|
||||
|
||||
val draftsFolder = storage.getString("$accountUuid.draftsFolderName", null)
|
||||
val draftsFolderSelection = getEnumStringPref<SpecialFolderSelection>(storage, "$accountUuid.draftsFolderSelection",
|
||||
SpecialFolderSelection.AUTOMATIC)
|
||||
setDraftsFolder(draftsFolder, draftsFolderSelection)
|
||||
|
||||
val sentFolder = storage.getString("$accountUuid.sentFolderName", null)
|
||||
val sentFolderSelection = getEnumStringPref<SpecialFolderSelection>(storage, "$accountUuid.sentFolderSelection",
|
||||
SpecialFolderSelection.AUTOMATIC)
|
||||
setSentFolder(sentFolder, sentFolderSelection)
|
||||
|
||||
val trashFolder = storage.getString("$accountUuid.trashFolderName", null)
|
||||
val trashFolderSelection = getEnumStringPref<SpecialFolderSelection>(storage, "$accountUuid.trashFolderSelection",
|
||||
SpecialFolderSelection.AUTOMATIC)
|
||||
setTrashFolder(trashFolder, trashFolderSelection)
|
||||
|
||||
val archiveFolder = storage.getString("$accountUuid.archiveFolderName", null)
|
||||
val archiveFolderSelection = getEnumStringPref<SpecialFolderSelection>(storage, "$accountUuid.archiveFolderSelection",
|
||||
SpecialFolderSelection.AUTOMATIC)
|
||||
setArchiveFolder(archiveFolder, archiveFolderSelection)
|
||||
|
||||
val spamFolder = storage.getString("$accountUuid.spamFolderName", null)
|
||||
val spamFolderSelection = getEnumStringPref<SpecialFolderSelection>(storage, "$accountUuid.spamFolderSelection",
|
||||
SpecialFolderSelection.AUTOMATIC)
|
||||
setSpamFolder(spamFolder, spamFolderSelection)
|
||||
|
||||
expungePolicy = getEnumStringPref<Expunge>(storage, "$accountUuid.expungePolicy", Expunge.EXPUNGE_IMMEDIATELY)
|
||||
isSyncRemoteDeletions = storage.getBoolean("$accountUuid.syncRemoteDeletions", true)
|
||||
|
||||
maxPushFolders = storage.getInt("$accountUuid.maxPushFolders", 10)
|
||||
isGoToUnreadMessageSearch = storage.getBoolean("$accountUuid.goToUnreadMessageSearch", false)
|
||||
isSubscribedFoldersOnly = storage.getBoolean("$accountUuid.subscribedFoldersOnly", false)
|
||||
maximumPolledMessageAge = storage.getInt("$accountUuid.maximumPolledMessageAge", -1)
|
||||
maximumAutoDownloadMessageSize = storage.getInt("$accountUuid.maximumAutoDownloadMessageSize", 32768)
|
||||
messageFormat = getEnumStringPref<MessageFormat>(storage, "$accountUuid.messageFormat", DEFAULT_MESSAGE_FORMAT)
|
||||
val messageFormatAuto = storage.getBoolean("$accountUuid.messageFormatAuto", DEFAULT_MESSAGE_FORMAT_AUTO)
|
||||
if (messageFormatAuto && messageFormat == MessageFormat.TEXT) {
|
||||
messageFormat = MessageFormat.AUTO
|
||||
}
|
||||
isMessageReadReceipt = storage.getBoolean("$accountUuid.messageReadReceipt", DEFAULT_MESSAGE_READ_RECEIPT)
|
||||
quoteStyle = getEnumStringPref<QuoteStyle>(storage, "$accountUuid.quoteStyle", DEFAULT_QUOTE_STYLE)
|
||||
quotePrefix = storage.getString("$accountUuid.quotePrefix", DEFAULT_QUOTE_PREFIX)
|
||||
isDefaultQuotedTextShown = storage.getBoolean("$accountUuid.defaultQuotedTextShown", DEFAULT_QUOTED_TEXT_SHOWN)
|
||||
isReplyAfterQuote = storage.getBoolean("$accountUuid.replyAfterQuote", DEFAULT_REPLY_AFTER_QUOTE)
|
||||
isStripSignature = storage.getBoolean("$accountUuid.stripSignature", DEFAULT_STRIP_SIGNATURE)
|
||||
for (type in NetworkType.values()) {
|
||||
val useCompression = storage.getBoolean("$accountUuid.useCompression.$type",
|
||||
true)
|
||||
setCompression(type, useCompression)
|
||||
}
|
||||
|
||||
autoExpandFolder = storage.getString("$accountUuid.autoExpandFolderName", INBOX)
|
||||
|
||||
accountNumber = storage.getInt("$accountUuid.accountNumber", 0)
|
||||
|
||||
chipColor = storage.getInt("$accountUuid.chipColor", FALLBACK_ACCOUNT_COLOR)
|
||||
|
||||
sortType = getEnumStringPref<SortType>(storage, "$accountUuid.sortTypeEnum", SortType.SORT_DATE)
|
||||
|
||||
setSortAscending(sortType, storage.getBoolean("$accountUuid.sortAscending", false))
|
||||
|
||||
showPictures = getEnumStringPref<ShowPictures>(storage, "$accountUuid.showPicturesEnum", ShowPictures.NEVER)
|
||||
|
||||
notificationSetting.setVibrateEnabled(storage.getBoolean("$accountUuid.vibrate", false))
|
||||
notificationSetting.vibratePattern = storage.getInt("$accountUuid.vibratePattern", 0)
|
||||
notificationSetting.vibrateTimes = storage.getInt("$accountUuid.vibrateTimes", 5)
|
||||
notificationSetting.isRingEnabled = storage.getBoolean("$accountUuid.ring", true)
|
||||
notificationSetting.ringtone = storage.getString("$accountUuid.ringtone",
|
||||
"content://settings/system/notification_sound")
|
||||
notificationSetting.setLed(storage.getBoolean("$accountUuid.led", true))
|
||||
notificationSetting.ledColor = storage.getInt("$accountUuid.ledColor", chipColor)
|
||||
|
||||
folderDisplayMode = getEnumStringPref<FolderMode>(storage, "$accountUuid.folderDisplayMode", FolderMode.NOT_SECOND_CLASS)
|
||||
|
||||
folderSyncMode = getEnumStringPref<FolderMode>(storage, "$accountUuid.folderSyncMode", FolderMode.FIRST_CLASS)
|
||||
|
||||
folderPushMode = getEnumStringPref<FolderMode>(storage, "$accountUuid.folderPushMode", FolderMode.FIRST_CLASS)
|
||||
|
||||
folderTargetMode = getEnumStringPref<FolderMode>(storage, "$accountUuid.folderTargetMode", FolderMode.NOT_SECOND_CLASS)
|
||||
|
||||
searchableFolders = getEnumStringPref<Searchable>(storage, "$accountUuid.searchableFolders", Searchable.ALL)
|
||||
|
||||
isSignatureBeforeQuotedText = storage.getBoolean("$accountUuid.signatureBeforeQuotedText", false)
|
||||
identities = loadIdentities(accountUuid, storage)
|
||||
|
||||
openPgpProvider = storage.getString("$accountUuid.openPgpProvider", "")
|
||||
openPgpKey = storage.getLong("$accountUuid.cryptoKey", NO_OPENPGP_KEY)
|
||||
isOpenPgpHideSignOnly = storage.getBoolean("$accountUuid.openPgpHideSignOnly", true)
|
||||
isOpenPgpEncryptSubject = storage.getBoolean("$accountUuid.openPgpEncryptSubject", true)
|
||||
isOpenPgpEncryptAllDrafts = storage.getBoolean("$accountUuid.openPgpEncryptAllDrafts", true)
|
||||
autocryptPreferEncryptMutual = storage.getBoolean("$accountUuid.autocryptMutualMode", false)
|
||||
isAllowRemoteSearch = storage.getBoolean("$accountUuid.allowRemoteSearch", false)
|
||||
isRemoteSearchFullText = storage.getBoolean("$accountUuid.remoteSearchFullText", false)
|
||||
remoteSearchNumResults = storage.getInt("$accountUuid.remoteSearchNumResults", DEFAULT_REMOTE_SEARCH_NUM_RESULTS)
|
||||
isUploadSentMessages = storage.getBoolean("$accountUuid.uploadSentMessages", true)
|
||||
|
||||
isEnabled = storage.getBoolean("$accountUuid.enabled", true)
|
||||
isMarkMessageAsReadOnView = storage.getBoolean("$accountUuid.markMessageAsReadOnView", true)
|
||||
isAlwaysShowCcBcc = storage.getBoolean("$accountUuid.alwaysShowCcBcc", false)
|
||||
|
||||
// Use email address as account description if necessary
|
||||
if (description == null) {
|
||||
description = email
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun loadIdentities(accountUuid: String, storage: Storage): List<Identity> {
|
||||
val newIdentities = ArrayList<Identity>()
|
||||
var ident = 0
|
||||
var gotOne: Boolean
|
||||
do {
|
||||
gotOne = false
|
||||
val name = storage.getString("$accountUuid.$IDENTITY_NAME_KEY.$ident", null)
|
||||
val email = storage.getString("$accountUuid.$IDENTITY_EMAIL_KEY.$ident", null)
|
||||
val signatureUse = storage.getBoolean("$accountUuid.signatureUse.$ident", true)
|
||||
val signature = storage.getString("$accountUuid.signature.$ident", null)
|
||||
val description = storage.getString("$accountUuid.$IDENTITY_DESCRIPTION_KEY.$ident", null)
|
||||
val replyTo = storage.getString("$accountUuid.replyTo.$ident", null)
|
||||
if (email != null) {
|
||||
val identity = Identity()
|
||||
identity.name = name
|
||||
identity.email = email
|
||||
identity.signatureUse = signatureUse
|
||||
identity.signature = signature
|
||||
identity.description = description
|
||||
identity.replyTo = replyTo
|
||||
newIdentities.add(identity)
|
||||
gotOne = true
|
||||
}
|
||||
ident++
|
||||
} while (gotOne)
|
||||
|
||||
if (newIdentities.isEmpty()) {
|
||||
val name = storage.getString("$accountUuid.name", null)
|
||||
val email = storage.getString("$accountUuid.email", null)
|
||||
val signatureUse = storage.getBoolean("$accountUuid.signatureUse", true)
|
||||
val signature = storage.getString("$accountUuid.signature", null)
|
||||
val identity = Identity()
|
||||
identity.name = name
|
||||
identity.email = email
|
||||
identity.signatureUse = signatureUse
|
||||
identity.signature = signature
|
||||
identity.description = email
|
||||
newIdentities.add(identity)
|
||||
}
|
||||
|
||||
return newIdentities
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun save(storage: Storage, editor: StorageEditor, account: Account) {
|
||||
val accountUuid = account.uuid
|
||||
|
||||
if (!storage.getString("accountUuids", "").contains(account.uuid)) {
|
||||
var accountUuids = storage.getString("accountUuids", "")
|
||||
accountUuids += (if (accountUuids.isNotEmpty()) "," else "") + account.uuid
|
||||
editor.putString("accountUuids", accountUuids)
|
||||
}
|
||||
|
||||
with (account) {
|
||||
editor.putString("$accountUuid.storeUri", Base64.encode(storeUri))
|
||||
editor.putString("$accountUuid.localStorageProvider", localStorageProviderId)
|
||||
editor.putString("$accountUuid.transportUri", Base64.encode(transportUri))
|
||||
editor.putString("$accountUuid.description", description)
|
||||
editor.putString("$accountUuid.alwaysBcc", alwaysBcc)
|
||||
editor.putInt("$accountUuid.automaticCheckIntervalMinutes", automaticCheckIntervalMinutes)
|
||||
editor.putInt("$accountUuid.idleRefreshMinutes", idleRefreshMinutes)
|
||||
editor.putBoolean("$accountUuid.pushPollOnConnect", isPushPollOnConnect)
|
||||
editor.putInt("$accountUuid.displayCount", displayCount)
|
||||
editor.putLong("$accountUuid.latestOldMessageSeenTime", latestOldMessageSeenTime)
|
||||
editor.putBoolean("$accountUuid.notifyNewMail", isNotifyNewMail)
|
||||
editor.putString("$accountUuid.folderNotifyNewMailMode", folderNotifyNewMailMode.name)
|
||||
editor.putBoolean("$accountUuid.notifySelfNewMail", isNotifySelfNewMail)
|
||||
editor.putBoolean("$accountUuid.notifyContactsMailOnly", isNotifyContactsMailOnly)
|
||||
editor.putBoolean("$accountUuid.notifyMailCheck", isNotifySync)
|
||||
editor.putInt("$accountUuid.deletePolicy", deletePolicy.setting)
|
||||
editor.putString("$accountUuid.inboxFolderName", inboxFolder)
|
||||
editor.putString("$accountUuid.draftsFolderName", draftsFolder)
|
||||
editor.putString("$accountUuid.sentFolderName", sentFolder)
|
||||
editor.putString("$accountUuid.trashFolderName", trashFolder)
|
||||
editor.putString("$accountUuid.archiveFolderName", archiveFolder)
|
||||
editor.putString("$accountUuid.spamFolderName", spamFolder)
|
||||
editor.putString("$accountUuid.archiveFolderSelection", archiveFolderSelection.name)
|
||||
editor.putString("$accountUuid.draftsFolderSelection", draftsFolderSelection.name)
|
||||
editor.putString("$accountUuid.sentFolderSelection", sentFolderSelection.name)
|
||||
editor.putString("$accountUuid.spamFolderSelection", spamFolderSelection.name)
|
||||
editor.putString("$accountUuid.trashFolderSelection", trashFolderSelection.name)
|
||||
editor.putString("$accountUuid.autoExpandFolderName", autoExpandFolder)
|
||||
editor.putInt("$accountUuid.accountNumber", accountNumber)
|
||||
editor.putString("$accountUuid.sortTypeEnum", sortType.name)
|
||||
editor.putBoolean("$accountUuid.sortAscending", isSortAscending(sortType))
|
||||
editor.putString("$accountUuid.showPicturesEnum", showPictures.name)
|
||||
editor.putString("$accountUuid.folderDisplayMode", folderDisplayMode.name)
|
||||
editor.putString("$accountUuid.folderSyncMode", folderSyncMode.name)
|
||||
editor.putString("$accountUuid.folderPushMode", folderPushMode.name)
|
||||
editor.putString("$accountUuid.folderTargetMode", folderTargetMode.name)
|
||||
editor.putBoolean("$accountUuid.signatureBeforeQuotedText", isSignatureBeforeQuotedText)
|
||||
editor.putString("$accountUuid.expungePolicy", expungePolicy.name)
|
||||
editor.putBoolean("$accountUuid.syncRemoteDeletions", isSyncRemoteDeletions)
|
||||
editor.putInt("$accountUuid.maxPushFolders", maxPushFolders)
|
||||
editor.putString("$accountUuid.searchableFolders", searchableFolders.name)
|
||||
editor.putInt("$accountUuid.chipColor", chipColor)
|
||||
editor.putBoolean("$accountUuid.goToUnreadMessageSearch", isGoToUnreadMessageSearch)
|
||||
editor.putBoolean("$accountUuid.subscribedFoldersOnly", isSubscribedFoldersOnly)
|
||||
editor.putInt("$accountUuid.maximumPolledMessageAge", maximumPolledMessageAge)
|
||||
editor.putInt("$accountUuid.maximumAutoDownloadMessageSize", maximumAutoDownloadMessageSize)
|
||||
val messageFormatAuto = if (Account.MessageFormat.AUTO == messageFormat) {
|
||||
// saving MessageFormat.AUTO as is to the database will cause downgrades to crash on
|
||||
// startup, so we save as MessageFormat.TEXT instead with a separate flag for auto.
|
||||
editor.putString("$accountUuid.messageFormat", Account.MessageFormat.TEXT.name)
|
||||
true
|
||||
} else {
|
||||
editor.putString("$accountUuid.messageFormat", messageFormat.name)
|
||||
false
|
||||
}
|
||||
editor.putBoolean("$accountUuid.messageFormatAuto", messageFormatAuto)
|
||||
editor.putBoolean("$accountUuid.messageReadReceipt", isMessageReadReceipt)
|
||||
editor.putString("$accountUuid.quoteStyle", quoteStyle.name)
|
||||
editor.putString("$accountUuid.quotePrefix", quotePrefix)
|
||||
editor.putBoolean("$accountUuid.defaultQuotedTextShown", isDefaultQuotedTextShown)
|
||||
editor.putBoolean("$accountUuid.replyAfterQuote", isReplyAfterQuote)
|
||||
editor.putBoolean("$accountUuid.stripSignature", isStripSignature)
|
||||
editor.putLong("$accountUuid.cryptoKey", openPgpKey)
|
||||
editor.putBoolean("$accountUuid.openPgpHideSignOnly", isOpenPgpHideSignOnly)
|
||||
editor.putBoolean("$accountUuid.openPgpEncryptSubject", isOpenPgpEncryptSubject)
|
||||
editor.putBoolean("$accountUuid.openPgpEncryptAllDrafts", isOpenPgpEncryptAllDrafts)
|
||||
editor.putString("$accountUuid.openPgpProvider", openPgpProvider)
|
||||
editor.putBoolean("$accountUuid.autocryptMutualMode", autocryptPreferEncryptMutual)
|
||||
editor.putBoolean("$accountUuid.allowRemoteSearch", isAllowRemoteSearch)
|
||||
editor.putBoolean("$accountUuid.remoteSearchFullText", isRemoteSearchFullText)
|
||||
editor.putInt("$accountUuid.remoteSearchNumResults", remoteSearchNumResults)
|
||||
editor.putBoolean("$accountUuid.enabled", isEnabled)
|
||||
editor.putBoolean("$accountUuid.markMessageAsReadOnView", isMarkMessageAsReadOnView)
|
||||
editor.putBoolean("$accountUuid.alwaysShowCcBcc", isAlwaysShowCcBcc)
|
||||
|
||||
editor.putBoolean("$accountUuid.vibrate", notificationSetting.isVibrateEnabled)
|
||||
editor.putInt("$accountUuid.vibratePattern", notificationSetting.vibratePattern)
|
||||
editor.putInt("$accountUuid.vibrateTimes", notificationSetting.vibrateTimes)
|
||||
editor.putBoolean("$accountUuid.ring", notificationSetting.isRingEnabled)
|
||||
editor.putString("$accountUuid.ringtone", notificationSetting.ringtone)
|
||||
editor.putBoolean("$accountUuid.led", notificationSetting.isLedEnabled)
|
||||
editor.putInt("$accountUuid.ledColor", notificationSetting.ledColor)
|
||||
|
||||
for (type in NetworkType.values()) {
|
||||
val useCompression = compressionMap[type]
|
||||
if (useCompression != null) {
|
||||
editor.putBoolean("$accountUuid.useCompression.$type", useCompression)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saveIdentities(account, storage, editor)
|
||||
|
||||
editor.commit()
|
||||
}
|
||||
|
||||
|
||||
@Synchronized
|
||||
fun delete(storage: Storage, account: Account) {
|
||||
val accountUuid = account.uuid
|
||||
|
||||
// Get the list of account UUIDs
|
||||
val uuids = storage.getString("accountUuids", "").split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
|
||||
// Create a list of all account UUIDs excluding this account
|
||||
val newUuids = ArrayList<String>(uuids.size)
|
||||
for (uuid in uuids) {
|
||||
if (uuid != accountUuid) {
|
||||
newUuids.add(uuid)
|
||||
}
|
||||
}
|
||||
|
||||
val editor = storage.edit()
|
||||
|
||||
// Only change the 'accountUuids' value if this account's UUID was listed before
|
||||
if (newUuids.size < uuids.size) {
|
||||
val accountUuids = Utility.combine(newUuids.toTypedArray(), ',')
|
||||
editor.putString("accountUuids", accountUuids)
|
||||
}
|
||||
|
||||
editor.remove("$accountUuid.storeUri")
|
||||
editor.remove("$accountUuid.transportUri")
|
||||
editor.remove("$accountUuid.description")
|
||||
editor.remove("$accountUuid.name")
|
||||
editor.remove("$accountUuid.email")
|
||||
editor.remove("$accountUuid.alwaysBcc")
|
||||
editor.remove("$accountUuid.automaticCheckIntervalMinutes")
|
||||
editor.remove("$accountUuid.pushPollOnConnect")
|
||||
editor.remove("$accountUuid.idleRefreshMinutes")
|
||||
editor.remove("$accountUuid.lastAutomaticCheckTime")
|
||||
editor.remove("$accountUuid.latestOldMessageSeenTime")
|
||||
editor.remove("$accountUuid.notifyNewMail")
|
||||
editor.remove("$accountUuid.notifySelfNewMail")
|
||||
editor.remove("$accountUuid.deletePolicy")
|
||||
editor.remove("$accountUuid.draftsFolderName")
|
||||
editor.remove("$accountUuid.sentFolderName")
|
||||
editor.remove("$accountUuid.trashFolderName")
|
||||
editor.remove("$accountUuid.archiveFolderName")
|
||||
editor.remove("$accountUuid.spamFolderName")
|
||||
editor.remove("$accountUuid.archiveFolderSelection")
|
||||
editor.remove("$accountUuid.draftsFolderSelection")
|
||||
editor.remove("$accountUuid.sentFolderSelection")
|
||||
editor.remove("$accountUuid.spamFolderSelection")
|
||||
editor.remove("$accountUuid.trashFolderSelection")
|
||||
editor.remove("$accountUuid.autoExpandFolderName")
|
||||
editor.remove("$accountUuid.accountNumber")
|
||||
editor.remove("$accountUuid.vibrate")
|
||||
editor.remove("$accountUuid.vibratePattern")
|
||||
editor.remove("$accountUuid.vibrateTimes")
|
||||
editor.remove("$accountUuid.ring")
|
||||
editor.remove("$accountUuid.ringtone")
|
||||
editor.remove("$accountUuid.folderDisplayMode")
|
||||
editor.remove("$accountUuid.folderSyncMode")
|
||||
editor.remove("$accountUuid.folderPushMode")
|
||||
editor.remove("$accountUuid.folderTargetMode")
|
||||
editor.remove("$accountUuid.signatureBeforeQuotedText")
|
||||
editor.remove("$accountUuid.expungePolicy")
|
||||
editor.remove("$accountUuid.syncRemoteDeletions")
|
||||
editor.remove("$accountUuid.maxPushFolders")
|
||||
editor.remove("$accountUuid.searchableFolders")
|
||||
editor.remove("$accountUuid.chipColor")
|
||||
editor.remove("$accountUuid.led")
|
||||
editor.remove("$accountUuid.ledColor")
|
||||
editor.remove("$accountUuid.goToUnreadMessageSearch")
|
||||
editor.remove("$accountUuid.subscribedFoldersOnly")
|
||||
editor.remove("$accountUuid.maximumPolledMessageAge")
|
||||
editor.remove("$accountUuid.maximumAutoDownloadMessageSize")
|
||||
editor.remove("$accountUuid.messageFormatAuto")
|
||||
editor.remove("$accountUuid.quoteStyle")
|
||||
editor.remove("$accountUuid.quotePrefix")
|
||||
editor.remove("$accountUuid.sortTypeEnum")
|
||||
editor.remove("$accountUuid.sortAscending")
|
||||
editor.remove("$accountUuid.showPicturesEnum")
|
||||
editor.remove("$accountUuid.replyAfterQuote")
|
||||
editor.remove("$accountUuid.stripSignature")
|
||||
editor.remove("$accountUuid.cryptoApp") // this is no longer set, but cleans up legacy values
|
||||
editor.remove("$accountUuid.cryptoAutoSignature")
|
||||
editor.remove("$accountUuid.cryptoAutoEncrypt")
|
||||
editor.remove("$accountUuid.cryptoApp")
|
||||
editor.remove("$accountUuid.cryptoKey")
|
||||
editor.remove("$accountUuid.cryptoSupportSignOnly")
|
||||
editor.remove("$accountUuid.openPgpProvider")
|
||||
editor.remove("$accountUuid.openPgpHideSignOnly")
|
||||
editor.remove("$accountUuid.openPgpEncryptSubject")
|
||||
editor.remove("$accountUuid.openPgpEncryptAllDrafts")
|
||||
editor.remove("$accountUuid.autocryptMutualMode")
|
||||
editor.remove("$accountUuid.enabled")
|
||||
editor.remove("$accountUuid.markMessageAsReadOnView")
|
||||
editor.remove("$accountUuid.alwaysShowCcBcc")
|
||||
editor.remove("$accountUuid.allowRemoteSearch")
|
||||
editor.remove("$accountUuid.remoteSearchFullText")
|
||||
editor.remove("$accountUuid.remoteSearchNumResults")
|
||||
editor.remove("$accountUuid.uploadSentMessages")
|
||||
editor.remove("$accountUuid.defaultQuotedTextShown")
|
||||
editor.remove("$accountUuid.displayCount")
|
||||
editor.remove("$accountUuid.inboxFolderName")
|
||||
editor.remove("$accountUuid.localStorageProvider")
|
||||
editor.remove("$accountUuid.messageFormat")
|
||||
editor.remove("$accountUuid.messageReadReceipt")
|
||||
editor.remove("$accountUuid.notifyMailCheck")
|
||||
for (type in NetworkType.values()) {
|
||||
editor.remove("$accountUuid.useCompression." + type.name)
|
||||
}
|
||||
deleteIdentities(account, storage, editor)
|
||||
// TODO: Remove preference settings that may exist for individual folders in the account.
|
||||
editor.commit()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun saveIdentities(account: Account, storage: Storage, editor: StorageEditor) {
|
||||
deleteIdentities(account, storage, editor)
|
||||
var ident = 0
|
||||
|
||||
with (account) {
|
||||
for (identity in identities) {
|
||||
editor.putString("$uuid.$IDENTITY_NAME_KEY.$ident", identity.name)
|
||||
editor.putString("$uuid.$IDENTITY_EMAIL_KEY.$ident", identity.email)
|
||||
editor.putBoolean("$uuid.signatureUse.$ident", identity.signatureUse)
|
||||
editor.putString("$uuid.signature.$ident", identity.signature)
|
||||
editor.putString("$uuid.$IDENTITY_DESCRIPTION_KEY.$ident", identity.description)
|
||||
editor.putString("$uuid.replyTo.$ident", identity.replyTo)
|
||||
ident++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun deleteIdentities(account: Account, storage: Storage, editor: StorageEditor) {
|
||||
val accountUuid = account.uuid
|
||||
|
||||
var identityIndex = 0
|
||||
var gotOne: Boolean
|
||||
do {
|
||||
gotOne = false
|
||||
val email = storage.getString("$accountUuid.$IDENTITY_EMAIL_KEY.$identityIndex", null)
|
||||
if (email != null) {
|
||||
editor.remove("$accountUuid.$IDENTITY_NAME_KEY.$identityIndex")
|
||||
editor.remove("$accountUuid.$IDENTITY_EMAIL_KEY.$identityIndex")
|
||||
editor.remove("$accountUuid.signatureUse.$identityIndex")
|
||||
editor.remove("$accountUuid.signature.$identityIndex")
|
||||
editor.remove("$accountUuid.$IDENTITY_DESCRIPTION_KEY.$identityIndex")
|
||||
editor.remove("$accountUuid.replyTo.$identityIndex")
|
||||
gotOne = true
|
||||
}
|
||||
identityIndex++
|
||||
} while (gotOne)
|
||||
}
|
||||
|
||||
fun move(account: Account, storage: Storage, moveUp: Boolean) {
|
||||
val uuids = storage.getString("accountUuids", "").split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
val editor = storage.edit()
|
||||
val newUuids = arrayOfNulls<String>(uuids.size)
|
||||
if (moveUp) {
|
||||
for (i in uuids.indices) {
|
||||
if (i > 0 && uuids[i] == account.uuid) {
|
||||
newUuids[i] = newUuids[i - 1]
|
||||
newUuids[i - 1] = account.uuid
|
||||
} else {
|
||||
newUuids[i] = uuids[i]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i in uuids.indices.reversed()) {
|
||||
if (i < uuids.size - 1 && uuids[i] == account.uuid) {
|
||||
newUuids[i] = newUuids[i + 1]
|
||||
newUuids[i + 1] = account.uuid
|
||||
} else {
|
||||
newUuids[i] = uuids[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
val accountUuids = Utility.combine(newUuids, ',')
|
||||
editor.putString("accountUuids", accountUuids)
|
||||
editor.commit()
|
||||
}
|
||||
|
||||
private fun <T : Enum<T>> getEnumStringPref(storage: Storage, key: String, defaultEnum: T): T {
|
||||
val stringPref = storage.getString(key, null)
|
||||
|
||||
return if (stringPref == null) {
|
||||
defaultEnum
|
||||
} else {
|
||||
try {
|
||||
java.lang.Enum.valueOf<T>(defaultEnum.declaringClass, stringPref)
|
||||
} catch (ex: IllegalArgumentException) {
|
||||
Timber.w(ex, "Unable to convert preference key [%s] value [%s] to enum of type %s",
|
||||
key, stringPref, defaultEnum.declaringClass)
|
||||
|
||||
defaultEnum
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun loadDefaults(account: Account) {
|
||||
with (account) {
|
||||
localStorageProviderId = storageManager.defaultProviderId
|
||||
automaticCheckIntervalMinutes = -1
|
||||
idleRefreshMinutes = 24
|
||||
isPushPollOnConnect = true
|
||||
displayCount = K9.DEFAULT_VISIBLE_LIMIT
|
||||
accountNumber = -1
|
||||
isNotifyNewMail = true
|
||||
folderNotifyNewMailMode = FolderMode.ALL
|
||||
isNotifySync = true
|
||||
isNotifySelfNewMail = true
|
||||
isNotifyContactsMailOnly = false
|
||||
folderDisplayMode = FolderMode.NOT_SECOND_CLASS
|
||||
folderSyncMode = FolderMode.FIRST_CLASS
|
||||
folderPushMode = FolderMode.FIRST_CLASS
|
||||
folderTargetMode = FolderMode.NOT_SECOND_CLASS
|
||||
sortType = DEFAULT_SORT_TYPE
|
||||
setSortAscending(DEFAULT_SORT_TYPE, DEFAULT_SORT_ASCENDING)
|
||||
showPictures = ShowPictures.NEVER
|
||||
isSignatureBeforeQuotedText = false
|
||||
expungePolicy = Expunge.EXPUNGE_IMMEDIATELY
|
||||
autoExpandFolder = INBOX
|
||||
inboxFolder = INBOX
|
||||
maxPushFolders = 10
|
||||
isGoToUnreadMessageSearch = false
|
||||
isSubscribedFoldersOnly = false
|
||||
maximumPolledMessageAge = -1
|
||||
maximumAutoDownloadMessageSize = 32768
|
||||
messageFormat = DEFAULT_MESSAGE_FORMAT
|
||||
isMessageFormatAuto = DEFAULT_MESSAGE_FORMAT_AUTO
|
||||
isMessageReadReceipt = DEFAULT_MESSAGE_READ_RECEIPT
|
||||
quoteStyle = DEFAULT_QUOTE_STYLE
|
||||
quotePrefix = DEFAULT_QUOTE_PREFIX
|
||||
isDefaultQuotedTextShown = DEFAULT_QUOTED_TEXT_SHOWN
|
||||
isReplyAfterQuote = DEFAULT_REPLY_AFTER_QUOTE
|
||||
isStripSignature = DEFAULT_STRIP_SIGNATURE
|
||||
isSyncRemoteDeletions = true
|
||||
openPgpKey = NO_OPENPGP_KEY
|
||||
isAllowRemoteSearch = false
|
||||
isRemoteSearchFullText = false
|
||||
remoteSearchNumResults = DEFAULT_REMOTE_SEARCH_NUM_RESULTS
|
||||
isUploadSentMessages = true
|
||||
isEnabled = true
|
||||
isMarkMessageAsReadOnView = true
|
||||
isAlwaysShowCcBcc = false
|
||||
|
||||
setArchiveFolder(null, SpecialFolderSelection.AUTOMATIC)
|
||||
setDraftsFolder(null, SpecialFolderSelection.AUTOMATIC)
|
||||
setSentFolder(null, SpecialFolderSelection.AUTOMATIC)
|
||||
setSpamFolder(null, SpecialFolderSelection.AUTOMATIC)
|
||||
setTrashFolder(null, SpecialFolderSelection.AUTOMATIC)
|
||||
setArchiveFolder(null, SpecialFolderSelection.AUTOMATIC)
|
||||
|
||||
searchableFolders = Searchable.ALL
|
||||
|
||||
identities = ArrayList<Identity>()
|
||||
|
||||
val identity = Identity().apply {
|
||||
signatureUse = true
|
||||
signature = resourceProvider.defaultSignature()
|
||||
description = resourceProvider.defaultIdentityDescription()
|
||||
}
|
||||
identities.add(identity)
|
||||
|
||||
with (notificationSetting) {
|
||||
isVibrateEnabled = false
|
||||
vibratePattern = 0
|
||||
vibrateTimes = 5
|
||||
isRingEnabled = true
|
||||
ringtone = "content://settings/system/notification_sound"
|
||||
ledColor = chipColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ACCOUNT_DESCRIPTION_KEY = "description"
|
||||
const val STORE_URI_KEY = "storeUri"
|
||||
const val TRANSPORT_URI_KEY = "transportUri"
|
||||
|
||||
const val IDENTITY_NAME_KEY = "name"
|
||||
const val IDENTITY_EMAIL_KEY = "email"
|
||||
const val IDENTITY_DESCRIPTION_KEY = "description"
|
||||
|
||||
const val FALLBACK_ACCOUNT_COLOR = 0x0099CC
|
||||
|
||||
@JvmField
|
||||
val DEFAULT_MESSAGE_FORMAT = MessageFormat.HTML
|
||||
@JvmField
|
||||
val DEFAULT_QUOTE_STYLE = QuoteStyle.PREFIX
|
||||
const val DEFAULT_MESSAGE_FORMAT_AUTO = false
|
||||
const val DEFAULT_MESSAGE_READ_RECEIPT = false
|
||||
const val DEFAULT_QUOTE_PREFIX = ">"
|
||||
const val DEFAULT_QUOTED_TEXT_SHOWN = true
|
||||
const val DEFAULT_REPLY_AFTER_QUOTE = false
|
||||
const val DEFAULT_STRIP_SIGNATURE = true
|
||||
const val DEFAULT_REMOTE_SEARCH_NUM_RESULTS = 25
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ import com.fsck.k9.message.html.htmlModule
|
|||
import com.fsck.k9.message.quote.quoteModule
|
||||
import com.fsck.k9.notification.coreNotificationModule
|
||||
import com.fsck.k9.power.DeviceIdleManager
|
||||
import com.fsck.k9.search.searchModule
|
||||
import com.fsck.k9.service.BootReceiver
|
||||
import com.fsck.k9.service.MailService
|
||||
import com.fsck.k9.service.ShutdownReceiver
|
||||
|
@ -39,6 +40,7 @@ object Core : KoinComponent {
|
|||
openPgpModule,
|
||||
autocryptModule,
|
||||
mailStoreModule,
|
||||
searchModule,
|
||||
extractorModule,
|
||||
htmlModule,
|
||||
quoteModule,
|
||||
|
|
|
@ -382,7 +382,7 @@ public class K9 {
|
|||
for (Account account : preferences.getAccounts()) {
|
||||
account.setOpenPgpProvider(openPgpProvider);
|
||||
account.setOpenPgpHideSignOnly(!openPgpSupportSignOnly);
|
||||
account.save(preferences);
|
||||
preferences.saveAccount(account);
|
||||
}
|
||||
|
||||
storage.edit()
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.fsck.k9
|
|||
import android.content.Context
|
||||
import com.fsck.k9.helper.Contacts
|
||||
import com.fsck.k9.mail.power.PowerManager
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider
|
||||
import com.fsck.k9.mailstore.StorageManager
|
||||
import com.fsck.k9.power.TracingPowerManager
|
||||
import org.koin.dsl.module.applicationContext
|
||||
|
@ -11,6 +12,7 @@ val mainModule = applicationContext {
|
|||
bean { Preferences.getPreferences(get()) }
|
||||
bean { get<Context>().resources }
|
||||
bean { StorageManager.getInstance(get()) }
|
||||
bean { LocalStoreProvider() }
|
||||
bean { TracingPowerManager.getPowerManager(get()) as PowerManager }
|
||||
bean { Contacts.getInstance(get()) }
|
||||
}
|
||||
|
|
65
app/core/src/main/java/com/fsck/k9/LocalKeyStoreManager.kt
Normal file
65
app/core/src/main/java/com/fsck/k9/LocalKeyStoreManager.kt
Normal file
|
@ -0,0 +1,65 @@
|
|||
package com.fsck.k9
|
||||
|
||||
import android.net.Uri
|
||||
import com.fsck.k9.mail.MailServerDirection
|
||||
import com.fsck.k9.mail.ssl.LocalKeyStore
|
||||
import java.security.cert.CertificateException
|
||||
import java.security.cert.X509Certificate
|
||||
|
||||
class LocalKeyStoreManager(
|
||||
val localKeyStore: LocalKeyStore
|
||||
) {
|
||||
/**
|
||||
* Add a new certificate for the incoming or outgoing server to the local key store.
|
||||
*/
|
||||
@Throws(CertificateException::class)
|
||||
fun addCertificate(account: Account, direction: MailServerDirection, certificate: X509Certificate) {
|
||||
val uri: Uri
|
||||
if (direction === MailServerDirection.INCOMING) {
|
||||
uri = Uri.parse(account.storeUri)
|
||||
} else {
|
||||
uri = Uri.parse(account.transportUri)
|
||||
}
|
||||
localKeyStore.addCertificate(uri.host, uri.port, certificate)
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine the existing settings for an account. If the old host/port is different from the
|
||||
* new host/port, then try and delete any (possibly non-existent) certificate stored for the
|
||||
* old host/port.
|
||||
*/
|
||||
fun deleteCertificate(account: Account, newHost: String, newPort: Int, direction: MailServerDirection) {
|
||||
val uri: Uri
|
||||
if (direction === MailServerDirection.INCOMING) {
|
||||
uri = Uri.parse(account.storeUri)
|
||||
} else {
|
||||
uri = Uri.parse(account.transportUri)
|
||||
}
|
||||
val oldHost = uri.host
|
||||
val oldPort = uri.port
|
||||
if (oldPort == -1) {
|
||||
// This occurs when a new account is created
|
||||
return
|
||||
}
|
||||
if (newHost != oldHost || newPort != oldPort) {
|
||||
localKeyStore.deleteCertificate(oldHost, oldPort)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Examine the settings for the account and attempt to delete (possibly non-existent)
|
||||
* certificates for the incoming and outgoing servers.
|
||||
*/
|
||||
fun deleteCertificates(account: Account) {
|
||||
val storeUri = account.storeUri
|
||||
if (storeUri != null) {
|
||||
val uri = Uri.parse(storeUri)
|
||||
localKeyStore.deleteCertificate(uri.host, uri.port)
|
||||
}
|
||||
val transportUri = account.transportUri
|
||||
if (transportUri != null) {
|
||||
val uri = Uri.parse(transportUri)
|
||||
localKeyStore.deleteCertificate(uri.host, uri.port)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -63,7 +63,7 @@ public class NotificationSetting {
|
|||
return vibrateEnabled;
|
||||
}
|
||||
|
||||
public synchronized void setVibrate(boolean vibrate) {
|
||||
public synchronized void setVibrateEnabled(boolean vibrate) {
|
||||
vibrateEnabled = vibrate;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,16 @@ import java.util.HashMap;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.RestrictTo;
|
||||
import android.support.annotation.RestrictTo.Scope;
|
||||
|
||||
import com.fsck.k9.backend.BackendManager;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mailstore.LocalStore;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.preferences.Storage;
|
||||
import com.fsck.k9.preferences.StorageEditor;
|
||||
import timber.log.Timber;
|
||||
|
@ -22,12 +27,16 @@ import timber.log.Timber;
|
|||
public class Preferences {
|
||||
|
||||
private static Preferences preferences;
|
||||
private AccountPreferenceSerializer accountPreferenceSerializer;
|
||||
|
||||
public static synchronized Preferences getPreferences(Context context) {
|
||||
Context appContext = context.getApplicationContext();
|
||||
CoreResourceProvider resourceProvider = DI.get(CoreResourceProvider.class);
|
||||
LocalKeyStoreManager localKeyStoreManager = DI.get(LocalKeyStoreManager.class);
|
||||
AccountPreferenceSerializer accountPreferenceSerializer = DI.get(AccountPreferenceSerializer.class);
|
||||
LocalStoreProvider localStoreProvider = DI.get(LocalStoreProvider.class);
|
||||
if (preferences == null) {
|
||||
preferences = new Preferences(appContext, resourceProvider);
|
||||
preferences = new Preferences(appContext, resourceProvider, localStoreProvider, localKeyStoreManager, accountPreferenceSerializer);
|
||||
}
|
||||
return preferences;
|
||||
}
|
||||
|
@ -37,12 +46,19 @@ public class Preferences {
|
|||
private List<Account> accountsInOrder = null;
|
||||
private Account newAccount;
|
||||
private Context context;
|
||||
private final LocalStoreProvider localStoreProvider;
|
||||
private final CoreResourceProvider resourceProvider;
|
||||
private final LocalKeyStoreManager localKeyStoreManager;
|
||||
|
||||
private Preferences(Context context, CoreResourceProvider resourceProvider) {
|
||||
private Preferences(Context context, CoreResourceProvider resourceProvider,
|
||||
LocalStoreProvider localStoreProvider, LocalKeyStoreManager localKeyStoreManager,
|
||||
AccountPreferenceSerializer accountPreferenceSerializer) {
|
||||
storage = Storage.getStorage(context);
|
||||
this.context = context;
|
||||
this.resourceProvider = resourceProvider;
|
||||
this.localStoreProvider = localStoreProvider;
|
||||
this.localKeyStoreManager = localKeyStoreManager;
|
||||
this.accountPreferenceSerializer = accountPreferenceSerializer;
|
||||
if (storage.isEmpty()) {
|
||||
Timber.i("Preferences storage is zero-size, importing from Android-style preferences");
|
||||
StorageEditor editor = storage.edit();
|
||||
|
@ -51,6 +67,12 @@ public class Preferences {
|
|||
}
|
||||
}
|
||||
|
||||
@RestrictTo(Scope.TESTS)
|
||||
public void clearAccounts() {
|
||||
accounts = new HashMap<>();
|
||||
accountsInOrder = new LinkedList<>();
|
||||
}
|
||||
|
||||
public synchronized void loadAccounts() {
|
||||
accounts = new HashMap<>();
|
||||
accountsInOrder = new LinkedList<>();
|
||||
|
@ -58,7 +80,8 @@ public class Preferences {
|
|||
if ((accountUuids != null) && (accountUuids.length() != 0)) {
|
||||
String[] uuids = accountUuids.split(",");
|
||||
for (String uuid : uuids) {
|
||||
Account newAccount = new Account(this, uuid);
|
||||
Account newAccount = new Account(uuid);
|
||||
accountPreferenceSerializer.loadAccount(newAccount, storage);
|
||||
accounts.put(uuid, newAccount);
|
||||
accountsInOrder.add(newAccount);
|
||||
}
|
||||
|
@ -113,7 +136,9 @@ public class Preferences {
|
|||
}
|
||||
|
||||
public synchronized Account newAccount() {
|
||||
newAccount = new Account(context, resourceProvider);
|
||||
String accountUuid = UUID.randomUUID().toString();
|
||||
newAccount = new Account(accountUuid);
|
||||
accountPreferenceSerializer.loadDefaults(newAccount);
|
||||
accounts.put(newAccount.getUuid(), newAccount);
|
||||
accountsInOrder.add(newAccount);
|
||||
|
||||
|
@ -135,7 +160,8 @@ public class Preferences {
|
|||
}
|
||||
LocalStore.removeAccount(account);
|
||||
|
||||
account.delete(this);
|
||||
DI.get(AccountPreferenceSerializer.class).delete(storage, account);
|
||||
localKeyStoreManager.deleteCertificates(account);
|
||||
|
||||
if (newAccount == account) {
|
||||
newAccount = null;
|
||||
|
@ -170,24 +196,72 @@ public class Preferences {
|
|||
return storage;
|
||||
}
|
||||
|
||||
static <T extends Enum<T>> T getEnumStringPref(Storage storage, String key, T defaultEnum) {
|
||||
String stringPref = storage.getString(key, null);
|
||||
|
||||
if (stringPref == null) {
|
||||
return defaultEnum;
|
||||
} else {
|
||||
try {
|
||||
return Enum.valueOf(defaultEnum.getDeclaringClass(), stringPref);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Timber.w(ex, "Unable to convert preference key [%s] value [%s] to enum of type %s",
|
||||
key, stringPref, defaultEnum.getDeclaringClass());
|
||||
|
||||
return defaultEnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BackendManager getBackendManager() {
|
||||
return DI.get(BackendManager.class);
|
||||
}
|
||||
|
||||
public void saveAccount(Account account) {
|
||||
StorageEditor editor = storage.edit();
|
||||
|
||||
if (!accounts.containsKey(account.getUuid())) {
|
||||
int accountNumber = generateAccountNumber();
|
||||
account.setAccountNumber(accountNumber);
|
||||
}
|
||||
|
||||
processChangedValues(account);
|
||||
|
||||
accountPreferenceSerializer.save(storage, editor, account);
|
||||
}
|
||||
|
||||
private void processChangedValues(Account account) {
|
||||
if (account.isChangedVisibleLimits()) {
|
||||
try {
|
||||
localStoreProvider.getInstance(account).resetVisibleLimits(account.getDisplayCount());
|
||||
} catch (MessagingException e) {
|
||||
Timber.e(e, "Failed to load LocalStore!");
|
||||
}
|
||||
}
|
||||
|
||||
if (account.isChangedLocalStorageProviderId()) {
|
||||
try {
|
||||
localStoreProvider.getInstance(account).switchLocalStorage(account.getLocalStorageProviderId());
|
||||
} catch (MessagingException e) {
|
||||
Timber.e(e, "Failed to load LocalStore!");
|
||||
}
|
||||
}
|
||||
|
||||
account.resetChangeMarkers();
|
||||
}
|
||||
|
||||
public int generateAccountNumber() {
|
||||
List<Integer> accountNumbers = getExistingAccountNumbers();
|
||||
return findNewAccountNumber(accountNumbers);
|
||||
}
|
||||
|
||||
private List<Integer> getExistingAccountNumbers() {
|
||||
List<Account> accounts = getAccounts();
|
||||
List<Integer> accountNumbers = new ArrayList<>(accounts.size());
|
||||
for (Account a : accounts) {
|
||||
accountNumbers.add(a.getAccountNumber());
|
||||
}
|
||||
return accountNumbers;
|
||||
}
|
||||
|
||||
private static int findNewAccountNumber(List<Integer> accountNumbers) {
|
||||
int newAccountNumber = -1;
|
||||
Collections.sort(accountNumbers);
|
||||
for (int accountNumber : accountNumbers) {
|
||||
if (accountNumber > newAccountNumber + 1) {
|
||||
break;
|
||||
}
|
||||
newAccountNumber = accountNumber;
|
||||
}
|
||||
newAccountNumber++;
|
||||
return newAccountNumber;
|
||||
}
|
||||
|
||||
public void move(Account account, boolean mUp) {
|
||||
accountPreferenceSerializer.move(account, storage, mUp);
|
||||
loadAccounts();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import com.fsck.k9.AccountStats
|
|||
import com.fsck.k9.K9
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.mail.MessagingException
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider
|
||||
import com.fsck.k9.search.AccountSearchConditions
|
||||
import com.fsck.k9.search.LocalSearch
|
||||
import com.fsck.k9.search.SearchAccount
|
||||
|
||||
|
@ -16,7 +18,11 @@ interface AccountStatsCollector {
|
|||
fun getSearchAccountStats(searchAccount: SearchAccount): AccountStats
|
||||
}
|
||||
|
||||
internal class DefaultAccountStatsCollector(private val context: Context) : AccountStatsCollector {
|
||||
internal class DefaultAccountStatsCollector(
|
||||
private val context: Context,
|
||||
private val accountSearchConditions: AccountSearchConditions,
|
||||
private val localStoreProvider: LocalStoreProvider
|
||||
) : AccountStatsCollector {
|
||||
private val preferences = Preferences.getPreferences(context)
|
||||
|
||||
|
||||
|
@ -25,11 +31,11 @@ internal class DefaultAccountStatsCollector(private val context: Context) : Acco
|
|||
return null
|
||||
}
|
||||
|
||||
val localStore = account.localStore
|
||||
val localStore = localStoreProvider.getInstance(account)
|
||||
|
||||
val search = LocalSearch()
|
||||
account.excludeSpecialFolders(search)
|
||||
account.limitToDisplayableFolders(search)
|
||||
accountSearchConditions.excludeSpecialFolders(account, search)
|
||||
accountSearchConditions.limitToDisplayableFolders(account, search)
|
||||
|
||||
val accountStats = localStore.getAccountStats(search)
|
||||
if (K9.measureAccounts()) {
|
||||
|
@ -45,7 +51,7 @@ internal class DefaultAccountStatsCollector(private val context: Context) : Acco
|
|||
|
||||
val aggregatedAccountStats = AccountStats()
|
||||
for (account in accounts) {
|
||||
val accountStats = account.localStore.getAccountStats(search)
|
||||
val accountStats = localStoreProvider.getInstance(account).getAccountStats(search)
|
||||
aggregatedAccountStats.unreadMessageCount += accountStats.unreadMessageCount
|
||||
aggregatedAccountStats.flaggedMessageCount += accountStats.flaggedMessageCount
|
||||
}
|
||||
|
|
|
@ -3,6 +3,6 @@ package com.fsck.k9.controller
|
|||
import org.koin.dsl.module.applicationContext
|
||||
|
||||
val controllerModule = applicationContext {
|
||||
bean { MessagingController(get(), get(), get(), get(), get(), get(), get("controllerExtensions")) }
|
||||
bean { DefaultAccountStatsCollector(get()) as AccountStatsCollector }
|
||||
bean { MessagingController(get(), get(), get(), get(), get(), get(), get(), get("controllerExtensions")) }
|
||||
bean { DefaultAccountStatsCollector(get(), get(), get()) as AccountStatsCollector }
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ import com.fsck.k9.mail.internet.MimeUtility;
|
|||
import com.fsck.k9.mailstore.LocalFolder;
|
||||
import com.fsck.k9.mailstore.LocalMessage;
|
||||
import com.fsck.k9.mailstore.LocalStore;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.mailstore.UnavailableStorageException;
|
||||
import com.fsck.k9.notification.NotificationController;
|
||||
import com.fsck.k9.power.TracingPowerManager;
|
||||
|
@ -114,6 +115,7 @@ public class MessagingController {
|
|||
private final Context context;
|
||||
private final Contacts contacts;
|
||||
private final NotificationController notificationController;
|
||||
private final LocalStoreProvider localStoreProvider;
|
||||
private final BackendManager backendManager;
|
||||
|
||||
private final Thread controllerThread;
|
||||
|
@ -137,11 +139,13 @@ public class MessagingController {
|
|||
}
|
||||
|
||||
|
||||
MessagingController(Context context, NotificationController notificationController, Contacts contacts,
|
||||
MessagingController(Context context, NotificationController notificationController,
|
||||
LocalStoreProvider localStoreProvider, Contacts contacts,
|
||||
AccountStatsCollector accountStatsCollector, CoreResourceProvider resourceProvider,
|
||||
BackendManager backendManager, List<ControllerExtension> controllerExtensions) {
|
||||
this.context = context;
|
||||
this.notificationController = notificationController;
|
||||
this.localStoreProvider = localStoreProvider;
|
||||
this.contacts = contacts;
|
||||
this.accountStatsCollector = accountStatsCollector;
|
||||
this.resourceProvider = resourceProvider;
|
||||
|
@ -267,7 +271,7 @@ public class MessagingController {
|
|||
|
||||
private LocalStore getLocalStoreOrThrow(Account account) {
|
||||
try {
|
||||
return account.getLocalStore();
|
||||
return localStoreProvider.getInstance(account);
|
||||
} catch (MessagingException e) {
|
||||
throw new IllegalStateException("Couldn't get LocalStore for account " + account.getDescription());
|
||||
}
|
||||
|
@ -393,7 +397,7 @@ public class MessagingController {
|
|||
Timber.i("not listing folders of unavailable account");
|
||||
} else {
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolders = localStore.getPersonalNamespaces(false);
|
||||
|
||||
if (refreshRemote || localFolders.isEmpty()) {
|
||||
|
@ -441,7 +445,7 @@ public class MessagingController {
|
|||
Backend backend = getBackend(account);
|
||||
backend.refreshFolderList();
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolders = localStore.getPersonalNamespaces(false);
|
||||
|
||||
for (MessagingListener l : getListeners(listener)) {
|
||||
|
@ -517,7 +521,7 @@ public class MessagingController {
|
|||
|
||||
// build and do the query in the localstore
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localStore.searchForMessages(retrievalListener, search);
|
||||
} catch (Exception e) {
|
||||
Timber.e(e);
|
||||
|
@ -554,7 +558,7 @@ public class MessagingController {
|
|||
|
||||
List<String> extraResults = new ArrayList<>();
|
||||
try {
|
||||
LocalStore localStore = acct.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(acct);
|
||||
|
||||
LocalFolder localFolder = localStore.getFolder(folderServerId);
|
||||
if (localFolder == null) {
|
||||
|
@ -609,7 +613,7 @@ public class MessagingController {
|
|||
listener.enableProgressIndicator(true);
|
||||
}
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
|
||||
if (localStore == null) {
|
||||
throw new MessagingException("Could not get store");
|
||||
|
@ -656,7 +660,7 @@ public class MessagingController {
|
|||
|
||||
public void loadMoreMessages(Account account, String folder, MessagingListener listener) {
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
LocalFolder localFolder = localStore.getFolder(folder);
|
||||
if (localFolder.getVisibleLimit() > 0) {
|
||||
localFolder.setVisibleLimit(localFolder.getVisibleLimit() + account.getDisplayCount());
|
||||
|
@ -726,7 +730,7 @@ public class MessagingController {
|
|||
return new SyncConfig(
|
||||
account.getExpungePolicy().toBackendExpungePolicy(),
|
||||
account.getEarliestPollDate(),
|
||||
account.syncRemoteDeletions(),
|
||||
account.isSyncRemoteDeletions(),
|
||||
account.getMaximumAutoDownloadMessageSize(),
|
||||
K9.DEFAULT_VISIBLE_LIMIT,
|
||||
SYNC_FLAGS);
|
||||
|
@ -734,7 +738,7 @@ public class MessagingController {
|
|||
|
||||
private void updateFolderStatus(Account account, String folderServerId, String status) {
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
LocalFolder localFolder = localStore.getFolder(folderServerId);
|
||||
localFolder.setStatus(status);
|
||||
} catch (MessagingException e) {
|
||||
|
@ -754,7 +758,7 @@ public class MessagingController {
|
|||
|
||||
private void queuePendingCommand(Account account, PendingCommand command) {
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localStore.addPendingCommand(command);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to enqueue pending command", e);
|
||||
|
@ -784,7 +788,7 @@ public class MessagingController {
|
|||
}
|
||||
|
||||
public void processPendingCommandsSynchronous(Account account) throws MessagingException {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
List<PendingCommand> commands = localStore.getPendingCommands();
|
||||
|
||||
int progress = 0;
|
||||
|
@ -859,7 +863,7 @@ public class MessagingController {
|
|||
String folder = command.folder;
|
||||
String uid = command.uid;
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(folder);
|
||||
LocalMessage localMessage = localFolder.getMessage(uid);
|
||||
|
||||
|
@ -959,7 +963,7 @@ public class MessagingController {
|
|||
boolean isCopy, Map<String, String> newUidMap) throws MessagingException {
|
||||
LocalFolder localDestFolder;
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localDestFolder = localStore.getFolder(destFolder);
|
||||
|
||||
Backend backend = getBackend(account);
|
||||
|
@ -1042,7 +1046,7 @@ public class MessagingController {
|
|||
String folder = command.folder;
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(folder);
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
List<? extends Message> messages = localFolder.getMessages(null, false);
|
||||
|
@ -1104,7 +1108,7 @@ public class MessagingController {
|
|||
|
||||
LocalStore localStore;
|
||||
try {
|
||||
localStore = account.getLocalStore();
|
||||
localStore = localStoreProvider.getInstance(account);
|
||||
} catch (MessagingException e) {
|
||||
Timber.e(e, "Couldn't get LocalStore instance");
|
||||
return;
|
||||
|
@ -1180,7 +1184,7 @@ public class MessagingController {
|
|||
// objects being modified right after this method returns.
|
||||
Folder localFolder = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(folderServerId);
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
|
@ -1238,7 +1242,7 @@ public class MessagingController {
|
|||
boolean newState) {
|
||||
Folder localFolder = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(folderServerId);
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
|
@ -1256,7 +1260,7 @@ public class MessagingController {
|
|||
public void clearAllPending(final Account account) {
|
||||
try {
|
||||
Timber.w("Clearing pending commands!");
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localStore.removePendingCommands();
|
||||
} catch (MessagingException me) {
|
||||
Timber.e(me, "Unable to clear pending command");
|
||||
|
@ -1288,7 +1292,7 @@ public class MessagingController {
|
|||
final String uid, final MessagingListener listener, final boolean loadPartialFromSearch) {
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(folder);
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
|
@ -1344,7 +1348,7 @@ public class MessagingController {
|
|||
}
|
||||
|
||||
public LocalMessage loadMessage(Account account, String folderServerId, String uid) throws MessagingException {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
LocalFolder localFolder = localStore.getFolder(folderServerId);
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
|
@ -1365,7 +1369,7 @@ public class MessagingController {
|
|||
}
|
||||
|
||||
public LocalMessage loadMessageMetadata(Account account, String folderServerId, String uid) throws MessagingException {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
LocalFolder localFolder = localStore.getFolder(folderServerId);
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
|
@ -1403,7 +1407,7 @@ public class MessagingController {
|
|||
try {
|
||||
String folderServerId = message.getFolder().getServerId();
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(folderServerId);
|
||||
|
||||
ProgressBodyFactory bodyFactory = new ProgressBodyFactory(new ProgressListener() {
|
||||
|
@ -1446,7 +1450,7 @@ public class MessagingController {
|
|||
String plaintextSubject,
|
||||
MessagingListener listener) {
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
LocalFolder localFolder = localStore.getFolder(account.getOutboxFolder());
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
localFolder.appendMessages(Collections.singletonList(message));
|
||||
|
@ -1506,13 +1510,13 @@ public class MessagingController {
|
|||
}
|
||||
|
||||
private void showSendingNotificationIfNecessary(Account account) {
|
||||
if (account.isShowOngoing()) {
|
||||
if (account.isNotifySync()) {
|
||||
notificationController.showSendingNotification(account);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearSendingNotificationIfNecessary(Account account) {
|
||||
if (account.isShowOngoing()) {
|
||||
if (account.isNotifySync()) {
|
||||
notificationController.clearSendingNotification(account);
|
||||
}
|
||||
}
|
||||
|
@ -1520,7 +1524,7 @@ public class MessagingController {
|
|||
private boolean messagesPendingSend(final Account account) {
|
||||
Folder localFolder = null;
|
||||
try {
|
||||
localFolder = account.getLocalStore().getFolder(
|
||||
localFolder = localStoreProvider.getInstance(account).getFolder(
|
||||
account.getOutboxFolder());
|
||||
if (!localFolder.exists()) {
|
||||
return false;
|
||||
|
@ -1548,7 +1552,7 @@ public class MessagingController {
|
|||
Exception lastFailure = null;
|
||||
boolean wasPermanentFailure = false;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(
|
||||
account.getOutboxFolder());
|
||||
if (!localFolder.exists()) {
|
||||
|
@ -1793,7 +1797,7 @@ public class MessagingController {
|
|||
}
|
||||
|
||||
public int getFolderUnreadMessageCount(Account account, String folderServerId) throws MessagingException {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
Folder localFolder = localStore.getFolder(folderServerId);
|
||||
return localFolder.getUnreadMessageCount();
|
||||
}
|
||||
|
@ -1932,7 +1936,7 @@ public class MessagingController {
|
|||
final List<? extends Message> inMessages, final String destFolder, final boolean isCopy) {
|
||||
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
if (!isCopy && !isMoveCapable(account)) {
|
||||
return;
|
||||
}
|
||||
|
@ -2032,7 +2036,7 @@ public class MessagingController {
|
|||
public void deleteDraft(final Account account, long id) {
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(account.getDraftsFolder());
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
String uid = localFolder.getMessageUidById(id);
|
||||
|
@ -2076,10 +2080,10 @@ public class MessagingController {
|
|||
}
|
||||
}
|
||||
|
||||
private static List<Message> collectMessagesInThreads(Account account, List<? extends Message> messages)
|
||||
private List<Message> collectMessagesInThreads(Account account, List<? extends Message> messages)
|
||||
throws MessagingException {
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
|
||||
List<Message> messagesInThreads = new ArrayList<>();
|
||||
for (Message message : messages) {
|
||||
|
@ -2175,7 +2179,7 @@ public class MessagingController {
|
|||
}
|
||||
}
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(folder);
|
||||
Map<String, String> uidMap = null;
|
||||
if (folder.equals(account.getTrashFolder()) || !account.hasTrashFolder()) {
|
||||
|
@ -2264,7 +2268,7 @@ public class MessagingController {
|
|||
|
||||
// When we empty trash, we need to actually synchronize the folder
|
||||
// or local deletes will never get cleaned up
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
LocalFolder folder = localStore.getFolder(trashFolderServerId);
|
||||
folder.open(Folder.OPEN_MODE_RW);
|
||||
synchronizeFolder(account, folder, true, 0, null);
|
||||
|
@ -2278,7 +2282,7 @@ public class MessagingController {
|
|||
public void run() {
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(account.getTrashFolder());
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
|
@ -2323,7 +2327,7 @@ public class MessagingController {
|
|||
protected void clearFolderSynchronous(Account account, String folderServerId, MessagingListener listener) {
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
localFolder = account.getLocalStore().getFolder(folderServerId);
|
||||
localFolder = localStoreProvider.getInstance(account).getFolder(folderServerId);
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
localFolder.clearAllMessages();
|
||||
} catch (UnavailableStorageException e) {
|
||||
|
@ -2489,7 +2493,7 @@ public class MessagingController {
|
|||
Account.FolderMode aDisplayMode = account.getFolderDisplayMode();
|
||||
Account.FolderMode aSyncMode = account.getFolderSyncMode();
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
for (final Folder folder : localStore.getPersonalNamespaces(false)) {
|
||||
folder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
|
@ -2569,7 +2573,7 @@ public class MessagingController {
|
|||
try {
|
||||
// In case multiple Commands get enqueued, don't run more than
|
||||
// once
|
||||
final LocalStore localStore = account.getLocalStore();
|
||||
final LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
tLocalFolder = localStore.getFolder(folder.getServerId());
|
||||
tLocalFolder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
|
@ -2600,13 +2604,13 @@ public class MessagingController {
|
|||
}
|
||||
|
||||
private void showFetchingMailNotificationIfNecessary(Account account, Folder folder) {
|
||||
if (account.isShowOngoing()) {
|
||||
if (account.isNotifySync()) {
|
||||
notificationController.showFetchingMailNotification(account, folder);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearFetchingMailNotificationIfNecessary(Account account) {
|
||||
if (account.isShowOngoing()) {
|
||||
if (account.isNotifySync()) {
|
||||
notificationController.clearFetchingMailNotification(account);
|
||||
}
|
||||
}
|
||||
|
@ -2617,7 +2621,7 @@ public class MessagingController {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
long oldSize = localStore.getSize();
|
||||
localStore.compact();
|
||||
long newSize = localStore.getSize();
|
||||
|
@ -2639,7 +2643,7 @@ public class MessagingController {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
long oldSize = localStore.getSize();
|
||||
localStore.clear();
|
||||
localStore.resetVisibleLimits(account.getDisplayCount());
|
||||
|
@ -2667,7 +2671,7 @@ public class MessagingController {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
long oldSize = localStore.getSize();
|
||||
localStore.recreate();
|
||||
localStore.resetVisibleLimits(account.getDisplayCount());
|
||||
|
@ -2765,7 +2769,7 @@ public class MessagingController {
|
|||
public Message saveDraft(final Account account, final Message message, long existingDraftId, String plaintextSubject, boolean saveRemotely) {
|
||||
LocalMessage localMessage = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
LocalFolder localFolder = localStore.getFolder(account.getDraftsFolder());
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
|
@ -2870,7 +2874,7 @@ public class MessagingController {
|
|||
|
||||
List<String> names = new ArrayList<>();
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
for (final Folder folder : localStore.getPersonalNamespaces(false)) {
|
||||
if (folder.getServerId().equals(account.getOutboxFolder())) {
|
||||
continue;
|
||||
|
@ -2910,7 +2914,7 @@ public class MessagingController {
|
|||
}
|
||||
|
||||
if (!names.isEmpty()) {
|
||||
PushReceiver receiver = new MessagingControllerPushReceiver(context, account, this);
|
||||
PushReceiver receiver = new MessagingControllerPushReceiver(context, localStoreProvider, account, this);
|
||||
int maxPushFolders = account.getMaxPushFolders();
|
||||
|
||||
if (names.size() > maxPushFolders) {
|
||||
|
@ -3038,7 +3042,7 @@ public class MessagingController {
|
|||
private void actOnMessageGroup(
|
||||
Account account, String folderServerId, List<MessageReference> messageReferences, MessageActor actor) {
|
||||
try {
|
||||
LocalFolder messageFolder = account.getLocalStore().getFolder(folderServerId);
|
||||
LocalFolder messageFolder = localStoreProvider.getInstance(account).getFolder(folderServerId);
|
||||
List<LocalMessage> localMessages = messageFolder.getMessagesByReference(messageReferences);
|
||||
actor.act(account, messageFolder, localMessages);
|
||||
} catch (MessagingException e) {
|
||||
|
|
|
@ -1,31 +1,34 @@
|
|||
package com.fsck.k9.controller;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.fsck.k9.mail.power.WakeLock;
|
||||
import timber.log.Timber;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.mail.Folder;
|
||||
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.PushReceiver;
|
||||
import com.fsck.k9.mail.power.WakeLock;
|
||||
import com.fsck.k9.mailstore.LocalFolder;
|
||||
import com.fsck.k9.mailstore.LocalStore;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.service.SleepService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class MessagingControllerPushReceiver implements PushReceiver {
|
||||
final Account account;
|
||||
final MessagingController controller;
|
||||
final Context context;
|
||||
final LocalStoreProvider localStoreProvider;
|
||||
|
||||
public MessagingControllerPushReceiver(Context context, Account nAccount, MessagingController nController) {
|
||||
public MessagingControllerPushReceiver(Context context, LocalStoreProvider localStoreProvider,
|
||||
Account nAccount, MessagingController nController) {
|
||||
account = nAccount;
|
||||
controller = nController;
|
||||
this.localStoreProvider = localStoreProvider;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
@ -90,7 +93,7 @@ public class MessagingControllerPushReceiver implements PushReceiver {
|
|||
public String getPushState(String folderServerId) {
|
||||
LocalFolder localFolder = null;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = localStoreProvider.getInstance(account);
|
||||
localFolder = localStore.getFolder(folderServerId);
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
return localFolder.getPushState();
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.fsck.k9.mail.Folder.FolderClass
|
|||
import com.fsck.k9.mail.Folder.FolderType as RemoteFolderType
|
||||
|
||||
class FolderRepository(
|
||||
private val localStoreProvider: LocalStoreProvider,
|
||||
private val specialFolderSelectionStrategy: SpecialFolderSelectionStrategy,
|
||||
private val account: Account
|
||||
) {
|
||||
|
@ -30,7 +31,7 @@ class FolderRepository(
|
|||
}
|
||||
|
||||
private fun getRemoteFolders(): List<Folder> {
|
||||
val folders = account.localStore.getPersonalNamespaces(false)
|
||||
val folders = localStoreProvider.getInstance(account).getPersonalNamespaces(false)
|
||||
|
||||
return folders
|
||||
.filterNot { it.isLocalOnly }
|
||||
|
@ -38,7 +39,7 @@ class FolderRepository(
|
|||
}
|
||||
|
||||
fun getDisplayFolders(): List<Folder> {
|
||||
val folders = account.localStore.getPersonalNamespaces(false)
|
||||
val folders = localStoreProvider.getInstance(account).getPersonalNamespaces(false)
|
||||
return folders
|
||||
.filter(::shouldDisplayFolder)
|
||||
.sortedWith(sortForDisplay)
|
||||
|
|
|
@ -2,6 +2,9 @@ package com.fsck.k9.mailstore
|
|||
|
||||
import com.fsck.k9.Account
|
||||
|
||||
class FolderRepositoryManager(private val specialFolderSelectionStrategy: SpecialFolderSelectionStrategy) {
|
||||
fun getFolderRepository(account: Account) = FolderRepository(specialFolderSelectionStrategy, account)
|
||||
class FolderRepositoryManager(
|
||||
private val localStoreProvider: LocalStoreProvider,
|
||||
private val specialFolderSelectionStrategy: SpecialFolderSelectionStrategy
|
||||
) {
|
||||
fun getFolderRepository(account: Account) = FolderRepository(localStoreProvider, specialFolderSelectionStrategy, account)
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ class K9BackendFolder(
|
|||
|
||||
override fun setLatestOldMessageSeenTime(date: Date) {
|
||||
account.latestOldMessageSeenTime = date.time
|
||||
account.save(preferences)
|
||||
preferences.saveAccount(account)
|
||||
}
|
||||
|
||||
override fun getOldestMessageDate(): Date? {
|
||||
|
|
|
@ -5,11 +5,13 @@ import com.fsck.k9.Preferences
|
|||
|
||||
class K9BackendStorageFactory(
|
||||
private val preferences: Preferences,
|
||||
private val folderRepositoryManager: FolderRepositoryManager
|
||||
private val folderRepositoryManager: FolderRepositoryManager,
|
||||
private val localStoreProvider: LocalStoreProvider
|
||||
) {
|
||||
fun createBackendStorage(account: Account): K9BackendStorage {
|
||||
val folderRepository = folderRepositoryManager.getFolderRepository(account)
|
||||
val localStore = localStoreProvider.getInstance(account)
|
||||
val specialFolderUpdater = SpecialFolderUpdater(preferences, folderRepository, account)
|
||||
return K9BackendStorage(preferences, account, account.localStore, specialFolderUpdater)
|
||||
return K9BackendStorage(preferences, account, localStore, specialFolderUpdater)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ package com.fsck.k9.mailstore
|
|||
import org.koin.dsl.module.applicationContext
|
||||
|
||||
val mailStoreModule = applicationContext {
|
||||
bean { FolderRepositoryManager(get()) }
|
||||
bean { FolderRepositoryManager(get(), get()) }
|
||||
bean { MessageViewInfoExtractor(get(), get(), get()) }
|
||||
bean { StorageManager.getInstance(get()) }
|
||||
bean { SearchStatusManager() }
|
||||
bean { SpecialFolderSelectionStrategy() }
|
||||
bean { K9BackendStorageFactory(get(), get()) }
|
||||
bean { K9BackendStorageFactory(get(), get(), get()) }
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ public class LocalFolder extends Folder<LocalMessage> {
|
|||
}
|
||||
|
||||
public boolean syncRemoteDeletions() {
|
||||
return getAccount().syncRemoteDeletions();
|
||||
return getAccount().isSyncRemoteDeletions();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,8 +17,6 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
|
@ -81,18 +79,6 @@ public class LocalStore {
|
|||
static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
|
||||
|
||||
/**
|
||||
* Lock objects indexed by account UUID.
|
||||
*
|
||||
* @see #getInstance(Account, Context)
|
||||
*/
|
||||
private static ConcurrentMap<String, Object> sAccountLocks = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Local stores indexed by UUID because the Uri may change due to migration to/from SD-card.
|
||||
*/
|
||||
private static ConcurrentMap<String, LocalStore> sLocalStores = new ConcurrentHashMap<>();
|
||||
|
||||
/*
|
||||
* a String containing the columns getMessages expects to work with
|
||||
* in the correct order.
|
||||
|
@ -195,9 +181,13 @@ public class LocalStore {
|
|||
private final Account account;
|
||||
private final LockableDatabase database;
|
||||
|
||||
static LocalStore createInstance(Account account, Context context) throws MessagingException {
|
||||
return new LocalStore(account, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* local://localhost/path/to/database/uuid.db
|
||||
* This constructor is only used by {@link LocalStore#getInstance(Account, Context)}
|
||||
* This constructor is only used by {@link LocalStoreProvider#getInstance(Account)}
|
||||
* @throws UnavailableStorageException if not {@link StorageProvider#isReady(Context)}
|
||||
*/
|
||||
private LocalStore(final Account account, final Context context) throws MessagingException {
|
||||
|
@ -221,37 +211,6 @@ public class LocalStore {
|
|||
database.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of a local mail store.
|
||||
*
|
||||
* @throws UnavailableStorageException
|
||||
* if not {@link StorageProvider#isReady(Context)}
|
||||
*/
|
||||
public static LocalStore getInstance(Account account, Context context)
|
||||
throws MessagingException {
|
||||
|
||||
String accountUuid = account.getUuid();
|
||||
|
||||
// Create new per-account lock object if necessary
|
||||
sAccountLocks.putIfAbsent(accountUuid, new Object());
|
||||
|
||||
// Use per-account locks so DatabaseUpgradeService always knows which account database is
|
||||
// currently upgraded.
|
||||
synchronized (sAccountLocks.get(accountUuid)) {
|
||||
LocalStore store = sLocalStores.get(accountUuid);
|
||||
|
||||
if (store == null) {
|
||||
// Creating a LocalStore instance will create or upgrade the database if
|
||||
// necessary. This could take some time.
|
||||
store = new LocalStore(account, context);
|
||||
|
||||
sLocalStores.put(accountUuid, store);
|
||||
}
|
||||
|
||||
return store;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getDbVersion() {
|
||||
SchemaDefinitionFactory schemaDefinitionFactory = DI.get(SchemaDefinitionFactory.class);
|
||||
return schemaDefinitionFactory.getDatabaseVersion();
|
||||
|
@ -266,8 +225,7 @@ public class LocalStore {
|
|||
}
|
||||
|
||||
private static void removeInstance(Account account) {
|
||||
String accountUuid = account.getUuid();
|
||||
sLocalStores.remove(accountUuid);
|
||||
DI.get(LocalStoreProvider.class).removeInstance(account);
|
||||
}
|
||||
|
||||
public void switchLocalStorage(final String newStorageProviderId) throws MessagingException {
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package com.fsck.k9.mailstore
|
||||
|
||||
import android.content.Context
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.DI
|
||||
import com.fsck.k9.mail.MessagingException
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class LocalStoreProvider {
|
||||
private val localStores = ConcurrentHashMap<String, LocalStore>()
|
||||
private val accountLocks = ConcurrentHashMap<String, Any>()
|
||||
|
||||
@Throws(MessagingException::class)
|
||||
fun getInstance(account: Account): LocalStore {
|
||||
val context = DI.get(Context::class.java)
|
||||
val accountUuid = account.uuid
|
||||
|
||||
// Use per-account locks so DatabaseUpgradeService always knows which account database is currently upgraded.
|
||||
synchronized(accountLocks.getOrPut(accountUuid) { Any() }) {
|
||||
// Creating a LocalStore instance will create or upgrade the database if
|
||||
// necessary. This could take some time.
|
||||
return localStores.getOrPut(accountUuid) { LocalStore.createInstance(account, context) }
|
||||
}
|
||||
}
|
||||
|
||||
fun removeInstance(account: Account) {
|
||||
val accountUuid = account.uuid
|
||||
localStores.remove(accountUuid)
|
||||
}
|
||||
}
|
|
@ -77,6 +77,6 @@ class SpecialFolderUpdater(
|
|||
}
|
||||
|
||||
private fun saveAccount() {
|
||||
account.save(preferences)
|
||||
preferences.saveAccount(account)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ package com.fsck.k9.notification
|
|||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.support.v4.app.NotificationManagerCompat
|
||||
import com.fsck.k9.AccountPreferenceSerializer
|
||||
import com.fsck.k9.LocalKeyStoreManager
|
||||
import com.fsck.k9.mail.ssl.LocalKeyStore
|
||||
import org.koin.dsl.module.applicationContext
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
|
@ -18,6 +21,9 @@ val coreNotificationModule = applicationContext {
|
|||
get()
|
||||
)
|
||||
}
|
||||
bean { AccountPreferenceSerializer(get(), get()) }
|
||||
bean { LocalKeyStore.getInstance() }
|
||||
bean { LocalKeyStoreManager(get()) }
|
||||
bean { CertificateErrorNotifications(get(), get(), get()) }
|
||||
bean { AuthenticationErrorNotifications(get(), get(), get()) }
|
||||
bean { SyncNotifications(get(), get(), get()) }
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.fsck.k9.Account.Searchable;
|
|||
import com.fsck.k9.Account.ShowPictures;
|
||||
import com.fsck.k9.Account.SortType;
|
||||
import com.fsck.k9.Account.SpecialFolderSelection;
|
||||
import com.fsck.k9.AccountPreferenceSerializer;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.core.R;
|
||||
|
@ -68,7 +69,7 @@ public class AccountSettings {
|
|||
new V(1, new ColorSetting(0xFF0000FF))
|
||||
));
|
||||
s.put("defaultQuotedTextShown", Settings.versions(
|
||||
new V(1, new BooleanSetting(Account.DEFAULT_QUOTED_TEXT_SHOWN))
|
||||
new V(1, new BooleanSetting(AccountPreferenceSerializer.DEFAULT_QUOTED_TEXT_SHOWN))
|
||||
));
|
||||
s.put("deletePolicy", Settings.versions(
|
||||
new V(1, new DeletePolicySetting(DeletePolicy.NEVER))
|
||||
|
@ -128,13 +129,13 @@ public class AccountSettings {
|
|||
new V(1, new IntegerResourceSetting(-1, R.array.message_age_values))
|
||||
));
|
||||
s.put("messageFormat", Settings.versions(
|
||||
new V(1, new EnumSetting<>(MessageFormat.class, Account.DEFAULT_MESSAGE_FORMAT))
|
||||
new V(1, new EnumSetting<>(MessageFormat.class, AccountPreferenceSerializer.DEFAULT_MESSAGE_FORMAT))
|
||||
));
|
||||
s.put("messageFormatAuto", Settings.versions(
|
||||
new V(2, new BooleanSetting(Account.DEFAULT_MESSAGE_FORMAT_AUTO))
|
||||
new V(2, new BooleanSetting(AccountPreferenceSerializer.DEFAULT_MESSAGE_FORMAT_AUTO))
|
||||
));
|
||||
s.put("messageReadReceipt", Settings.versions(
|
||||
new V(1, new BooleanSetting(Account.DEFAULT_MESSAGE_READ_RECEIPT))
|
||||
new V(1, new BooleanSetting(AccountPreferenceSerializer.DEFAULT_MESSAGE_READ_RECEIPT))
|
||||
));
|
||||
s.put("notifyMailCheck", Settings.versions(
|
||||
new V(1, new BooleanSetting(false))
|
||||
|
@ -152,13 +153,13 @@ public class AccountSettings {
|
|||
new V(1, new BooleanSetting(true))
|
||||
));
|
||||
s.put("quotePrefix", Settings.versions(
|
||||
new V(1, new StringSetting(Account.DEFAULT_QUOTE_PREFIX))
|
||||
new V(1, new StringSetting(AccountPreferenceSerializer.DEFAULT_QUOTE_PREFIX))
|
||||
));
|
||||
s.put("quoteStyle", Settings.versions(
|
||||
new V(1, new EnumSetting<>(QuoteStyle.class, Account.DEFAULT_QUOTE_STYLE))
|
||||
new V(1, new EnumSetting<>(QuoteStyle.class, AccountPreferenceSerializer.DEFAULT_QUOTE_STYLE))
|
||||
));
|
||||
s.put("replyAfterQuote", Settings.versions(
|
||||
new V(1, new BooleanSetting(Account.DEFAULT_REPLY_AFTER_QUOTE))
|
||||
new V(1, new BooleanSetting(AccountPreferenceSerializer.DEFAULT_REPLY_AFTER_QUOTE))
|
||||
));
|
||||
s.put("ring", Settings.versions(
|
||||
new V(1, new BooleanSetting(true))
|
||||
|
@ -190,7 +191,7 @@ public class AccountSettings {
|
|||
new V(53, new StringSetting(null))
|
||||
));
|
||||
s.put("stripSignature", Settings.versions(
|
||||
new V(2, new BooleanSetting(Account.DEFAULT_STRIP_SIGNATURE))
|
||||
new V(2, new BooleanSetting(AccountPreferenceSerializer.DEFAULT_STRIP_SIGNATURE))
|
||||
));
|
||||
s.put("subscribedFoldersOnly", Settings.versions(
|
||||
new V(1, new BooleanSetting(false))
|
||||
|
@ -224,7 +225,7 @@ public class AccountSettings {
|
|||
new V(18, new BooleanSetting(true))
|
||||
));
|
||||
s.put("remoteSearchNumResults", Settings.versions(
|
||||
new V(18, new IntegerResourceSetting(Account.DEFAULT_REMOTE_SEARCH_NUM_RESULTS,
|
||||
new V(18, new IntegerResourceSetting(AccountPreferenceSerializer.DEFAULT_REMOTE_SEARCH_NUM_RESULTS,
|
||||
R.array.remote_search_num_results_values))
|
||||
));
|
||||
s.put("remoteSearchFullText", Settings.versions(
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.os.Environment;
|
|||
import android.util.Xml;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.AccountPreferenceSerializer;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.backend.BackendManager;
|
||||
|
@ -226,7 +227,7 @@ public class SettingsExporter {
|
|||
serializer.startTag(null, ACCOUNT_ELEMENT);
|
||||
serializer.attribute(null, UUID_ATTRIBUTE, accountUuid);
|
||||
|
||||
String name = (String) prefs.get(accountUuid + "." + Account.ACCOUNT_DESCRIPTION_KEY);
|
||||
String name = (String) prefs.get(accountUuid + "." + AccountPreferenceSerializer.ACCOUNT_DESCRIPTION_KEY);
|
||||
if (name != null) {
|
||||
serializer.startTag(null, NAME_ELEMENT);
|
||||
serializer.text(name);
|
||||
|
@ -324,7 +325,7 @@ public class SettingsExporter {
|
|||
String secondPart = keyPart.substring(0, indexOfLastDot);
|
||||
String thirdPart = keyPart.substring(indexOfLastDot + 1);
|
||||
|
||||
if (Account.IDENTITY_DESCRIPTION_KEY.equals(secondPart)) {
|
||||
if (AccountPreferenceSerializer.IDENTITY_DESCRIPTION_KEY.equals(secondPart)) {
|
||||
// This is an identity key. Save identity index for later...
|
||||
try {
|
||||
identities.add(Integer.parseInt(thirdPart));
|
||||
|
@ -393,19 +394,19 @@ public class SettingsExporter {
|
|||
String suffix = "." + identity;
|
||||
|
||||
// Write name belonging to the identity
|
||||
String name = (String) prefs.get(prefix + Account.IDENTITY_NAME_KEY + suffix);
|
||||
String name = (String) prefs.get(prefix + AccountPreferenceSerializer.IDENTITY_NAME_KEY + suffix);
|
||||
serializer.startTag(null, NAME_ELEMENT);
|
||||
serializer.text(name);
|
||||
serializer.endTag(null, NAME_ELEMENT);
|
||||
|
||||
// Write email address belonging to the identity
|
||||
String email = (String) prefs.get(prefix + Account.IDENTITY_EMAIL_KEY + suffix);
|
||||
String email = (String) prefs.get(prefix + AccountPreferenceSerializer.IDENTITY_EMAIL_KEY + suffix);
|
||||
serializer.startTag(null, EMAIL_ELEMENT);
|
||||
serializer.text(email);
|
||||
serializer.endTag(null, EMAIL_ELEMENT);
|
||||
|
||||
// Write identity description
|
||||
String description = (String) prefs.get(prefix + Account.IDENTITY_DESCRIPTION_KEY + suffix);
|
||||
String description = (String) prefs.get(prefix + AccountPreferenceSerializer.IDENTITY_DESCRIPTION_KEY + suffix);
|
||||
if (description != null) {
|
||||
serializer.startTag(null, DESCRIPTION_ELEMENT);
|
||||
serializer.text(description);
|
||||
|
|
|
@ -18,6 +18,7 @@ import android.support.annotation.VisibleForTesting;
|
|||
import android.text.TextUtils;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.AccountPreferenceSerializer;
|
||||
import com.fsck.k9.Core;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.Identity;
|
||||
|
@ -338,7 +339,7 @@ public class SettingsImporter {
|
|||
|
||||
// Write account name
|
||||
String accountKeyPrefix = uuid + ".";
|
||||
putString(editor, accountKeyPrefix + Account.ACCOUNT_DESCRIPTION_KEY, accountName);
|
||||
putString(editor, accountKeyPrefix + AccountPreferenceSerializer.ACCOUNT_DESCRIPTION_KEY, accountName);
|
||||
|
||||
if (account.incoming == null) {
|
||||
// We don't import accounts without incoming server settings
|
||||
|
@ -349,7 +350,7 @@ public class SettingsImporter {
|
|||
ServerSettings incoming = new ImportedServerSettings(account.incoming);
|
||||
BackendManager backendManager = DI.get(BackendManager.class);
|
||||
String storeUri = backendManager.createStoreUri(incoming);
|
||||
putString(editor, accountKeyPrefix + Account.STORE_URI_KEY, Base64.encode(storeUri));
|
||||
putString(editor, accountKeyPrefix + AccountPreferenceSerializer.STORE_URI_KEY, Base64.encode(storeUri));
|
||||
|
||||
// Mark account as disabled if the AuthType isn't EXTERNAL and the
|
||||
// settings file didn't contain a password
|
||||
|
@ -366,7 +367,7 @@ public class SettingsImporter {
|
|||
// Write outgoing server settings (transportUri)
|
||||
ServerSettings outgoing = new ImportedServerSettings(account.outgoing);
|
||||
String transportUri = backendManager.createTransportUri(outgoing);
|
||||
putString(editor, accountKeyPrefix + Account.TRANSPORT_URI_KEY, Base64.encode(transportUri));
|
||||
putString(editor, accountKeyPrefix + AccountPreferenceSerializer.TRANSPORT_URI_KEY, Base64.encode(transportUri));
|
||||
|
||||
/*
|
||||
* Mark account as disabled if the settings file contained a username but no password. However, no password
|
||||
|
@ -417,7 +418,7 @@ public class SettingsImporter {
|
|||
|
||||
// If it's a new account generate and write a new "accountNumber"
|
||||
if (!mergeImportedAccount) {
|
||||
int newAccountNumber = Account.generateAccountNumber(prefs);
|
||||
int newAccountNumber = prefs.generateAccountNumber();
|
||||
putString(editor, accountKeyPrefix + "accountNumber", Integer.toString(newAccountNumber));
|
||||
}
|
||||
|
||||
|
@ -522,7 +523,7 @@ public class SettingsImporter {
|
|||
|
||||
// Write name used in identity
|
||||
String identityName = (identity.name == null) ? "" : identity.name;
|
||||
putString(editor, accountKeyPrefix + Account.IDENTITY_NAME_KEY + identitySuffix, identityName);
|
||||
putString(editor, accountKeyPrefix + AccountPreferenceSerializer.IDENTITY_NAME_KEY + identitySuffix, identityName);
|
||||
|
||||
// Validate email address
|
||||
if (!IdentitySettings.isEmailAddressValid(identity.email)) {
|
||||
|
@ -530,10 +531,10 @@ public class SettingsImporter {
|
|||
}
|
||||
|
||||
// Write email address
|
||||
putString(editor, accountKeyPrefix + Account.IDENTITY_EMAIL_KEY + identitySuffix, identity.email);
|
||||
putString(editor, accountKeyPrefix + AccountPreferenceSerializer.IDENTITY_EMAIL_KEY + identitySuffix, identity.email);
|
||||
|
||||
// Write identity description
|
||||
putString(editor, accountKeyPrefix + Account.IDENTITY_DESCRIPTION_KEY + identitySuffix,
|
||||
putString(editor, accountKeyPrefix + AccountPreferenceSerializer.IDENTITY_DESCRIPTION_KEY + identitySuffix,
|
||||
identityDescription);
|
||||
|
||||
if (identity.settings != null) {
|
||||
|
|
|
@ -13,6 +13,9 @@ import android.net.Uri;
|
|||
import android.os.ParcelFileDescriptor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import timber.log.Timber;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
|
@ -94,7 +97,7 @@ public class AttachmentProvider extends ContentProvider {
|
|||
final AttachmentInfo attachmentInfo;
|
||||
try {
|
||||
final Account account = Preferences.getPreferences(getContext()).getAccount(accountUuid);
|
||||
attachmentInfo = LocalStore.getInstance(account, getContext()).getAttachmentInfo(id);
|
||||
attachmentInfo = DI.get(LocalStoreProvider.class).getInstance(account).getAttachmentInfo(id);
|
||||
} catch (MessagingException e) {
|
||||
Timber.e(e, "Unable to retrieve attachment info from local store for ID: %s", id);
|
||||
return null;
|
||||
|
@ -143,7 +146,7 @@ public class AttachmentProvider extends ContentProvider {
|
|||
final Account account = Preferences.getPreferences(getContext()).getAccount(accountUuid);
|
||||
|
||||
try {
|
||||
final LocalStore localStore = LocalStore.getInstance(account, getContext());
|
||||
final LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
|
||||
AttachmentInfo attachmentInfo = localStore.getAttachmentInfo(id);
|
||||
if (mimeType != null) {
|
||||
|
@ -180,7 +183,7 @@ public class AttachmentProvider extends ContentProvider {
|
|||
@Nullable
|
||||
private OpenPgpDataSource getAttachmentDataSource(String accountUuid, String attachmentId) throws MessagingException {
|
||||
final Account account = Preferences.getPreferences(getContext()).getAccount(accountUuid);
|
||||
LocalStore localStore = LocalStore.getInstance(account, getContext());
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
return localStore.getAttachmentDataSource(attachmentId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,13 @@ import android.net.Uri;
|
|||
import android.text.TextUtils;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.cache.EmailProviderCacheCursor;
|
||||
import com.fsck.k9.helper.Utility;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mailstore.LocalStore;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.mailstore.LockableDatabase;
|
||||
import com.fsck.k9.mailstore.LockableDatabase.DbCallback;
|
||||
import com.fsck.k9.mailstore.LockableDatabase.WrappedException;
|
||||
|
@ -527,7 +529,7 @@ public class EmailProvider extends ContentProvider {
|
|||
private LockableDatabase getDatabase(Account account) {
|
||||
LocalStore localStore;
|
||||
try {
|
||||
localStore = account.getLocalStore();
|
||||
localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
} catch (MessagingException e) {
|
||||
throw new RuntimeException("Couldn't get LocalStore", e);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import android.support.annotation.NonNull;
|
|||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.controller.MessageReference;
|
||||
import com.fsck.k9.mail.FetchProfile;
|
||||
|
@ -27,6 +28,7 @@ import com.fsck.k9.mail.filter.CountingOutputStream;
|
|||
import com.fsck.k9.mailstore.LocalFolder;
|
||||
import com.fsck.k9.mailstore.LocalMessage;
|
||||
import com.fsck.k9.mailstore.LocalStore;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import org.openintents.openpgp.util.OpenPgpApi.OpenPgpDataSource;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
@ -181,7 +183,7 @@ public class RawMessageProvider extends ContentProvider {
|
|||
}
|
||||
|
||||
try {
|
||||
LocalStore localStore = LocalStore.getInstance(account, getContext());
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
LocalFolder localFolder = localStore.getFolder(folderServerId);
|
||||
localFolder.open(Folder.OPEN_MODE_RW);
|
||||
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
package com.fsck.k9.search
|
||||
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Account.FolderMode
|
||||
import com.fsck.k9.BaseAccount
|
||||
import com.fsck.k9.mail.Folder.FolderClass
|
||||
import com.fsck.k9.search.SearchSpecification.*
|
||||
|
||||
class AccountSearchConditions {
|
||||
/**
|
||||
* Modify the supplied [LocalSearch] instance to limit the search to displayable folders.
|
||||
*
|
||||
* This method uses the current folder display mode to decide what folders to include/exclude.
|
||||
*
|
||||
* @param search
|
||||
* The `LocalSearch` instance to modify.
|
||||
*
|
||||
* @see .getFolderDisplayMode
|
||||
*/
|
||||
fun limitToDisplayableFolders(account: Account, search: LocalSearch) {
|
||||
val displayMode = account.folderDisplayMode
|
||||
|
||||
when (displayMode) {
|
||||
FolderMode.FIRST_CLASS -> {
|
||||
// Count messages in the INBOX and non-special first class folders
|
||||
search.and(SearchField.DISPLAY_CLASS, FolderClass.FIRST_CLASS.name, Attribute.EQUALS)
|
||||
}
|
||||
FolderMode.FIRST_AND_SECOND_CLASS -> {
|
||||
// Count messages in the INBOX and non-special first and second class folders
|
||||
search.and(SearchField.DISPLAY_CLASS, FolderClass.FIRST_CLASS.name, Attribute.EQUALS)
|
||||
|
||||
// TODO: Create a proper interface for creating arbitrary condition trees
|
||||
val searchCondition = SearchCondition(
|
||||
SearchField.DISPLAY_CLASS, Attribute.EQUALS, FolderClass.SECOND_CLASS.name)
|
||||
val root = search.conditions
|
||||
if (root.mRight != null) {
|
||||
root.mRight.or(searchCondition)
|
||||
} else {
|
||||
search.or(searchCondition)
|
||||
}
|
||||
}
|
||||
FolderMode.NOT_SECOND_CLASS -> {
|
||||
// Count messages in the INBOX and non-special non-second-class folders
|
||||
search.and(SearchField.DISPLAY_CLASS, FolderClass.SECOND_CLASS.name, Attribute.NOT_EQUALS)
|
||||
}
|
||||
FolderMode.ALL, FolderMode.NONE -> {
|
||||
// Count messages in the INBOX and non-special folders
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the supplied [LocalSearch] instance to exclude special folders.
|
||||
*
|
||||
* Currently the following folders are excluded:
|
||||
*
|
||||
* * Trash
|
||||
* * Drafts
|
||||
* * Spam
|
||||
* * Outbox
|
||||
* * Sent
|
||||
*
|
||||
* The Inbox will always be included even if one of the special folders is configured to point
|
||||
* to the Inbox.
|
||||
*
|
||||
* @param search
|
||||
* The `LocalSearch` instance to modify.
|
||||
*/
|
||||
fun excludeSpecialFolders(account: Account, search: LocalSearch) {
|
||||
excludeSpecialFolder(search, account.trashFolder)
|
||||
excludeSpecialFolder(search, account.draftsFolder)
|
||||
excludeSpecialFolder(search, account.spamFolder)
|
||||
excludeSpecialFolder(search, account.outboxFolder)
|
||||
excludeSpecialFolder(search, account.sentFolder)
|
||||
search.or(SearchCondition(SearchField.FOLDER, Attribute.EQUALS, account.getInboxFolder()))
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the supplied [LocalSearch] instance to exclude "unwanted" folders.
|
||||
*
|
||||
* Currently the following folders are excluded:
|
||||
*
|
||||
* * Trash
|
||||
* * Spam
|
||||
* * Outbox
|
||||
*
|
||||
* The Inbox will always be included even if one of the special folders is configured to point
|
||||
* to the Inbox.
|
||||
*
|
||||
* @param search
|
||||
* The `LocalSearch` instance to modify.
|
||||
*/
|
||||
fun excludeUnwantedFolders(account: Account, search: LocalSearch) {
|
||||
excludeSpecialFolder(search, account.trashFolder)
|
||||
excludeSpecialFolder(search, account.spamFolder)
|
||||
excludeSpecialFolder(search, account.outboxFolder)
|
||||
search.or(SearchCondition(SearchField.FOLDER, Attribute.EQUALS, account.inboxFolder))
|
||||
}
|
||||
|
||||
private fun excludeSpecialFolder(search: LocalSearch, folderServerId: String?) {
|
||||
if (folderServerId != null) {
|
||||
search.and(SearchField.FOLDER, folderServerId, Attribute.NOT_EQUALS)
|
||||
}
|
||||
}
|
||||
|
||||
fun createUnreadSearch(account: BaseAccount, searchTitle: String): LocalSearch {
|
||||
val search: LocalSearch
|
||||
if (account is SearchAccount) {
|
||||
search = account.relatedSearch.clone()
|
||||
search.name = searchTitle
|
||||
} else {
|
||||
search = LocalSearch(searchTitle)
|
||||
search.addAccountUuid(account.uuid)
|
||||
|
||||
val realAccount = account as Account
|
||||
excludeSpecialFolders(realAccount, search)
|
||||
limitToDisplayableFolders(realAccount, search)
|
||||
}
|
||||
|
||||
search.and(SearchField.READ, "1", Attribute.NOT_EQUALS)
|
||||
|
||||
return search
|
||||
}
|
||||
}
|
8
app/core/src/main/java/com/fsck/k9/search/KoinModule.kt
Normal file
8
app/core/src/main/java/com/fsck/k9/search/KoinModule.kt
Normal file
|
@ -0,0 +1,8 @@
|
|||
package com.fsck.k9.search
|
||||
|
||||
import com.fsck.k9.mailstore.*
|
||||
import org.koin.dsl.module.applicationContext
|
||||
|
||||
val searchModule = applicationContext {
|
||||
bean { AccountSearchConditions() }
|
||||
}
|
|
@ -2,6 +2,8 @@ package com.fsck.k9.search;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import timber.log.Timber;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
|
@ -28,6 +30,7 @@ public class SqlQueryBuilder {
|
|||
}
|
||||
|
||||
if (node.mLeft == null && node.mRight == null) {
|
||||
AccountSearchConditions accountSearchConditions = DI.get(AccountSearchConditions.class);
|
||||
SearchCondition condition = node.mCondition;
|
||||
switch (condition.field) {
|
||||
case FOLDER: {
|
||||
|
@ -48,7 +51,7 @@ public class SqlQueryBuilder {
|
|||
LocalSearch tempSearch = new LocalSearch();
|
||||
// ...the helper methods in Account to create the necessary conditions
|
||||
// to exclude "unwanted" folders.
|
||||
account.excludeUnwantedFolders(tempSearch);
|
||||
accountSearchConditions.excludeUnwantedFolders(account, tempSearch);
|
||||
|
||||
buildWhereClauseInternal(account, tempSearch.getConditions(), query,
|
||||
selectionArgs);
|
||||
|
@ -59,8 +62,8 @@ public class SqlQueryBuilder {
|
|||
LocalSearch tempSearch = new LocalSearch();
|
||||
// ...the helper methods in Account to create the necessary conditions
|
||||
// to limit the selection to displayable, non-special folders.
|
||||
account.excludeSpecialFolders(tempSearch);
|
||||
account.limitToDisplayableFolders(tempSearch);
|
||||
accountSearchConditions.excludeSpecialFolders(account, tempSearch);
|
||||
accountSearchConditions.limitToDisplayableFolders(account, tempSearch);
|
||||
|
||||
buildWhereClauseInternal(account, tempSearch.getConditions(), query,
|
||||
selectionArgs);
|
||||
|
@ -107,7 +110,7 @@ public class SqlQueryBuilder {
|
|||
private static long getFolderId(Account account, String folderServerId) {
|
||||
long folderId = 0;
|
||||
try {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
LocalFolder folder = localStore.getFolder(folderServerId);
|
||||
folder.open(Folder.OPEN_MODE_RO);
|
||||
folderId = folder.getDatabaseId();
|
||||
|
|
|
@ -12,8 +12,10 @@ import android.os.PowerManager;
|
|||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.mailstore.UnavailableStorageException;
|
||||
import com.fsck.k9.power.TracingPowerManager;
|
||||
import com.fsck.k9.power.TracingPowerManager.TracingWakeLock;
|
||||
|
@ -192,7 +194,7 @@ public class DatabaseUpgradeService extends Service {
|
|||
|
||||
try {
|
||||
// Account.getLocalStore() is blocking and will upgrade the database if necessary
|
||||
account.getLocalStore();
|
||||
DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
} catch (UnavailableStorageException e) {
|
||||
Timber.e("Database unavailable");
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
package com.fsck.k9
|
||||
|
||||
class TestCoreResourceProvider : CoreResourceProvider {
|
||||
override fun defaultSignature(): String {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
override fun defaultSignature() = "\n--\nbrevity!"
|
||||
|
||||
override fun defaultIdentityDescription(): String {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
override fun defaultIdentityDescription() = "initial identity"
|
||||
|
||||
override fun sendAlternateChooserTitle(): String {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
|
|
|
@ -11,8 +11,11 @@ import java.util.Set;
|
|||
import android.content.Context;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.Account.SpecialFolderSelection;
|
||||
import com.fsck.k9.AccountPreferenceSerializer;
|
||||
import com.fsck.k9.AccountStats;
|
||||
import com.fsck.k9.CoreResourceProvider;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.K9RobolectricTest;
|
||||
import com.fsck.k9.Preferences;
|
||||
|
@ -29,6 +32,7 @@ import com.fsck.k9.mail.MessagingException;
|
|||
import com.fsck.k9.mailstore.LocalFolder;
|
||||
import com.fsck.k9.mailstore.LocalMessage;
|
||||
import com.fsck.k9.mailstore.LocalStore;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.mailstore.UnavailableStorageException;
|
||||
import com.fsck.k9.notification.NotificationController;
|
||||
import com.fsck.k9.search.LocalSearch;
|
||||
|
@ -44,6 +48,7 @@ import org.mockito.ArgumentMatchers;
|
|||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
@ -61,6 +66,7 @@ import static org.mockito.Mockito.doThrow;
|
|||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
@ -71,17 +77,18 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
private static final String FOLDER_NAME = "Folder";
|
||||
private static final String SENT_FOLDER_NAME = "Sent";
|
||||
private static final int MAXIMUM_SMALL_MESSAGE_SIZE = 1000;
|
||||
|
||||
private static final String ACCOUNT_UUID = "1";
|
||||
|
||||
private MessagingController controller;
|
||||
private Account account;
|
||||
@Mock
|
||||
private BackendManager backendManager;
|
||||
@Mock
|
||||
private Backend backend;
|
||||
@Mock
|
||||
private Contacts contacts;
|
||||
private LocalStoreProvider localStoreProvider;
|
||||
@Mock
|
||||
private Account account;
|
||||
private Contacts contacts;
|
||||
@Mock
|
||||
private AccountStats accountStats;
|
||||
@Mock
|
||||
|
@ -137,17 +144,18 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
MockitoAnnotations.initMocks(this);
|
||||
appContext = RuntimeEnvironment.application;
|
||||
|
||||
controller = new MessagingController(appContext, notificationController, contacts,
|
||||
controller = new MessagingController(appContext, notificationController, localStoreProvider, contacts,
|
||||
accountStatsCollector, mock(CoreResourceProvider.class), backendManager,
|
||||
Collections.<ControllerExtension>emptyList());
|
||||
|
||||
configureBackendManager();
|
||||
configureAccount();
|
||||
configureBackendManager();
|
||||
configureLocalStore();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
removeAccountsFromPreferences();
|
||||
controller.stop();
|
||||
StandAloneContext.INSTANCE.closeKoin();
|
||||
}
|
||||
|
@ -258,7 +266,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
@Test
|
||||
public void searchLocalMessagesSynchronous_shouldCallSearchForMessagesOnLocalStore()
|
||||
throws Exception {
|
||||
setAccountsInPreferences(Collections.singletonMap("1", account));
|
||||
setAccountsInPreferences(Collections.singletonMap(ACCOUNT_UUID, account));
|
||||
when(search.getAccountUuids()).thenReturn(new String[]{"allAccounts"});
|
||||
|
||||
controller.searchLocalMessagesSynchronous(search, listener);
|
||||
|
@ -269,7 +277,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
@Test
|
||||
public void searchLocalMessagesSynchronous_shouldNotifyWhenStoreFinishesRetrievingAMessage()
|
||||
throws Exception {
|
||||
setAccountsInPreferences(Collections.singletonMap("1", account));
|
||||
setAccountsInPreferences(Collections.singletonMap(ACCOUNT_UUID, account));
|
||||
LocalMessage localMessage = mock(LocalMessage.class);
|
||||
when(localMessage.getFolder()).thenReturn(localFolder);
|
||||
when(search.getAccountUuids()).thenReturn(new String[]{"allAccounts"});
|
||||
|
@ -285,7 +293,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
}
|
||||
|
||||
private void setupRemoteSearch() throws Exception {
|
||||
setAccountsInPreferences(Collections.singletonMap("1", account));
|
||||
setAccountsInPreferences(Collections.singletonMap(ACCOUNT_UUID, account));
|
||||
|
||||
remoteMessages = new ArrayList<>();
|
||||
Collections.addAll(remoteMessages, "oldMessageUid", "newMessageUid1", "newMessageUid2");
|
||||
|
@ -323,14 +331,14 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
reqFlags = Collections.singleton(Flag.ANSWERED);
|
||||
forbiddenFlags = Collections.singleton(Flag.DELETED);
|
||||
|
||||
when(account.getRemoteSearchNumResults()).thenReturn(50);
|
||||
account.setRemoteSearchNumResults(50);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void searchRemoteMessagesSynchronous_shouldNotifyStartedListingRemoteMessages() throws Exception {
|
||||
setupRemoteSearch();
|
||||
|
||||
controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
controller.searchRemoteMessagesSynchronous(ACCOUNT_UUID, FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
|
||||
verify(listener).remoteSearchStarted(FOLDER_NAME);
|
||||
}
|
||||
|
@ -339,7 +347,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
public void searchRemoteMessagesSynchronous_shouldQueryRemoteFolder() throws Exception {
|
||||
setupRemoteSearch();
|
||||
|
||||
controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
controller.searchRemoteMessagesSynchronous(ACCOUNT_UUID, FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
|
||||
verify(backend).search(FOLDER_NAME, "query", reqFlags, forbiddenFlags);
|
||||
}
|
||||
|
@ -348,7 +356,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
public void searchRemoteMessagesSynchronous_shouldAskLocalFolderToDetermineNewMessages() throws Exception {
|
||||
setupRemoteSearch();
|
||||
|
||||
controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
controller.searchRemoteMessagesSynchronous(ACCOUNT_UUID, FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
|
||||
verify(localFolder).extractNewMessages(remoteMessages);
|
||||
}
|
||||
|
@ -357,7 +365,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
public void searchRemoteMessagesSynchronous_shouldTryAndGetNewMessages() throws Exception {
|
||||
setupRemoteSearch();
|
||||
|
||||
controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
controller.searchRemoteMessagesSynchronous(ACCOUNT_UUID, FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
|
||||
verify(localFolder).getMessage("newMessageUid1");
|
||||
}
|
||||
|
@ -366,7 +374,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
public void searchRemoteMessagesSynchronous_shouldNotTryAndGetOldMessages() throws Exception {
|
||||
setupRemoteSearch();
|
||||
|
||||
controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
controller.searchRemoteMessagesSynchronous(ACCOUNT_UUID, FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
|
||||
verify(localFolder, never()).getMessage("oldMessageUid");
|
||||
}
|
||||
|
@ -375,7 +383,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
public void searchRemoteMessagesSynchronous_shouldFetchNewMessages() throws Exception {
|
||||
setupRemoteSearch();
|
||||
|
||||
controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
controller.searchRemoteMessagesSynchronous(ACCOUNT_UUID, FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
|
||||
verify(backend).fetchMessage(eq(FOLDER_NAME), eq("newMessageUid2"), fetchProfileCaptor.capture());
|
||||
}
|
||||
|
@ -384,7 +392,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
public void searchRemoteMessagesSynchronous_shouldNotFetchExistingMessages() throws Exception {
|
||||
setupRemoteSearch();
|
||||
|
||||
controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
controller.searchRemoteMessagesSynchronous(ACCOUNT_UUID, FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
|
||||
verify(backend, never()).fetchMessage(eq(FOLDER_NAME), eq("newMessageUid1"), fetchProfileCaptor.capture());
|
||||
}
|
||||
|
@ -395,7 +403,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
when(backend.search(anyString(), anyString(), nullable(Set.class), nullable(Set.class)))
|
||||
.thenThrow(new MessagingException("Test"));
|
||||
|
||||
controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
controller.searchRemoteMessagesSynchronous(ACCOUNT_UUID, FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
|
||||
verify(listener).remoteSearchFailed(null, "Test");
|
||||
}
|
||||
|
@ -406,7 +414,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
when(backend.search(anyString(), nullable(String.class), nullable(Set.class), nullable(Set.class)))
|
||||
.thenThrow(new MessagingException("Test"));
|
||||
|
||||
controller.searchRemoteMessagesSynchronous("1", FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
controller.searchRemoteMessagesSynchronous(ACCOUNT_UUID, FOLDER_NAME, "query", reqFlags, forbiddenFlags, listener);
|
||||
|
||||
verify(listener).remoteSearchFinished(FOLDER_NAME, 0, 50, Collections.<String>emptyList());
|
||||
}
|
||||
|
@ -519,8 +527,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
|
||||
private void setupAccountWithMessageToSend() throws MessagingException {
|
||||
when(account.getOutboxFolder()).thenReturn(FOLDER_NAME);
|
||||
when(account.hasSentFolder()).thenReturn(true);
|
||||
when(account.getSentFolder()).thenReturn(SENT_FOLDER_NAME);
|
||||
account.setSentFolder(SENT_FOLDER_NAME, SpecialFolderSelection.AUTOMATIC);
|
||||
when(localStore.getFolder(SENT_FOLDER_NAME)).thenReturn(sentFolder);
|
||||
when(sentFolder.getDatabaseId()).thenReturn(1L);
|
||||
when(localFolder.exists()).thenReturn(true);
|
||||
|
@ -535,20 +542,24 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
}
|
||||
|
||||
private void configureAccount() throws MessagingException {
|
||||
when(account.isAvailable(appContext)).thenReturn(true);
|
||||
when(account.getLocalStore()).thenReturn(localStore);
|
||||
when(account.getMaximumAutoDownloadMessageSize()).thenReturn(MAXIMUM_SMALL_MESSAGE_SIZE);
|
||||
when(account.getEmail()).thenReturn("user@host.com");
|
||||
// TODO use simple account object without mocks
|
||||
account = spy(new Account(ACCOUNT_UUID));
|
||||
DI.get(AccountPreferenceSerializer.class).loadDefaults(account);
|
||||
account.setMaximumAutoDownloadMessageSize(MAXIMUM_SMALL_MESSAGE_SIZE);
|
||||
account.setEmail("user@host.com");
|
||||
Mockito.doReturn(true).when(account).isAvailable(appContext);
|
||||
}
|
||||
|
||||
private void configureLocalStore() throws MessagingException {
|
||||
when(localStore.getFolder(FOLDER_NAME)).thenReturn(localFolder);
|
||||
when(localFolder.getServerId()).thenReturn(FOLDER_NAME);
|
||||
when(localStore.getPersonalNamespaces(false)).thenReturn(Collections.singletonList(localFolder));
|
||||
when(localStoreProvider.getInstance(account)).thenReturn(localStore);
|
||||
}
|
||||
|
||||
private void setAccountsInPreferences(Map<String, Account> newAccounts)
|
||||
throws Exception {
|
||||
// TODO this affects other tests, try to get rid of it
|
||||
Field accounts = Preferences.class.getDeclaredField("accounts");
|
||||
accounts.setAccessible(true);
|
||||
accounts.set(Preferences.getPreferences(appContext), newAccounts);
|
||||
|
@ -558,4 +569,8 @@ public class MessagingControllerTest extends K9RobolectricTest {
|
|||
ArrayList<Account> newAccountsInOrder = new ArrayList<>(newAccounts.values());
|
||||
accountsInOrder.set(Preferences.getPreferences(appContext), newAccountsInOrder);
|
||||
}
|
||||
|
||||
private void removeAccountsFromPreferences() {
|
||||
Preferences.getPreferences(appContext).clearAccounts();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,8 @@ import com.fsck.k9.mail.Message
|
|||
import com.fsck.k9.mail.Message.RecipientType
|
||||
import com.fsck.k9.mail.internet.MimeMessage
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.nhaarman.mockito_kotlin.mock
|
||||
import org.junit.Test
|
||||
import org.robolectric.RuntimeEnvironment
|
||||
import java.util.*
|
||||
|
||||
class IdentityHelperTest : RobolectricTest() {
|
||||
private val account = createDummyAccount()
|
||||
|
@ -110,7 +109,7 @@ class IdentityHelperTest : RobolectricTest() {
|
|||
}
|
||||
|
||||
|
||||
private fun createDummyAccount() = DummyAccount().apply {
|
||||
private fun createDummyAccount() = Account(UUID.randomUUID().toString()).apply {
|
||||
identities = listOf(
|
||||
newIdentity("Default", DEFAULT_ADDRESS),
|
||||
newIdentity("Identity 1", IDENTITY_1_ADDRESS),
|
||||
|
@ -142,7 +141,4 @@ class IdentityHelperTest : RobolectricTest() {
|
|||
const val IDENTITY_4_ADDRESS = "identity4@example.org"
|
||||
const val IDENTITY_5_ADDRESS = "identity5@example.org"
|
||||
}
|
||||
|
||||
|
||||
class DummyAccount : Account(RuntimeEnvironment.application, mock())
|
||||
}
|
||||
|
|
|
@ -27,10 +27,11 @@ import org.koin.standalone.inject
|
|||
class K9BackendFolderTest : K9RobolectricTest() {
|
||||
val preferences: Preferences by inject()
|
||||
val folderRepositoryManager: FolderRepositoryManager by inject()
|
||||
val localStoreProvider: LocalStoreProvider by inject()
|
||||
|
||||
val account: Account = createAccount()
|
||||
val backendFolder = createBackendFolder()
|
||||
val database: LockableDatabase = account.localStore.database
|
||||
val database: LockableDatabase = localStoreProvider.getInstance(account).database
|
||||
|
||||
|
||||
@Before
|
||||
|
@ -78,13 +79,13 @@ class K9BackendFolderTest : K9RobolectricTest() {
|
|||
|
||||
fun createAccount(): Account {
|
||||
//FIXME: This is a hack to get Preferences into a state where it's safe to call newAccount()
|
||||
preferences.loadAccounts()
|
||||
preferences.clearAccounts()
|
||||
|
||||
return preferences.newAccount()
|
||||
}
|
||||
|
||||
fun createBackendFolder(): BackendFolder {
|
||||
val localStore: LocalStore = account.localStore
|
||||
val localStore: LocalStore = localStoreProvider.getInstance(account)
|
||||
val folderRepository = folderRepositoryManager.getFolderRepository(account)
|
||||
val specialFolderUpdater = SpecialFolderUpdater(preferences, folderRepository, account)
|
||||
val backendStorage = K9BackendStorage(preferences, account, localStore, specialFolderUpdater)
|
||||
|
|
|
@ -6,7 +6,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.K9RobolectricTest;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.mail.AuthType;
|
||||
|
@ -32,9 +31,7 @@ public class SettingsImporterTest extends K9RobolectricTest {
|
|||
|
||||
private void deletePreExistingAccounts() {
|
||||
Preferences preferences = Preferences.getPreferences(RuntimeEnvironment.application);
|
||||
for (Account account : preferences.getAccounts()) {
|
||||
preferences.deleteAccount(account);
|
||||
}
|
||||
preferences.clearAccounts();
|
||||
}
|
||||
|
||||
@Test(expected = SettingsImportExportException.class)
|
||||
|
|
|
@ -55,7 +55,7 @@ public class MessageProviderTest extends ProviderTestCase2 {
|
|||
account.setDescription("TestAccount");
|
||||
account.setChipColor(10);
|
||||
account.setStoreUri("imap://user@domain.com/");
|
||||
account.save(preferences);
|
||||
preferences.saveAccount(account);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.test.ApplicationTestCase;
|
|||
import android.test.RenamingDelegatingContext;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.mail.Body;
|
||||
import com.fsck.k9.mail.FetchProfile;
|
||||
|
@ -134,7 +135,7 @@ public class ReconstructMessageFromDatabaseTest extends ApplicationTestCase<K9>
|
|||
}
|
||||
|
||||
protected LocalFolder createFolderInDatabase() throws MessagingException {
|
||||
LocalStore localStore = LocalStore.getInstance(account, getApplication());
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
LocalFolder inbox = localStore.getFolder("INBOX");
|
||||
localStore.createFolders(Collections.singletonList(inbox), 10);
|
||||
return inbox;
|
||||
|
|
|
@ -13,10 +13,12 @@ import android.support.test.runner.AndroidJUnit4;
|
|||
import android.test.ProviderTestCase2;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -157,7 +159,7 @@ public class EmailProviderTest extends ProviderTestCase2<EmailProvider> {
|
|||
public void query_forMessagesWithAccountAndRequiredFieldsAndOrderBy_providesResult() throws MessagingException {
|
||||
Account account = Preferences.getPreferences(getContext()).newAccount();
|
||||
account.getUuid();
|
||||
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(message));
|
||||
DI.get(LocalStoreProvider.class).getInstance(account).getFolder("Inbox").appendMessages(Collections.singletonList(message));
|
||||
|
||||
Cursor cursor = getProvider().query(
|
||||
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() + "/messages"),
|
||||
|
@ -179,7 +181,8 @@ public class EmailProviderTest extends ProviderTestCase2<EmailProvider> {
|
|||
public void query_forMessagesWithAccountAndRequiredFieldsAndOrderBy_sortsCorrectly() throws MessagingException {
|
||||
Account account = Preferences.getPreferences(getContext()).newAccount();
|
||||
account.getUuid();
|
||||
account.getLocalStore().getFolder("Inbox").appendMessages(Arrays.asList(message, laterMessage));
|
||||
DI.get(LocalStoreProvider.class).getInstance(account)
|
||||
.getFolder("Inbox").appendMessages(Arrays.asList(message, laterMessage));
|
||||
|
||||
Cursor cursor = getProvider().query(
|
||||
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() + "/messages"),
|
||||
|
@ -204,7 +207,8 @@ public class EmailProviderTest extends ProviderTestCase2<EmailProvider> {
|
|||
public void query_forThreadedMessages_sortsCorrectly() throws MessagingException {
|
||||
Account account = Preferences.getPreferences(getContext()).newAccount();
|
||||
account.getUuid();
|
||||
account.getLocalStore().getFolder("Inbox").appendMessages(Arrays.asList(message, laterMessage));
|
||||
DI.get(LocalStoreProvider.class).getInstance(account)
|
||||
.getFolder("Inbox").appendMessages(Arrays.asList(message, laterMessage));
|
||||
|
||||
Cursor cursor = getProvider().query(
|
||||
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() +
|
||||
|
@ -230,8 +234,8 @@ public class EmailProviderTest extends ProviderTestCase2<EmailProvider> {
|
|||
public void query_forThreadedMessages_showsThreadOfEmailOnce() throws MessagingException {
|
||||
Account account = Preferences.getPreferences(getContext()).newAccount();
|
||||
account.getUuid();
|
||||
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(message));
|
||||
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(reply));
|
||||
DI.get(LocalStoreProvider.class).getInstance(account).getFolder("Inbox").appendMessages(Collections.singletonList(message));
|
||||
DI.get(LocalStoreProvider.class).getInstance(account).getFolder("Inbox").appendMessages(Collections.singletonList(reply));
|
||||
|
||||
Cursor cursor = getProvider().query(
|
||||
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() +
|
||||
|
@ -258,8 +262,8 @@ public class EmailProviderTest extends ProviderTestCase2<EmailProvider> {
|
|||
public void query_forThreadedMessages_showsThreadOfEmailWithSameSendTimeOnce() throws MessagingException {
|
||||
Account account = Preferences.getPreferences(getContext()).newAccount();
|
||||
account.getUuid();
|
||||
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(message));
|
||||
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(replyAtSameTime));
|
||||
DI.get(LocalStoreProvider.class).getInstance(account).getFolder("Inbox").appendMessages(Collections.singletonList(message));
|
||||
DI.get(LocalStoreProvider.class).getInstance(account).getFolder("Inbox").appendMessages(Collections.singletonList(replyAtSameTime));
|
||||
|
||||
Cursor cursor = getProvider().query(
|
||||
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() +
|
||||
|
@ -289,7 +293,7 @@ public class EmailProviderTest extends ProviderTestCase2<EmailProvider> {
|
|||
Message message = new MimeMessage();
|
||||
message.setSubject("Test Subject");
|
||||
message.setSentDate(new GregorianCalendar(2016, 1, 2).getTime(), false);
|
||||
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(message));
|
||||
DI.get(LocalStoreProvider.class).getInstance(account).getFolder("Inbox").appendMessages(Collections.singletonList(message));
|
||||
|
||||
//Now get the thread id we just put in.
|
||||
Cursor cursor = getProvider().query(
|
||||
|
|
|
@ -97,7 +97,7 @@ public class RemoteControlService extends CoreService {
|
|||
account.getNotificationSetting().setRingEnabled(Boolean.parseBoolean(ringEnabled));
|
||||
}
|
||||
if (vibrateEnabled != null) {
|
||||
account.getNotificationSetting().setVibrate(Boolean.parseBoolean(vibrateEnabled));
|
||||
account.getNotificationSetting().setVibrateEnabled(Boolean.parseBoolean(vibrateEnabled));
|
||||
}
|
||||
if (pushClasses != null) {
|
||||
needsPushRestart |= account.setFolderPushMode(FolderMode.valueOf(pushClasses));
|
||||
|
@ -114,7 +114,7 @@ public class RemoteControlService extends CoreService {
|
|||
}
|
||||
}
|
||||
}
|
||||
account.save(Preferences.getPreferences(RemoteControlService.this));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(account);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,10 @@ import android.support.v4.app.TaskStackBuilder;
|
|||
import android.text.TextUtils;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.R;
|
||||
import com.fsck.k9.activity.Accounts;
|
||||
import com.fsck.k9.activity.FolderList;
|
||||
import com.fsck.k9.activity.MessageList;
|
||||
|
@ -20,6 +22,7 @@ import com.fsck.k9.activity.NotificationDeleteConfirmation;
|
|||
import com.fsck.k9.activity.compose.MessageActions;
|
||||
import com.fsck.k9.activity.setup.AccountSetupIncoming;
|
||||
import com.fsck.k9.activity.setup.AccountSetupOutgoing;
|
||||
import com.fsck.k9.search.AccountSearchConditions;
|
||||
import com.fsck.k9.search.LocalSearch;
|
||||
|
||||
|
||||
|
@ -35,6 +38,7 @@ import com.fsck.k9.search.LocalSearch;
|
|||
*/
|
||||
class K9NotificationActionCreator implements NotificationActionCreator {
|
||||
private final Context context;
|
||||
private final AccountSearchConditions accountSearchConditions = DI.get(AccountSearchConditions.class);
|
||||
|
||||
|
||||
public K9NotificationActionCreator(Context context) {
|
||||
|
@ -58,7 +62,7 @@ class K9NotificationActionCreator implements NotificationActionCreator {
|
|||
int notificationId) {
|
||||
|
||||
TaskStackBuilder stack;
|
||||
if (account.goToUnreadMessageSearch()) {
|
||||
if (account.isGoToUnreadMessageSearch()) {
|
||||
stack = buildUnreadBackStack(account);
|
||||
} else {
|
||||
String folderServerId = getFolderServerIdOfAllMessages(messageReferences);
|
||||
|
@ -227,7 +231,8 @@ class K9NotificationActionCreator implements NotificationActionCreator {
|
|||
private TaskStackBuilder buildUnreadBackStack(final Account account) {
|
||||
TaskStackBuilder stack = buildAccountsBackStack();
|
||||
|
||||
LocalSearch search = Accounts.createUnreadSearch(context, account);
|
||||
String searchTitle = context.getString(R.string.search_title, account.getDescription(), context.getString(R.string.unread_modifier));
|
||||
LocalSearch search = accountSearchConditions.createUnreadSearch(account, searchTitle);
|
||||
Intent intent = MessageList.intentDisplaySearch(context, search, true, false, false);
|
||||
|
||||
stack.addNextIntent(intent);
|
||||
|
|
|
@ -8,13 +8,15 @@ import java.io.FileInputStream;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.AccountPreferenceSerializer;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.mail.BodyPart;
|
||||
import com.fsck.k9.mail.FetchProfile;
|
||||
import com.fsck.k9.mail.Multipart;
|
||||
|
@ -26,6 +28,7 @@ import com.fsck.k9.mailstore.FileBackedBody;
|
|||
import com.fsck.k9.mailstore.LocalBodyPart;
|
||||
import com.fsck.k9.mailstore.LocalMessage;
|
||||
import com.fsck.k9.mailstore.LocalStore;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.mailstore.StorageManager;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.james.mime4j.util.MimeUtil;
|
||||
|
@ -159,7 +162,7 @@ public class MigrationTest extends K9RobolectricTest {
|
|||
insertSimplePlaintextMessage(db);
|
||||
db.close();
|
||||
|
||||
LocalStore localStore = LocalStore.getInstance(account, RuntimeEnvironment.application);
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
|
||||
LocalMessage msg = localStore.getFolder("dev").getMessage("3");
|
||||
FetchProfile fp = new FetchProfile();
|
||||
|
@ -226,7 +229,7 @@ public class MigrationTest extends K9RobolectricTest {
|
|||
insertMixedWithAttachments(db);
|
||||
db.close();
|
||||
|
||||
LocalStore localStore = LocalStore.getInstance(account, RuntimeEnvironment.application);
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
|
||||
LocalMessage msg = localStore.getFolder("dev").getMessage("4");
|
||||
FetchProfile fp = new FetchProfile();
|
||||
|
@ -298,7 +301,7 @@ public class MigrationTest extends K9RobolectricTest {
|
|||
insertPgpMimeSignedMessage(db);
|
||||
db.close();
|
||||
|
||||
LocalStore localStore = LocalStore.getInstance(account, RuntimeEnvironment.application);
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
|
||||
LocalMessage msg = localStore.getFolder("dev").getMessage("5");
|
||||
FetchProfile fp = new FetchProfile();
|
||||
|
@ -357,7 +360,7 @@ public class MigrationTest extends K9RobolectricTest {
|
|||
insertPgpMimeEncryptedMessage(db);
|
||||
db.close();
|
||||
|
||||
LocalStore localStore = LocalStore.getInstance(account, RuntimeEnvironment.application);
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
|
||||
LocalMessage msg = localStore.getFolder("dev").getMessage("6");
|
||||
FetchProfile fp = new FetchProfile();
|
||||
|
@ -475,7 +478,7 @@ public class MigrationTest extends K9RobolectricTest {
|
|||
insertPgpInlineEncryptedMessage(db);
|
||||
db.close();
|
||||
|
||||
LocalStore localStore = LocalStore.getInstance(account, RuntimeEnvironment.application);
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
|
||||
LocalMessage msg = localStore.getFolder("dev").getMessage("7");
|
||||
FetchProfile fp = new FetchProfile();
|
||||
|
@ -562,7 +565,7 @@ public class MigrationTest extends K9RobolectricTest {
|
|||
insertPgpInlineClearsignedMessage(db);
|
||||
db.close();
|
||||
|
||||
LocalStore localStore = LocalStore.getInstance(account, RuntimeEnvironment.application);
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
|
||||
LocalMessage msg = localStore.getFolder("dev").getMessage("8");
|
||||
FetchProfile fp = new FetchProfile();
|
||||
|
@ -620,7 +623,7 @@ public class MigrationTest extends K9RobolectricTest {
|
|||
insertMultipartAlternativeMessage(db);
|
||||
db.close();
|
||||
|
||||
LocalStore localStore = LocalStore.getInstance(account, RuntimeEnvironment.application);
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
|
||||
LocalMessage msg = localStore.getFolder("dev").getMessage("9");
|
||||
FetchProfile fp = new FetchProfile();
|
||||
|
@ -685,7 +688,7 @@ public class MigrationTest extends K9RobolectricTest {
|
|||
insertHtmlWithRelatedMessage(db);
|
||||
db.close();
|
||||
|
||||
LocalStore localStore = LocalStore.getInstance(account, RuntimeEnvironment.application);
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
|
||||
LocalMessage msg = localStore.getFolder("dev").getMessage("10");
|
||||
FetchProfile fp = new FetchProfile();
|
||||
|
@ -721,14 +724,9 @@ public class MigrationTest extends K9RobolectricTest {
|
|||
}
|
||||
|
||||
private Account getNewAccount() {
|
||||
Preferences preferences = Preferences.getPreferences(RuntimeEnvironment.application);
|
||||
|
||||
//FIXME: This is a hack to get Preferences into a state where it's safe to call newAccount()
|
||||
preferences.loadAccounts();
|
||||
|
||||
Account account = preferences.newAccount();
|
||||
Account account = new Account(UUID.randomUUID().toString());
|
||||
DI.get(AccountPreferenceSerializer.class).loadDefaults(account);
|
||||
account.setStoreUri("imap+tls+://user:password@imap.example.org");
|
||||
|
||||
return account;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,19 +66,18 @@ import com.fsck.k9.DI;
|
|||
import com.fsck.k9.FontSizes;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.backend.BackendManager;
|
||||
import com.fsck.k9.preferences.Protocols;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.activity.compose.MessageActions;
|
||||
import com.fsck.k9.activity.misc.ExtendedAsyncTask;
|
||||
import com.fsck.k9.activity.misc.NonConfigurationInstance;
|
||||
import com.fsck.k9.activity.setup.AccountSetupBasics;
|
||||
import com.fsck.k9.activity.setup.WelcomeMessage;
|
||||
import com.fsck.k9.backend.BackendManager;
|
||||
import com.fsck.k9.controller.MessagingController;
|
||||
import com.fsck.k9.ui.helper.SizeFormatter;
|
||||
import com.fsck.k9.mail.AuthType;
|
||||
import com.fsck.k9.mail.ServerSettings;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.mailstore.StorageManager;
|
||||
import com.fsck.k9.preferences.Protocols;
|
||||
import com.fsck.k9.preferences.SettingsExporter;
|
||||
import com.fsck.k9.preferences.SettingsImportExportException;
|
||||
import com.fsck.k9.preferences.SettingsImporter;
|
||||
|
@ -86,10 +85,13 @@ import com.fsck.k9.preferences.SettingsImporter.AccountDescription;
|
|||
import com.fsck.k9.preferences.SettingsImporter.AccountDescriptionPair;
|
||||
import com.fsck.k9.preferences.SettingsImporter.ImportContents;
|
||||
import com.fsck.k9.preferences.SettingsImporter.ImportResults;
|
||||
import com.fsck.k9.search.AccountSearchConditions;
|
||||
import com.fsck.k9.search.LocalSearch;
|
||||
import com.fsck.k9.search.SearchAccount;
|
||||
import com.fsck.k9.search.SearchSpecification.Attribute;
|
||||
import com.fsck.k9.search.SearchSpecification.SearchField;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.ui.helper.SizeFormatter;
|
||||
import com.fsck.k9.ui.settings.SettingsActivity;
|
||||
import com.fsck.k9.ui.settings.account.AccountSettingsActivity;
|
||||
import com.fsck.k9.view.ColorChip;
|
||||
|
@ -115,6 +117,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
|
|||
private static final int DIALOG_NO_FILE_MANAGER = 4;
|
||||
|
||||
private final ColorChipProvider colorChipProvider = DI.get(ColorChipProvider.class);
|
||||
private final AccountSearchConditions accountSearchConditions = DI.get(AccountSearchConditions.class);
|
||||
private MessagingController controller;
|
||||
|
||||
/*
|
||||
|
@ -341,28 +344,6 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
|
|||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public static LocalSearch createUnreadSearch(Context context, BaseAccount account) {
|
||||
String searchTitle = context.getString(R.string.search_title, account.getDescription(),
|
||||
context.getString(R.string.unread_modifier));
|
||||
|
||||
LocalSearch search;
|
||||
if (account instanceof SearchAccount) {
|
||||
search = ((SearchAccount) account).getRelatedSearch().clone();
|
||||
search.setName(searchTitle);
|
||||
} else {
|
||||
search = new LocalSearch(searchTitle);
|
||||
search.addAccountUuid(account.getUuid());
|
||||
|
||||
Account realAccount = (Account) account;
|
||||
realAccount.excludeSpecialFolders(search);
|
||||
realAccount.limitToDisplayableFolders(search);
|
||||
}
|
||||
|
||||
search.and(SearchField.READ, "1", Attribute.NOT_EQUALS);
|
||||
|
||||
return search;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
@ -988,7 +969,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
|
|||
mAccount.setEnabled(true);
|
||||
|
||||
// Save the account settings
|
||||
mAccount.save(Preferences.getPreferences(mContext));
|
||||
Preferences.getPreferences(mContext).saveAccount(mAccount);
|
||||
|
||||
// Start services if necessary
|
||||
Core.setServicesEnabled(mContext);
|
||||
|
@ -1048,7 +1029,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
|
|||
if (selectedContextAccount instanceof Account) {
|
||||
Account realAccount = (Account) selectedContextAccount;
|
||||
try {
|
||||
realAccount.getLocalStore().delete();
|
||||
DI.get(LocalStoreProvider.class).getInstance(realAccount).delete();
|
||||
} catch (Exception e) {
|
||||
// Ignore, this may lead to localStores on sd-cards that
|
||||
// are currently not inserted to be left
|
||||
|
@ -1739,8 +1720,8 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
|
|||
search.addAccountUuid(account.getUuid());
|
||||
|
||||
Account realAccount = (Account) account;
|
||||
realAccount.excludeSpecialFolders(search);
|
||||
realAccount.limitToDisplayableFolders(search);
|
||||
accountSearchConditions.excludeSpecialFolders(realAccount, search);
|
||||
accountSearchConditions.limitToDisplayableFolders(realAccount, search);
|
||||
}
|
||||
|
||||
search.and(SearchField.FLAGGED, "1", Attribute.EQUALS);
|
||||
|
@ -1749,7 +1730,9 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
|
|||
}
|
||||
|
||||
private OnClickListener createUnreadSearchListener(BaseAccount account) {
|
||||
LocalSearch search = createUnreadSearch(Accounts.this, account);
|
||||
String searchTitle = getString(R.string.search_title, account.getDescription(), getString(R.string.unread_modifier));
|
||||
LocalSearch search = accountSearchConditions.createUnreadSearch(account, searchTitle);
|
||||
|
||||
return new AccountClickListener(search);
|
||||
}
|
||||
|
||||
|
@ -2048,7 +2031,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener {
|
|||
|
||||
@Override
|
||||
protected Void doInBackground(Void... args) {
|
||||
mAccount.move(Preferences.getPreferences(mContext), mUp);
|
||||
Preferences.getPreferences(mContext).move(mAccount, mUp);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ public class EditIdentity extends K9Activity {
|
|||
identities.add(mIdentityIndex, mIdentity);
|
||||
}
|
||||
|
||||
mAccount.save(Preferences.getPreferences(getApplication().getApplicationContext()));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(mAccount);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import com.fsck.k9.DI;
|
|||
import com.fsck.k9.FontSizes;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.activity.compose.MessageActions;
|
||||
import com.fsck.k9.activity.setup.FolderSettings;
|
||||
|
@ -420,7 +421,7 @@ public class FolderList extends K9ListActivity {
|
|||
|
||||
private void setDisplayMode(FolderMode newMode) {
|
||||
account.setFolderDisplayMode(newMode);
|
||||
account.save(Preferences.getPreferences(this));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(account);
|
||||
if (account.getFolderPushMode() != FolderMode.NONE) {
|
||||
MailService.actionRestartPushers(this, null);
|
||||
}
|
||||
|
@ -742,7 +743,7 @@ public class FolderList extends K9ListActivity {
|
|||
Timber.i("not refreshing folder of unavailable account");
|
||||
return;
|
||||
}
|
||||
localFolder = account.getLocalStore().getFolder(folderServerId);
|
||||
localFolder = DI.get(LocalStoreProvider.class).getInstance(account).getFolder(folderServerId);
|
||||
FolderInfoHolder folderHolder = getFolder(folderServerId);
|
||||
if (folderHolder != null) {
|
||||
folderHolder.populate(context, localFolder, FolderList.this.account, -1);
|
||||
|
|
|
@ -129,7 +129,7 @@ public class ManageIdentities extends ChooseIdentity {
|
|||
private void saveIdentities() {
|
||||
if (mIdentitiesChanged) {
|
||||
mAccount.setIdentities(identities);
|
||||
mAccount.save(Preferences.getPreferences(getApplication().getApplicationContext()));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(mAccount);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -393,7 +393,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
|
|||
signatureView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
requestReadReceipt = account.isMessageReadReceiptAlways();
|
||||
requestReadReceipt = account.isMessageReadReceipt();
|
||||
|
||||
updateFrom();
|
||||
|
||||
|
|
|
@ -300,7 +300,7 @@ public class MessageLoaderHelper {
|
|||
retainCryptoHelperFragment.setData(messageCryptoHelper);
|
||||
}
|
||||
messageCryptoHelper.asyncStartOrResumeProcessingMessage(
|
||||
localMessage, messageCryptoCallback, cachedDecryptionResult, !account.getOpenPgpHideSignOnly());
|
||||
localMessage, messageCryptoCallback, cachedDecryptionResult, !account.isOpenPgpHideSignOnly());
|
||||
}
|
||||
|
||||
private void cancelAndClearCryptoOperation() {
|
||||
|
|
|
@ -51,9 +51,9 @@ import com.fsck.k9.service.DatabaseUpgradeService;
|
|||
* Currently we make no attempts to stop the background code (e.g. {@link MessagingController}) from
|
||||
* opening the accounts' databases. If this happens the upgrade is performed in one of the
|
||||
* background threads and not by {@link DatabaseUpgradeService}. But this is not a problem. Due to
|
||||
* the locking in {@link LocalStore#getInstance(Account, Context)} the upgrade
|
||||
* service will block in the {@link Account#getLocalStore()} call and from the outside (especially
|
||||
* for this activity) it will appear as if {@link DatabaseUpgradeService} is performing the upgrade.
|
||||
* the locking in {@link com.fsck.k9.mailstore.LocalStoreProvider#getInstance(Account)} the upgrade service will block
|
||||
* and from the outside (especially for this activity) it will appear as if
|
||||
* {@link DatabaseUpgradeService} is performing the upgrade.
|
||||
* </p>
|
||||
*/
|
||||
public class UpgradeDatabases extends K9Activity {
|
||||
|
|
|
@ -35,7 +35,6 @@ import com.fsck.k9.mail.Address;
|
|||
import com.fsck.k9.mail.Flag;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.Message.RecipientType;
|
||||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.message.AutocryptStatusInteractor;
|
||||
import com.fsck.k9.message.AutocryptStatusInteractor.RecipientAutocryptStatus;
|
||||
import com.fsck.k9.message.ComposePgpEnableByDefaultDecider;
|
||||
|
@ -307,7 +306,7 @@ public class RecipientPresenter {
|
|||
menu.findItem(R.id.openpgp_encrypt_enable).setVisible(!isEncrypting);
|
||||
menu.findItem(R.id.openpgp_encrypt_disable).setVisible(isEncrypting);
|
||||
|
||||
boolean showSignOnly = !account.getOpenPgpHideSignOnly();
|
||||
boolean showSignOnly = !account.isOpenPgpHideSignOnly();
|
||||
boolean isSignOnly = currentCryptoStatus.isSignOnly();
|
||||
menu.findItem(R.id.openpgp_sign_only).setVisible(showSignOnly && !isSignOnly);
|
||||
menu.findItem(R.id.openpgp_sign_only_disable).setVisible(showSignOnly && isSignOnly);
|
||||
|
@ -429,8 +428,8 @@ public class RecipientPresenter {
|
|||
cryptoEnablePgpInline,
|
||||
account.getAutocryptPreferEncryptMutual(),
|
||||
isReplyToEncryptedMessage,
|
||||
account.getOpenPgpEncryptAllDrafts(),
|
||||
account.getOpenPgpEncryptSubject(),
|
||||
account.isOpenPgpEncryptAllDrafts(),
|
||||
account.isOpenPgpEncryptSubject(),
|
||||
currentCryptoMode);
|
||||
|
||||
if (openPgpProviderState != OpenPgpProviderState.OK) {
|
||||
|
|
|
@ -376,7 +376,7 @@ public class AccountSetupBasics extends K9Activity
|
|||
} else {
|
||||
//We've successfully checked outgoing as well.
|
||||
mAccount.setDescription(mAccount.getEmail());
|
||||
mAccount.save(Preferences.getPreferences(this));
|
||||
Preferences.getPreferences(this).saveAccount(mAccount);
|
||||
Core.setServicesEnabled(this);
|
||||
AccountSetupNames.actionSetNames(this, mAccount);
|
||||
finish();
|
||||
|
|
|
@ -29,6 +29,7 @@ import android.widget.TextView;
|
|||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.Account.SpecialFolderSelection;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.LocalKeyStoreManager;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.activity.K9Activity;
|
||||
import com.fsck.k9.controller.MessagingController;
|
||||
|
@ -42,6 +43,7 @@ import com.fsck.k9.mail.MessagingException;
|
|||
import com.fsck.k9.mail.filter.Hex;
|
||||
import com.fsck.k9.mailstore.LocalFolder;
|
||||
import com.fsck.k9.mailstore.LocalStore;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.ui.R;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
@ -301,7 +303,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||
*/
|
||||
private void acceptCertificate(X509Certificate certificate) {
|
||||
try {
|
||||
mAccount.addCertificate(mDirection.toMailServerDirection(), certificate);
|
||||
DI.get(LocalKeyStoreManager.class).addCertificate(mAccount, mDirection.toMailServerDirection(), certificate);
|
||||
} catch (CertificateException e) {
|
||||
showErrorDialog(
|
||||
R.string.account_setup_failed_dlg_certificate_message_fmt,
|
||||
|
@ -517,7 +519,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||
return;
|
||||
}
|
||||
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
createLocalFolder(localStore, Account.OUTBOX, getString(R.string.special_mailbox_name_outbox));
|
||||
|
||||
if (!account.getStoreUri().startsWith("pop3")) {
|
||||
|
|
|
@ -117,7 +117,7 @@ public class AccountSetupComposition extends K9Activity {
|
|||
mAccount.setSignatureBeforeQuotedText(isSignatureBeforeQuotedText);
|
||||
}
|
||||
|
||||
mAccount.save(Preferences.getPreferences(this));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(mAccount);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -134,7 +134,7 @@ public class AccountSetupComposition extends K9Activity {
|
|||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
mAccount.save(Preferences.getPreferences(this));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(mAccount);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import android.widget.Toast;
|
|||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.Account.FolderMode;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.LocalKeyStoreManager;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.backend.BackendManager;
|
||||
import com.fsck.k9.preferences.Protocols;
|
||||
|
@ -304,7 +305,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||
}
|
||||
mCurrentPortViewSetting = mPortView.getText().toString();
|
||||
|
||||
mSubscribedFoldersOnly.setChecked(mAccount.subscribedFoldersOnly());
|
||||
mSubscribedFoldersOnly.setChecked(mAccount.isSubscribedFoldersOnly());
|
||||
} catch (Exception e) {
|
||||
failure(e);
|
||||
}
|
||||
|
@ -515,7 +516,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||
if (isPushCapable && mAccount.getFolderPushMode() != FolderMode.NONE) {
|
||||
MailService.actionRestartPushers(this, null);
|
||||
}
|
||||
mAccount.save(Preferences.getPreferences(this));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(mAccount);
|
||||
finish();
|
||||
} else {
|
||||
/*
|
||||
|
@ -588,7 +589,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||
mWebdavMailboxPathView.getText().toString());
|
||||
}
|
||||
|
||||
mAccount.deleteCertificate(host, port, MailServerDirection.INCOMING);
|
||||
DI.get(LocalKeyStoreManager.class).deleteCertificate(mAccount, host, port, MailServerDirection.INCOMING);
|
||||
ServerSettings settings = new ServerSettings(mStoreType, host, port,
|
||||
connectionSecurity, authType, username, password, clientCertificateAlias, extra);
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ public class AccountSetupNames extends K9Activity implements OnClickListener {
|
|||
mAccount.setDescription(mDescription.getText().toString());
|
||||
}
|
||||
mAccount.setName(mName.getText().toString());
|
||||
mAccount.save(Preferences.getPreferences(this));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(mAccount);
|
||||
Accounts.listAccounts(this);
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ public class AccountSetupOptions extends K9Activity implements OnClickListener {
|
|||
mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
|
||||
|
||||
mNotifyView.setChecked(mAccount.isNotifyNewMail());
|
||||
mNotifySyncView.setChecked(mAccount.isShowOngoing());
|
||||
mNotifySyncView.setChecked(mAccount.isNotifySync());
|
||||
SpinnerOption.setSpinnerOptionValue(mCheckFrequencyView, mAccount
|
||||
.getAutomaticCheckIntervalMinutes());
|
||||
SpinnerOption.setSpinnerOptionValue(mDisplayCountView, mAccount
|
||||
|
@ -131,7 +131,7 @@ public class AccountSetupOptions extends K9Activity implements OnClickListener {
|
|||
private void onDone() {
|
||||
mAccount.setDescription(mAccount.getEmail());
|
||||
mAccount.setNotifyNewMail(mNotifyView.isChecked());
|
||||
mAccount.setShowOngoing(mNotifySyncView.isChecked());
|
||||
mAccount.setNotifySync(mNotifySyncView.isChecked());
|
||||
mAccount.setAutomaticCheckIntervalMinutes((Integer)((SpinnerOption)mCheckFrequencyView
|
||||
.getSelectedItem()).value);
|
||||
mAccount.setDisplayCount((Integer)((SpinnerOption)mDisplayCountView
|
||||
|
@ -143,7 +143,7 @@ public class AccountSetupOptions extends K9Activity implements OnClickListener {
|
|||
mAccount.setFolderPushMode(Account.FolderMode.NONE);
|
||||
}
|
||||
|
||||
mAccount.save(Preferences.getPreferences(this));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(mAccount);
|
||||
if (mAccount.equals(Preferences.getPreferences(this).getDefaultAccount()) ||
|
||||
getIntent().getBooleanExtra(EXTRA_MAKE_DEFAULT, false)) {
|
||||
Preferences.getPreferences(this).setDefaultAccount(mAccount);
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.widget.Toast;
|
|||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.LocalKeyStoreManager;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.backend.BackendManager;
|
||||
import com.fsck.k9.preferences.Protocols;
|
||||
|
@ -459,7 +460,7 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
|
|||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
if (Intent.ACTION_EDIT.equals(getIntent().getAction())) {
|
||||
mAccount.save(Preferences.getPreferences(this));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(mAccount);
|
||||
finish();
|
||||
} else {
|
||||
AccountSetupOptions.actionOptions(this, mAccount, mMakeDefault);
|
||||
|
@ -490,7 +491,7 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
|
|||
int newPort = Integer.parseInt(mPortView.getText().toString());
|
||||
ServerSettings server = new ServerSettings(Protocols.SMTP, newHost, newPort, securityType, authType, username, password, clientCertificateAlias);
|
||||
uri = backendManager.createTransportUri(server);
|
||||
mAccount.deleteCertificate(newHost, newPort, MailServerDirection.OUTGOING);
|
||||
DI.get(LocalKeyStoreManager.class).deleteCertificate(mAccount, newHost, newPort, MailServerDirection.OUTGOING);
|
||||
mAccount.setTransportUri(uri);
|
||||
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.OUTGOING);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.preference.Preference;
|
|||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.activity.FolderInfoHolder;
|
||||
import com.fsck.k9.activity.K9PreferenceActivity;
|
||||
|
@ -64,7 +65,7 @@ public class FolderSettings extends K9PreferenceActivity {
|
|||
Account mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
|
||||
|
||||
try {
|
||||
LocalStore localStore = mAccount.getLocalStore();
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(mAccount);
|
||||
mFolder = localStore.getFolder(folderServerId);
|
||||
mFolder.open(Folder.OPEN_MODE_RW);
|
||||
} catch (MessagingException me) {
|
||||
|
|
|
@ -838,7 +838,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
account.setSortAscending(this.sortType, this.sortAscending);
|
||||
sortDateAscending = account.isSortAscending(SortType.SORT_DATE);
|
||||
|
||||
account.save(preferences);
|
||||
Preferences.getPreferences(getContext()).saveAccount(account);
|
||||
} else {
|
||||
K9.setSortType(this.sortType);
|
||||
|
||||
|
@ -2442,7 +2442,7 @@ public class MessageListFragment extends Fragment implements OnItemClickListener
|
|||
boolean allowRemoteSearch = false;
|
||||
final Account searchAccount = account;
|
||||
if (searchAccount != null) {
|
||||
allowRemoteSearch = searchAccount.allowRemoteSearch();
|
||||
allowRemoteSearch = searchAccount.isAllowRemoteSearch();
|
||||
}
|
||||
|
||||
return allowRemoteSearch;
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.database.Cursor;
|
|||
import android.text.TextUtils;
|
||||
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.controller.MessageReference;
|
||||
import com.fsck.k9.helper.Utility;
|
||||
|
@ -15,6 +16,7 @@ import com.fsck.k9.mail.Folder;
|
|||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mailstore.LocalFolder;
|
||||
import com.fsck.k9.mailstore.LocalStore;
|
||||
import com.fsck.k9.mailstore.LocalStoreProvider;
|
||||
|
||||
import static com.fsck.k9.fragment.MLFProjectionInfo.SENDER_LIST_COLUMN;
|
||||
|
||||
|
@ -22,7 +24,7 @@ import static com.fsck.k9.fragment.MLFProjectionInfo.SENDER_LIST_COLUMN;
|
|||
public class MlfUtils {
|
||||
|
||||
static LocalFolder getOpenFolder(String folderServerId, Account account) throws MessagingException {
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
|
||||
LocalFolder localFolder = localStore.getFolder(folderServerId);
|
||||
localFolder.open(Folder.OPEN_MODE_RO);
|
||||
return localFolder;
|
||||
|
|
|
@ -118,7 +118,7 @@ public class MessageTopView extends LinearLayout {
|
|||
containerView, false);
|
||||
containerView.addView(view);
|
||||
|
||||
boolean hideUnsignedTextDivider = account.getOpenPgpHideSignOnly();
|
||||
boolean hideUnsignedTextDivider = account.isOpenPgpHideSignOnly();
|
||||
view.displayMessageViewContainer(messageViewInfo, new OnRenderingFinishedListener() {
|
||||
@Override
|
||||
public void onLoadFinished() {
|
||||
|
|
|
@ -19,10 +19,10 @@ class AccountSettingsDataStore(
|
|||
return when (key) {
|
||||
"account_default" -> account == preferences.defaultAccount
|
||||
"mark_message_as_read_on_view" -> account.isMarkMessageAsReadOnView
|
||||
"account_sync_remote_deletetions" -> account.syncRemoteDeletions()
|
||||
"account_sync_remote_deletetions" -> account.isSyncRemoteDeletions
|
||||
"push_poll_on_connect" -> account.isPushPollOnConnect
|
||||
"always_show_cc_bcc" -> account.isAlwaysShowCcBcc
|
||||
"message_read_receipt" -> account.isMessageReadReceiptAlways
|
||||
"message_read_receipt" -> account.isMessageReadReceipt
|
||||
"default_quoted_text_shown" -> account.isDefaultQuotedTextShown
|
||||
"reply_after_quote" -> account.isReplyAfterQuote
|
||||
"strip_signature" -> account.isStripSignature
|
||||
|
@ -31,12 +31,12 @@ class AccountSettingsDataStore(
|
|||
"account_notify_contacts_mail_only" -> account.isNotifyContactsMailOnly
|
||||
"account_vibrate" -> account.notificationSetting.isVibrateEnabled
|
||||
"account_led" -> account.notificationSetting.isLedEnabled
|
||||
"account_notify_sync" -> account.isShowOngoing
|
||||
"notification_opens_unread" -> account.goToUnreadMessageSearch()
|
||||
"remote_search_enabled" -> account.allowRemoteSearch()
|
||||
"openpgp_hide_sign_only" -> account.openPgpHideSignOnly
|
||||
"openpgp_encrypt_subject" -> account.openPgpEncryptSubject
|
||||
"openpgp_encrypt_all_drafts" -> account.openPgpEncryptAllDrafts
|
||||
"account_notify_sync" -> account.isNotifySync
|
||||
"notification_opens_unread" -> account.isGoToUnreadMessageSearch
|
||||
"openpgp_hide_sign_only" -> account.isOpenPgpHideSignOnly
|
||||
"openpgp_encrypt_subject" -> account.isOpenPgpEncryptSubject
|
||||
"openpgp_encrypt_all_drafts" -> account.isOpenPgpEncryptAllDrafts
|
||||
"remote_search_enabled" -> account.isAllowRemoteSearch
|
||||
"autocrypt_prefer_encrypt" -> account.autocryptPreferEncryptMutual
|
||||
"upload_sent_messages" -> account.isUploadSentMessages
|
||||
else -> defValue
|
||||
|
@ -52,24 +52,24 @@ class AccountSettingsDataStore(
|
|||
return
|
||||
}
|
||||
"mark_message_as_read_on_view" -> account.isMarkMessageAsReadOnView = value
|
||||
"account_sync_remote_deletetions" -> account.setSyncRemoteDeletions(value)
|
||||
"account_sync_remote_deletetions" -> account.isSyncRemoteDeletions = value
|
||||
"push_poll_on_connect" -> account.isPushPollOnConnect = value
|
||||
"always_show_cc_bcc" -> account.isAlwaysShowCcBcc = value
|
||||
"message_read_receipt" -> account.setMessageReadReceipt(value)
|
||||
"message_read_receipt" -> account.isMessageReadReceipt = value
|
||||
"default_quoted_text_shown" -> account.isDefaultQuotedTextShown = value
|
||||
"reply_after_quote" -> account.isReplyAfterQuote = value
|
||||
"strip_signature" -> account.isStripSignature = value
|
||||
"account_notify" -> account.isNotifyNewMail = value
|
||||
"account_notify_self" -> account.isNotifySelfNewMail = value
|
||||
"account_notify_contacts_mail_only" -> account.isNotifyContactsMailOnly = value
|
||||
"account_vibrate" -> account.notificationSetting.setVibrate(value)
|
||||
"account_vibrate" -> account.notificationSetting.isVibrateEnabled = value
|
||||
"account_led" -> account.notificationSetting.setLed(value)
|
||||
"account_notify_sync" -> account.isShowOngoing = value
|
||||
"notification_opens_unread" -> account.setGoToUnreadMessageSearch(value)
|
||||
"remote_search_enabled" -> account.setAllowRemoteSearch(value)
|
||||
"openpgp_hide_sign_only" -> account.openPgpHideSignOnly = value
|
||||
"openpgp_encrypt_subject" -> account.openPgpEncryptSubject = value
|
||||
"openpgp_encrypt_all_drafts" -> account.openPgpEncryptAllDrafts = value
|
||||
"account_notify_sync" -> account.isNotifySync = value
|
||||
"notification_opens_unread" -> account.isGoToUnreadMessageSearch = value
|
||||
"remote_search_enabled" -> account.isAllowRemoteSearch = value
|
||||
"openpgp_hide_sign_only" -> account.isOpenPgpHideSignOnly = value
|
||||
"openpgp_encrypt_subject" -> account.isOpenPgpEncryptSubject = value
|
||||
"openpgp_encrypt_all_drafts" -> account.isOpenPgpEncryptAllDrafts = value
|
||||
"autocrypt_prefer_encrypt" -> account.autocryptPreferEncryptMutual = value
|
||||
"upload_sent_messages" -> account.isUploadSentMessages = value
|
||||
else -> return
|
||||
|
@ -194,13 +194,7 @@ class AccountSettingsDataStore(
|
|||
"account_vibrate_pattern" -> account.notificationSetting.vibratePattern = value.toInt()
|
||||
"account_vibrate_times" -> account.notificationSetting.vibrateTimes = value.toInt()
|
||||
"account_remote_search_num_results" -> account.remoteSearchNumResults = value.toInt()
|
||||
"local_storage_provider" -> {
|
||||
executorService.execute {
|
||||
account.localStorageProviderId = value
|
||||
saveSettings()
|
||||
}
|
||||
return
|
||||
}
|
||||
"local_storage_provider" -> account.localStorageProviderId = value
|
||||
"account_ringtone" -> with(account.notificationSetting) {
|
||||
isRingEnabled = true
|
||||
ringtone = value
|
||||
|
@ -218,7 +212,7 @@ class AccountSettingsDataStore(
|
|||
}
|
||||
|
||||
private fun saveSettings() {
|
||||
account.save(preferences)
|
||||
preferences.saveAccount(account)
|
||||
}
|
||||
|
||||
private fun reschedulePoll() {
|
||||
|
|
|
@ -332,7 +332,7 @@ public class OpenPgpAppSelectDialog extends FragmentActivity {
|
|||
|
||||
private void persistOpenPgpProviderSetting(String selectedPackage) {
|
||||
account.setOpenPgpProvider(selectedPackage);
|
||||
account.save(Preferences.getPreferences(this));
|
||||
Preferences.getPreferences(getApplicationContext()).saveAccount(account);
|
||||
}
|
||||
|
||||
public void onDismissApgDialog() {
|
||||
|
|
|
@ -4,7 +4,7 @@ package com.fsck.k9.mail.store;
|
|||
import com.fsck.k9.mail.NetworkType;
|
||||
|
||||
public interface StoreConfig {
|
||||
boolean subscribedFoldersOnly();
|
||||
boolean isSubscribedFoldersOnly();
|
||||
boolean useCompression(NetworkType type);
|
||||
|
||||
String getInboxFolder();
|
||||
|
@ -13,7 +13,7 @@ public interface StoreConfig {
|
|||
|
||||
int getMaximumAutoDownloadMessageSize();
|
||||
|
||||
boolean allowRemoteSearch();
|
||||
boolean isAllowRemoteSearch();
|
||||
boolean isRemoteSearchFullText();
|
||||
|
||||
boolean isPushPollOnConnect();
|
||||
|
|
|
@ -1399,7 +1399,7 @@ public class ImapFolder extends Folder<ImapMessage> {
|
|||
public List<ImapMessage> search(final String queryString, final Set<Flag> requiredFlags,
|
||||
final Set<Flag> forbiddenFlags) throws MessagingException {
|
||||
|
||||
if (!store.getStoreConfig().allowRemoteSearch()) {
|
||||
if (!store.getStoreConfig().isAllowRemoteSearch()) {
|
||||
throw new MessagingException("Your settings do not allow remote searching of this account");
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ public class ImapStore extends RemoteStore {
|
|||
try {
|
||||
List<FolderListItem> folders = listFolders(connection, false);
|
||||
|
||||
if (!mStoreConfig.subscribedFoldersOnly()) {
|
||||
if (!mStoreConfig.isSubscribedFoldersOnly()) {
|
||||
return getFolders(folders);
|
||||
}
|
||||
|
||||
|
|
|
@ -1067,7 +1067,7 @@ public class ImapFolderTest {
|
|||
public void search_withFullTextSearchEnabled_shouldIssueRespectiveCommand() throws Exception {
|
||||
ImapFolder folder = createFolder("Folder");
|
||||
prepareImapFolderForOpen(OPEN_MODE_RO);
|
||||
when(storeConfig.allowRemoteSearch()).thenReturn(true);
|
||||
when(storeConfig.isAllowRemoteSearch()).thenReturn(true);
|
||||
when(storeConfig.isRemoteSearchFullText()).thenReturn(true);
|
||||
setupUidSearchResponses("1 OK SEARCH completed");
|
||||
|
||||
|
@ -1080,7 +1080,7 @@ public class ImapFolderTest {
|
|||
public void search_withFullTextSearchDisabled_shouldIssueRespectiveCommand() throws Exception {
|
||||
ImapFolder folder = createFolder("Folder");
|
||||
prepareImapFolderForOpen(OPEN_MODE_RO);
|
||||
when(storeConfig.allowRemoteSearch()).thenReturn(true);
|
||||
when(storeConfig.isAllowRemoteSearch()).thenReturn(true);
|
||||
when(storeConfig.isRemoteSearchFullText()).thenReturn(false);
|
||||
setupUidSearchResponses("1 OK SEARCH completed");
|
||||
|
||||
|
@ -1092,7 +1092,7 @@ public class ImapFolderTest {
|
|||
@Test
|
||||
public void search_withRemoteSearchDisabled_shouldThrow() throws Exception {
|
||||
ImapFolder folder = createFolder("Folder");
|
||||
when(storeConfig.allowRemoteSearch()).thenReturn(false);
|
||||
when(storeConfig.isAllowRemoteSearch()).thenReturn(false);
|
||||
|
||||
try {
|
||||
folder.search("query", Collections.<Flag>emptySet(), Collections.<Flag>emptySet());
|
||||
|
|
|
@ -142,7 +142,7 @@ public class ImapStoreTest {
|
|||
|
||||
@Test
|
||||
public void getPersonalNamespaces_withoutSubscribedFoldersOnly() throws Exception {
|
||||
when(storeConfig.subscribedFoldersOnly()).thenReturn(false);
|
||||
when(storeConfig.isSubscribedFoldersOnly()).thenReturn(false);
|
||||
ImapConnection imapConnection = mock(ImapConnection.class);
|
||||
List<ImapResponse> imapResponses = Arrays.asList(
|
||||
createImapResponse("* LIST (\\HasNoChildren) \".\" \"INBOX\""),
|
||||
|
@ -162,7 +162,7 @@ public class ImapStoreTest {
|
|||
@Test
|
||||
public void getPersonalNamespaces_withSubscribedFoldersOnly_shouldOnlyReturnExistingSubscribedFolders()
|
||||
throws Exception {
|
||||
when(storeConfig.subscribedFoldersOnly()).thenReturn(true);
|
||||
when(storeConfig.isSubscribedFoldersOnly()).thenReturn(true);
|
||||
ImapConnection imapConnection = mock(ImapConnection.class);
|
||||
List<ImapResponse> lsubResponses = Arrays.asList(
|
||||
createImapResponse("* LSUB (\\HasNoChildren) \".\" \"INBOX\""),
|
||||
|
|
Loading…
Reference in a new issue