Fix code style issues found by ktlint
This commit is contained in:
parent
88d863c4c2
commit
93d0e14b68
204 changed files with 728 additions and 931 deletions
|
@ -6,14 +6,14 @@ import com.fsck.k9.autodiscovery.ConnectionSettingsDiscovery
|
||||||
import com.fsck.k9.backend.BackendManager
|
import com.fsck.k9.backend.BackendManager
|
||||||
import com.fsck.k9.helper.EmailHelper
|
import com.fsck.k9.helper.EmailHelper
|
||||||
import com.fsck.k9.helper.UrlEncodingHelper
|
import com.fsck.k9.helper.UrlEncodingHelper
|
||||||
import org.xmlpull.v1.XmlPullParser
|
|
||||||
import timber.log.Timber
|
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.net.URISyntaxException
|
import java.net.URISyntaxException
|
||||||
|
import org.xmlpull.v1.XmlPullParser
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
class ProvidersXmlDiscovery(
|
class ProvidersXmlDiscovery(
|
||||||
private val backendManager: BackendManager,
|
private val backendManager: BackendManager,
|
||||||
private val xmlProvider: ProvidersXmlProvider
|
private val xmlProvider: ProvidersXmlProvider
|
||||||
) : ConnectionSettingsDiscovery {
|
) : ConnectionSettingsDiscovery {
|
||||||
|
|
||||||
override fun discover(email: String): ConnectionSettings? {
|
override fun discover(email: String): ConnectionSettings? {
|
||||||
|
@ -108,11 +108,10 @@ class ProvidersXmlDiscovery(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal data class Provider(
|
internal data class Provider(
|
||||||
val incomingUriTemplate: String,
|
val incomingUriTemplate: String,
|
||||||
val incomingUsernameTemplate: String,
|
val incomingUsernameTemplate: String,
|
||||||
val outgoingUriTemplate: String,
|
val outgoingUriTemplate: String,
|
||||||
val outgoingUsernameTemplate: String?
|
val outgoingUsernameTemplate: String?
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package com.fsck.k9.autodiscovery.thunderbird
|
package com.fsck.k9.autodiscovery.thunderbird
|
||||||
|
|
||||||
import com.fsck.k9.helper.EmailHelper
|
import com.fsck.k9.helper.EmailHelper
|
||||||
|
import java.io.InputStream
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
class ThunderbirdAutoconfigFetcher(private val okHttpClient: OkHttpClient) {
|
class ThunderbirdAutoconfigFetcher(private val okHttpClient: OkHttpClient) {
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ class ThunderbirdAutoconfigFetcher(private val okHttpClient: OkHttpClient) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// address described at:
|
// address described at:
|
||||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration#Configuration_server_at_ISP
|
// https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration#Configuration_server_at_ISP
|
||||||
|
|
|
@ -4,12 +4,12 @@ import com.fsck.k9.autodiscovery.ConnectionSettings
|
||||||
import com.fsck.k9.mail.AuthType
|
import com.fsck.k9.mail.AuthType
|
||||||
import com.fsck.k9.mail.ConnectionSecurity
|
import com.fsck.k9.mail.ConnectionSecurity
|
||||||
import com.fsck.k9.mail.ServerSettings
|
import com.fsck.k9.mail.ServerSettings
|
||||||
import org.xmlpull.v1.XmlPullParser
|
|
||||||
import org.xmlpull.v1.XmlPullParserException
|
|
||||||
import org.xmlpull.v1.XmlPullParserFactory
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
|
import org.xmlpull.v1.XmlPullParser
|
||||||
|
import org.xmlpull.v1.XmlPullParserException
|
||||||
|
import org.xmlpull.v1.XmlPullParserFactory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parser for Thunderbird's
|
* Parser for Thunderbird's
|
||||||
|
|
|
@ -4,9 +4,9 @@ import com.fsck.k9.autodiscovery.ConnectionSettings
|
||||||
import com.fsck.k9.autodiscovery.ConnectionSettingsDiscovery
|
import com.fsck.k9.autodiscovery.ConnectionSettingsDiscovery
|
||||||
|
|
||||||
class ThunderbirdDiscovery(
|
class ThunderbirdDiscovery(
|
||||||
private val fetcher: ThunderbirdAutoconfigFetcher,
|
private val fetcher: ThunderbirdAutoconfigFetcher,
|
||||||
private val parser: ThunderbirdAutoconfigParser
|
private val parser: ThunderbirdAutoconfigParser
|
||||||
): ConnectionSettingsDiscovery {
|
) : ConnectionSettingsDiscovery {
|
||||||
|
|
||||||
override fun discover(email: String): ConnectionSettings? {
|
override fun discover(email: String): ConnectionSettings? {
|
||||||
val autoconfigInputStream = fetcher.fetchAutoconfigFile(email) ?: return null
|
val autoconfigInputStream = fetcher.fetchAutoconfigFile(email) ?: return null
|
||||||
|
|
|
@ -13,7 +13,6 @@ import org.junit.Test
|
||||||
import org.mockito.ArgumentMatchers.anyString
|
import org.mockito.ArgumentMatchers.anyString
|
||||||
import org.robolectric.RuntimeEnvironment
|
import org.robolectric.RuntimeEnvironment
|
||||||
|
|
||||||
|
|
||||||
class ProvidersXmlDiscoveryTest : RobolectricTest() {
|
class ProvidersXmlDiscoveryTest : RobolectricTest() {
|
||||||
val backendManager = mock<BackendManager> {
|
val backendManager = mock<BackendManager> {
|
||||||
on { decodeStoreUri(anyString()) } doAnswer { mock -> ImapStoreUriDecoder.decode(mock.getArgument(0)) }
|
on { decodeStoreUri(anyString()) } doAnswer { mock -> ImapStoreUriDecoder.decode(mock.getArgument(0)) }
|
||||||
|
@ -24,7 +23,6 @@ class ProvidersXmlDiscoveryTest : RobolectricTest() {
|
||||||
val xmlProvider = ProvidersXmlProvider(RuntimeEnvironment.application)
|
val xmlProvider = ProvidersXmlProvider(RuntimeEnvironment.application)
|
||||||
val providersXmlDiscovery = ProvidersXmlDiscovery(backendManager, xmlProvider)
|
val providersXmlDiscovery = ProvidersXmlDiscovery(backendManager, xmlProvider)
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun discover_withGmailDomain_shouldReturnCorrectSettings() {
|
fun discover_withGmailDomain_shouldReturnCorrectSettings() {
|
||||||
val connectionSettings = providersXmlDiscovery.discover("user@gmail.com")
|
val connectionSettings = providersXmlDiscovery.discover("user@gmail.com")
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
package com.fsck.k9
|
package com.fsck.k9
|
||||||
|
|
||||||
import com.fsck.k9.Account.*
|
import com.fsck.k9.Account.DEFAULT_SORT_ASCENDING
|
||||||
|
import com.fsck.k9.Account.DEFAULT_SORT_TYPE
|
||||||
|
import com.fsck.k9.Account.DeletePolicy
|
||||||
|
import com.fsck.k9.Account.Expunge
|
||||||
|
import com.fsck.k9.Account.FolderMode
|
||||||
|
import com.fsck.k9.Account.INBOX
|
||||||
|
import com.fsck.k9.Account.INTERVAL_MINUTES_NEVER
|
||||||
|
import com.fsck.k9.Account.MessageFormat
|
||||||
|
import com.fsck.k9.Account.NO_OPENPGP_KEY
|
||||||
|
import com.fsck.k9.Account.QuoteStyle
|
||||||
|
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.Account.UNASSIGNED_ACCOUNT_NUMBER
|
||||||
import com.fsck.k9.helper.Utility
|
import com.fsck.k9.helper.Utility
|
||||||
import com.fsck.k9.mail.NetworkType
|
import com.fsck.k9.mail.NetworkType
|
||||||
import com.fsck.k9.mail.filter.Base64
|
import com.fsck.k9.mail.filter.Base64
|
||||||
|
@ -8,23 +22,22 @@ import com.fsck.k9.mailstore.StorageManager
|
||||||
import com.fsck.k9.preferences.Storage
|
import com.fsck.k9.preferences.Storage
|
||||||
import com.fsck.k9.preferences.StorageEditor
|
import com.fsck.k9.preferences.StorageEditor
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class AccountPreferenceSerializer(
|
class AccountPreferenceSerializer(
|
||||||
private val storageManager: StorageManager,
|
private val storageManager: StorageManager,
|
||||||
private val resourceProvider: CoreResourceProvider
|
private val resourceProvider: CoreResourceProvider
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun loadAccount(account: Account, storage: Storage) {
|
fun loadAccount(account: Account, storage: Storage) {
|
||||||
val accountUuid = account.uuid
|
val accountUuid = account.uuid
|
||||||
with (account) {
|
with(account) {
|
||||||
storeUri = Base64.decode(storage.getString("$accountUuid.storeUri", null))
|
storeUri = Base64.decode(storage.getString("$accountUuid.storeUri", null))
|
||||||
localStorageProviderId = storage.getString("$accountUuid.localStorageProvider", storageManager.defaultProviderId)
|
localStorageProviderId = storage.getString("$accountUuid.localStorageProvider", storageManager.defaultProviderId)
|
||||||
transportUri = Base64.decode(storage.getString("$accountUuid.transportUri", null))
|
transportUri = Base64.decode(storage.getString("$accountUuid.transportUri", null))
|
||||||
description = storage.getString("$accountUuid.description", null)
|
description = storage.getString("$accountUuid.description", null)
|
||||||
alwaysBcc = storage.getString("$accountUuid.alwaysBcc", alwaysBcc)
|
alwaysBcc = storage.getString("$accountUuid.alwaysBcc", alwaysBcc)
|
||||||
automaticCheckIntervalMinutes = storage.getInt("$accountUuid.automaticCheckIntervalMinutes", Account.INTERVAL_MINUTES_NEVER)
|
automaticCheckIntervalMinutes = storage.getInt("$accountUuid.automaticCheckIntervalMinutes", INTERVAL_MINUTES_NEVER)
|
||||||
idleRefreshMinutes = storage.getInt("$accountUuid.idleRefreshMinutes", 24)
|
idleRefreshMinutes = storage.getInt("$accountUuid.idleRefreshMinutes", 24)
|
||||||
isPushPollOnConnect = storage.getBoolean("$accountUuid.pushPollOnConnect", true)
|
isPushPollOnConnect = storage.getBoolean("$accountUuid.pushPollOnConnect", true)
|
||||||
displayCount = storage.getInt("$accountUuid.displayCount", K9.DEFAULT_VISIBLE_LIMIT)
|
displayCount = storage.getInt("$accountUuid.displayCount", K9.DEFAULT_VISIBLE_LIMIT)
|
||||||
|
@ -203,7 +216,7 @@ class AccountPreferenceSerializer(
|
||||||
editor.putString("accountUuids", accountUuids)
|
editor.putString("accountUuids", accountUuids)
|
||||||
}
|
}
|
||||||
|
|
||||||
with (account) {
|
with(account) {
|
||||||
editor.putString("$accountUuid.storeUri", Base64.encode(storeUri))
|
editor.putString("$accountUuid.storeUri", Base64.encode(storeUri))
|
||||||
editor.putString("$accountUuid.localStorageProvider", localStorageProviderId)
|
editor.putString("$accountUuid.localStorageProvider", localStorageProviderId)
|
||||||
editor.putString("$accountUuid.transportUri", Base64.encode(transportUri))
|
editor.putString("$accountUuid.transportUri", Base64.encode(transportUri))
|
||||||
|
@ -250,10 +263,10 @@ class AccountPreferenceSerializer(
|
||||||
editor.putBoolean("$accountUuid.subscribedFoldersOnly", isSubscribedFoldersOnly)
|
editor.putBoolean("$accountUuid.subscribedFoldersOnly", isSubscribedFoldersOnly)
|
||||||
editor.putInt("$accountUuid.maximumPolledMessageAge", maximumPolledMessageAge)
|
editor.putInt("$accountUuid.maximumPolledMessageAge", maximumPolledMessageAge)
|
||||||
editor.putInt("$accountUuid.maximumAutoDownloadMessageSize", maximumAutoDownloadMessageSize)
|
editor.putInt("$accountUuid.maximumAutoDownloadMessageSize", maximumAutoDownloadMessageSize)
|
||||||
val messageFormatAuto = if (Account.MessageFormat.AUTO == messageFormat) {
|
val messageFormatAuto = if (MessageFormat.AUTO == messageFormat) {
|
||||||
// saving MessageFormat.AUTO as is to the database will cause downgrades to crash on
|
// 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.
|
// startup, so we save as MessageFormat.TEXT instead with a separate flag for auto.
|
||||||
editor.putString("$accountUuid.messageFormat", Account.MessageFormat.TEXT.name)
|
editor.putString("$accountUuid.messageFormat", MessageFormat.TEXT.name)
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
editor.putString("$accountUuid.messageFormat", messageFormat.name)
|
editor.putString("$accountUuid.messageFormat", messageFormat.name)
|
||||||
|
@ -299,7 +312,6 @@ class AccountPreferenceSerializer(
|
||||||
saveIdentities(account, storage, editor)
|
saveIdentities(account, storage, editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun delete(editor: StorageEditor, storage: Storage, account: Account) {
|
fun delete(editor: StorageEditor, storage: Storage, account: Account) {
|
||||||
val accountUuid = account.uuid
|
val accountUuid = account.uuid
|
||||||
|
@ -413,7 +425,7 @@ class AccountPreferenceSerializer(
|
||||||
deleteIdentities(account, storage, editor)
|
deleteIdentities(account, storage, editor)
|
||||||
var ident = 0
|
var ident = 0
|
||||||
|
|
||||||
with (account) {
|
with(account) {
|
||||||
for (identity in identities) {
|
for (identity in identities) {
|
||||||
editor.putString("$uuid.$IDENTITY_NAME_KEY.$ident", identity.name)
|
editor.putString("$uuid.$IDENTITY_NAME_KEY.$ident", identity.name)
|
||||||
editor.putString("$uuid.$IDENTITY_EMAIL_KEY.$ident", identity.email)
|
editor.putString("$uuid.$IDENTITY_EMAIL_KEY.$ident", identity.email)
|
||||||
|
@ -488,14 +500,13 @@ class AccountPreferenceSerializer(
|
||||||
|
|
||||||
defaultEnum
|
defaultEnum
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadDefaults(account: Account) {
|
fun loadDefaults(account: Account) {
|
||||||
with (account) {
|
with(account) {
|
||||||
localStorageProviderId = storageManager.defaultProviderId
|
localStorageProviderId = storageManager.defaultProviderId
|
||||||
automaticCheckIntervalMinutes = Account.INTERVAL_MINUTES_NEVER
|
automaticCheckIntervalMinutes = INTERVAL_MINUTES_NEVER
|
||||||
idleRefreshMinutes = 24
|
idleRefreshMinutes = 24
|
||||||
isPushPollOnConnect = true
|
isPushPollOnConnect = true
|
||||||
displayCount = K9.DEFAULT_VISIBLE_LIMIT
|
displayCount = K9.DEFAULT_VISIBLE_LIMIT
|
||||||
|
@ -557,7 +568,7 @@ class AccountPreferenceSerializer(
|
||||||
)
|
)
|
||||||
identities.add(identity)
|
identities.add(identity)
|
||||||
|
|
||||||
with (notificationSetting) {
|
with(notificationSetting) {
|
||||||
isVibrateEnabled = false
|
isVibrateEnabled = false
|
||||||
vibratePattern = 0
|
vibratePattern = 0
|
||||||
vibrateTimes = 5
|
vibrateTimes = 5
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package com.fsck.k9
|
package com.fsck.k9
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
|
||||||
fun Activity.finishWithErrorToast(@StringRes errorRes: Int, vararg formatArgs: String) {
|
fun Activity.finishWithErrorToast(@StringRes errorRes: Int, vararg formatArgs: String) {
|
||||||
val text = getString(errorRes, *formatArgs)
|
val text = getString(errorRes, *formatArgs)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package com.fsck.k9
|
package com.fsck.k9
|
||||||
|
|
||||||
data class AppConfig(
|
data class AppConfig(
|
||||||
val componentsToDisable: List<Class<*>>
|
val componentsToDisable: List<Class<*>>
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,8 +13,8 @@ import com.fsck.k9.mail.internet.BinaryTempFileBody
|
||||||
import com.fsck.k9.service.BootReceiver
|
import com.fsck.k9.service.BootReceiver
|
||||||
import com.fsck.k9.service.ShutdownReceiver
|
import com.fsck.k9.service.ShutdownReceiver
|
||||||
import com.fsck.k9.service.StorageGoneReceiver
|
import com.fsck.k9.service.StorageGoneReceiver
|
||||||
import timber.log.Timber
|
|
||||||
import java.util.concurrent.SynchronousQueue
|
import java.util.concurrent.SynchronousQueue
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
object Core : EarlyInit {
|
object Core : EarlyInit {
|
||||||
private val context: Context by inject()
|
private val context: Context by inject()
|
||||||
|
@ -83,7 +83,6 @@ object Core : EarlyInit {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
jobManager.scheduleAllMailJobs()
|
jobManager.scheduleAllMailJobs()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,8 +8,8 @@ import org.koin.core.context.startKoin
|
||||||
import org.koin.core.module.Module
|
import org.koin.core.module.Module
|
||||||
import org.koin.core.parameter.ParametersDefinition
|
import org.koin.core.parameter.ParametersDefinition
|
||||||
import org.koin.core.qualifier.Qualifier
|
import org.koin.core.qualifier.Qualifier
|
||||||
import org.koin.java.KoinJavaComponent.getKoin
|
|
||||||
import org.koin.java.KoinJavaComponent.get as koinGet
|
import org.koin.java.KoinJavaComponent.get as koinGet
|
||||||
|
import org.koin.java.KoinJavaComponent.getKoin
|
||||||
|
|
||||||
object DI {
|
object DI {
|
||||||
private const val DEBUG = false
|
private const val DEBUG = false
|
||||||
|
@ -35,6 +35,6 @@ interface EarlyInit
|
||||||
|
|
||||||
// Copied from ComponentCallbacks.inject()
|
// Copied from ComponentCallbacks.inject()
|
||||||
inline fun <reified T : Any> EarlyInit.inject(
|
inline fun <reified T : Any> EarlyInit.inject(
|
||||||
qualifier: Qualifier? = null,
|
qualifier: Qualifier? = null,
|
||||||
noinline parameters: ParametersDefinition? = null
|
noinline parameters: ParametersDefinition? = null
|
||||||
) = lazy { getKoin().get<T>(qualifier, parameters) }
|
) = lazy { getKoin().get<T>(qualifier, parameters) }
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.fsck.k9
|
||||||
|
|
||||||
import android.text.util.Rfc822Tokenizer
|
import android.text.util.Rfc822Tokenizer
|
||||||
import android.widget.AutoCompleteTextView.Validator
|
import android.widget.AutoCompleteTextView.Validator
|
||||||
|
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
class EmailAddressValidator : Validator {
|
class EmailAddressValidator : Validator {
|
||||||
|
@ -15,8 +14,8 @@ class EmailAddressValidator : Validator {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
//https://www.rfc-editor.org/rfc/rfc2396.txt (3.2.2)
|
// https://www.rfc-editor.org/rfc/rfc2396.txt (3.2.2)
|
||||||
//https://www.rfc-editor.org/rfc/rfc5321.txt (4.1.2)
|
// https://www.rfc-editor.org/rfc/rfc5321.txt (4.1.2)
|
||||||
|
|
||||||
private const val ALPHA = "[a-zA-Z]"
|
private const val ALPHA = "[a-zA-Z]"
|
||||||
private const val ALPHANUM = "[a-zA-Z0-9]"
|
private const val ALPHANUM = "[a-zA-Z0-9]"
|
||||||
|
|
|
@ -5,12 +5,12 @@ import kotlinx.android.parcel.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class Identity(
|
data class Identity(
|
||||||
val description: String? = null,
|
val description: String? = null,
|
||||||
val name: String? = null,
|
val name: String? = null,
|
||||||
val email: String? = null,
|
val email: String? = null,
|
||||||
val signature: String? = null,
|
val signature: String? = null,
|
||||||
val signatureUse: Boolean = false,
|
val signatureUse: Boolean = false,
|
||||||
val replyTo: String? = null
|
val replyTo: String? = null
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
// TODO remove when callers are converted to Kotlin
|
// TODO remove when callers are converted to Kotlin
|
||||||
fun withName(name: String?) = copy(name = name)
|
fun withName(name: String?) = copy(name = name)
|
||||||
|
|
|
@ -15,14 +15,12 @@ import timber.log.Timber.DebugTree
|
||||||
object K9 : EarlyInit {
|
object K9 : EarlyInit {
|
||||||
private val preferences: Preferences by inject()
|
private val preferences: Preferences by inject()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this is `true`, various development settings will be enabled.
|
* If this is `true`, various development settings will be enabled.
|
||||||
*/
|
*/
|
||||||
@JvmField
|
@JvmField
|
||||||
val DEVELOPER_MODE = BuildConfig.DEBUG
|
val DEVELOPER_MODE = BuildConfig.DEBUG
|
||||||
|
|
||||||
|
|
||||||
private const val VERSION_MIGRATE_OPENPGP_TO_ACCOUNTS = 63
|
private const val VERSION_MIGRATE_OPENPGP_TO_ACCOUNTS = 63
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,7 +51,6 @@ object K9 : EarlyInit {
|
||||||
*/
|
*/
|
||||||
private var databasesUpToDate = false
|
private var databasesUpToDate = false
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if we already know whether all databases are using the current database schema.
|
* Check if we already know whether all databases are using the current database schema.
|
||||||
*
|
*
|
||||||
|
@ -132,7 +129,6 @@ object K9 : EarlyInit {
|
||||||
.commit()
|
.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
var isDebugLoggingEnabled: Boolean = DEVELOPER_MODE
|
var isDebugLoggingEnabled: Boolean = DEVELOPER_MODE
|
||||||
set(debug) {
|
set(debug) {
|
||||||
|
@ -319,7 +315,6 @@ object K9 : EarlyInit {
|
||||||
K9.sortAscending[sortType] = sortAscending
|
K9.sortAscending[sortType] = sortAscending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun init(context: Context) {
|
fun init(context: Context) {
|
||||||
K9MailLib.setDebugStatus(object : K9MailLib.DebugStatus {
|
K9MailLib.setDebugStatus(object : K9MailLib.DebugStatus {
|
||||||
override fun enabled(): Boolean = isDebugLoggingEnabled
|
override fun enabled(): Boolean = isDebugLoggingEnabled
|
||||||
|
@ -554,7 +549,6 @@ object K9 : EarlyInit {
|
||||||
const val MAIL_SERVICE_WAKE_LOCK_TIMEOUT = 60000
|
const val MAIL_SERVICE_WAKE_LOCK_TIMEOUT = 60000
|
||||||
const val BOOT_RECEIVER_WAKE_LOCK_TIMEOUT = 60000
|
const val BOOT_RECEIVER_WAKE_LOCK_TIMEOUT = 60000
|
||||||
|
|
||||||
|
|
||||||
enum class AppTheme {
|
enum class AppTheme {
|
||||||
LIGHT,
|
LIGHT,
|
||||||
DARK,
|
DARK,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import java.security.cert.CertificateException
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
|
|
||||||
class LocalKeyStoreManager(
|
class LocalKeyStoreManager(
|
||||||
private val localKeyStore: LocalKeyStore
|
private val localKeyStore: LocalKeyStore
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* Add a new certificate for the incoming or outgoing server to the local key store.
|
* Add a new certificate for the incoming or outgoing server to the local key store.
|
||||||
|
@ -60,4 +60,4 @@ class LocalKeyStoreManager(
|
||||||
localKeyStore.deleteCertificate(uri.host, uri.port)
|
localKeyStore.deleteCertificate(uri.host, uri.port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,14 @@ package com.fsck.k9.autocrypt
|
||||||
|
|
||||||
import com.fsck.k9.message.CryptoStatus
|
import com.fsck.k9.message.CryptoStatus
|
||||||
|
|
||||||
|
data class AutocryptDraftStateHeader(
|
||||||
data class AutocryptDraftStateHeader(val isEncrypt: Boolean,
|
val isEncrypt: Boolean,
|
||||||
val isSignOnly: Boolean,
|
val isSignOnly: Boolean,
|
||||||
val isReply: Boolean,
|
val isReply: Boolean,
|
||||||
val isByChoice: Boolean,
|
val isByChoice: Boolean,
|
||||||
val isPgpInline: Boolean,
|
val isPgpInline: Boolean,
|
||||||
val parameters: Map<String, String> = mapOf()) {
|
val parameters: Map<String, String> = mapOf()
|
||||||
|
) {
|
||||||
|
|
||||||
fun toHeaderValue(): String {
|
fun toHeaderValue(): String {
|
||||||
val builder = StringBuilder()
|
val builder = StringBuilder()
|
||||||
|
@ -42,7 +43,7 @@ data class AutocryptDraftStateHeader(val isEncrypt: Boolean,
|
||||||
const val PARAM_PGP_INLINE = "_pgp-inline"
|
const val PARAM_PGP_INLINE = "_pgp-inline"
|
||||||
const val PARAM_SIGN_ONLY = "_sign-only"
|
const val PARAM_SIGN_ONLY = "_sign-only"
|
||||||
|
|
||||||
const val VALUE_YES = "yes";
|
const val VALUE_YES = "yes"
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun fromCryptoStatus(cryptoStatus: CryptoStatus): AutocryptDraftStateHeader {
|
fun fromCryptoStatus(cryptoStatus: CryptoStatus): AutocryptDraftStateHeader {
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package com.fsck.k9.autocrypt
|
package com.fsck.k9.autocrypt
|
||||||
|
|
||||||
|
|
||||||
import com.fsck.k9.mail.internet.MimeUtility
|
import com.fsck.k9.mail.internet.MimeUtility
|
||||||
|
|
||||||
|
|
||||||
class AutocryptDraftStateHeaderParser internal constructor() {
|
class AutocryptDraftStateHeaderParser internal constructor() {
|
||||||
|
|
||||||
fun parseAutocryptDraftStateHeader(headerValue: String): AutocryptDraftStateHeader? {
|
fun parseAutocryptDraftStateHeader(headerValue: String): AutocryptDraftStateHeader? {
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package com.fsck.k9.autocrypt
|
package com.fsck.k9.autocrypt
|
||||||
|
|
||||||
|
|
||||||
import com.fsck.k9.K9
|
import com.fsck.k9.K9
|
||||||
import com.fsck.k9.mail.Address
|
import com.fsck.k9.mail.Address
|
||||||
import com.fsck.k9.mail.Flag
|
import com.fsck.k9.mail.Flag
|
||||||
import com.fsck.k9.mail.Message
|
import com.fsck.k9.mail.Message
|
||||||
import com.fsck.k9.mail.Message.RecipientType
|
|
||||||
import com.fsck.k9.mail.MessagingException
|
import com.fsck.k9.mail.MessagingException
|
||||||
import com.fsck.k9.mail.internet.MimeBodyPart
|
import com.fsck.k9.mail.internet.MimeBodyPart
|
||||||
import com.fsck.k9.mail.internet.MimeHeader
|
import com.fsck.k9.mail.internet.MimeHeader
|
||||||
|
@ -16,7 +14,6 @@ import com.fsck.k9.mail.internet.TextBody
|
||||||
import com.fsck.k9.mailstore.BinaryMemoryBody
|
import com.fsck.k9.mailstore.BinaryMemoryBody
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
|
|
||||||
class AutocryptTransferMessageCreator(private val stringProvider: AutocryptStringProvider) {
|
class AutocryptTransferMessageCreator(private val stringProvider: AutocryptStringProvider) {
|
||||||
fun createAutocryptTransferMessage(data: ByteArray, address: Address): Message {
|
fun createAutocryptTransferMessage(data: ByteArray, address: Address): Message {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -7,9 +7,8 @@ import com.fsck.k9.mail.ServerSettings
|
||||||
class BackendManager(private val backendFactories: Map<String, BackendFactory>) {
|
class BackendManager(private val backendFactories: Map<String, BackendFactory>) {
|
||||||
private val backendCache = mutableMapOf<String, BackendContainer>()
|
private val backendCache = mutableMapOf<String, BackendContainer>()
|
||||||
|
|
||||||
|
|
||||||
fun getBackend(account: Account): Backend {
|
fun getBackend(account: Account): Backend {
|
||||||
synchronized (backendCache) {
|
synchronized(backendCache) {
|
||||||
val container = backendCache[account.uuid]
|
val container = backendCache[account.uuid]
|
||||||
return if (container != null && isBackendStillValid(container, account)) {
|
return if (container != null && isBackendStillValid(container, account)) {
|
||||||
container.backend
|
container.backend
|
||||||
|
@ -26,7 +25,7 @@ class BackendManager(private val backendFactories: Map<String, BackendFactory>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeBackend(account: Account) {
|
fun removeBackend(account: Account) {
|
||||||
synchronized (backendCache) {
|
synchronized(backendCache) {
|
||||||
backendCache.remove(account.uuid)
|
backendCache.remove(account.uuid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,6 +81,5 @@ class BackendManager(private val backendFactories: Map<String, BackendFactory>)
|
||||||
throw IllegalArgumentException("Unsupported ServerSettings type")
|
throw IllegalArgumentException("Unsupported ServerSettings type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private data class BackendContainer(val backend: Backend, val storeUri: String, val transportUri: String)
|
private data class BackendContainer(val backend: Backend, val storeUri: String, val transportUri: String)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import com.fsck.k9.backend.BackendManager
|
||||||
interface ControllerExtension {
|
interface ControllerExtension {
|
||||||
fun init(controller: MessagingController, backendManager: BackendManager, controllerInternals: ControllerInternals)
|
fun init(controller: MessagingController, backendManager: BackendManager, controllerInternals: ControllerInternals)
|
||||||
|
|
||||||
|
|
||||||
interface ControllerInternals {
|
interface ControllerInternals {
|
||||||
fun put(description: String, listener: MessagingListener?, runnable: Runnable)
|
fun put(description: String, listener: MessagingListener?, runnable: Runnable)
|
||||||
fun putBackground(description: String, listener: MessagingListener?, runnable: Runnable)
|
fun putBackground(description: String, listener: MessagingListener?, runnable: Runnable)
|
||||||
|
|
|
@ -16,10 +16,10 @@ interface UnreadMessageCountProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class DefaultUnreadMessageCountProvider(
|
internal class DefaultUnreadMessageCountProvider(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
private val accountSearchConditions: AccountSearchConditions,
|
private val accountSearchConditions: AccountSearchConditions,
|
||||||
private val localStoreProvider: LocalStoreProvider
|
private val localStoreProvider: LocalStoreProvider
|
||||||
) : UnreadMessageCountProvider {
|
) : UnreadMessageCountProvider {
|
||||||
override fun getUnreadMessageCount(account: Account): Int {
|
override fun getUnreadMessageCount(account: Account): Int {
|
||||||
if (!account.isAvailable(context)) {
|
if (!account.isAvailable(context)) {
|
||||||
|
|
|
@ -9,9 +9,9 @@ interface EncryptionExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
data class EncryptionResult(
|
data class EncryptionResult(
|
||||||
val encryptionType: String,
|
val encryptionType: String,
|
||||||
val attachmentCount: Int,
|
val attachmentCount: Int,
|
||||||
val previewResult: PreviewResult = PreviewResult.encrypted(),
|
val previewResult: PreviewResult = PreviewResult.encrypted(),
|
||||||
val textForSearchIndex: String? = null,
|
val textForSearchIndex: String? = null,
|
||||||
val extraContentValues: ContentValues? = null
|
val extraContentValues: ContentValues? = null
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.fsck.k9.helper
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Access the system clipboard
|
* Access the system clipboard
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,7 +5,6 @@ import com.fsck.k9.Identity
|
||||||
import com.fsck.k9.mail.Message
|
import com.fsck.k9.mail.Message
|
||||||
import com.fsck.k9.mail.Message.RecipientType
|
import com.fsck.k9.mail.Message.RecipientType
|
||||||
|
|
||||||
|
|
||||||
object IdentityHelper {
|
object IdentityHelper {
|
||||||
private val RECIPIENT_TYPES = listOf(
|
private val RECIPIENT_TYPES = listOf(
|
||||||
RecipientType.TO,
|
RecipientType.TO,
|
||||||
|
|
|
@ -5,9 +5,9 @@ import com.fsck.k9.Preferences
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class K9JobManager(
|
class K9JobManager(
|
||||||
private val workManager: WorkManager,
|
private val workManager: WorkManager,
|
||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
private val mailSyncWorkerManager: MailSyncWorkerManager
|
private val mailSyncWorkerManager: MailSyncWorkerManager
|
||||||
) {
|
) {
|
||||||
fun scheduleAllMailJobs() {
|
fun scheduleAllMailJobs() {
|
||||||
Timber.v("scheduling all jobs")
|
Timber.v("scheduling all jobs")
|
||||||
|
|
|
@ -8,13 +8,13 @@ import com.fsck.k9.Preferences
|
||||||
import com.fsck.k9.controller.MessagingController
|
import com.fsck.k9.controller.MessagingController
|
||||||
|
|
||||||
class K9WorkerFactory(
|
class K9WorkerFactory(
|
||||||
private val messagingController: MessagingController,
|
private val messagingController: MessagingController,
|
||||||
private val preferences: Preferences
|
private val preferences: Preferences
|
||||||
) : WorkerFactory() {
|
) : WorkerFactory() {
|
||||||
override fun createWorker(
|
override fun createWorker(
|
||||||
appContext: Context,
|
appContext: Context,
|
||||||
workerClassName: String,
|
workerClassName: String,
|
||||||
workerParameters: WorkerParameters
|
workerParameters: WorkerParameters
|
||||||
): ListenableWorker? {
|
): ListenableWorker? {
|
||||||
return when (workerClassName) {
|
return when (workerClassName) {
|
||||||
MailSyncWorker::class.java.canonicalName -> {
|
MailSyncWorker::class.java.canonicalName -> {
|
||||||
|
|
|
@ -9,10 +9,10 @@ import com.fsck.k9.service.CoreService
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
class MailSyncWorker(
|
class MailSyncWorker(
|
||||||
private val messagingController: MessagingController,
|
private val messagingController: MessagingController,
|
||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
context: Context,
|
context: Context,
|
||||||
parameters: WorkerParameters
|
parameters: WorkerParameters
|
||||||
) : Worker(context, parameters) {
|
) : Worker(context, parameters) {
|
||||||
|
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
|
|
|
@ -7,8 +7,8 @@ import androidx.work.PeriodicWorkRequestBuilder
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import androidx.work.workDataOf
|
import androidx.work.workDataOf
|
||||||
import com.fsck.k9.Account
|
import com.fsck.k9.Account
|
||||||
import timber.log.Timber
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
class MailSyncWorkerManager(private val workManager: WorkManager) {
|
class MailSyncWorkerManager(private val workManager: WorkManager) {
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ import com.fsck.k9.mail.Folder.FolderClass
|
||||||
import com.fsck.k9.mail.Folder.FolderType as RemoteFolderType
|
import com.fsck.k9.mail.Folder.FolderType as RemoteFolderType
|
||||||
|
|
||||||
class FolderRepository(
|
class FolderRepository(
|
||||||
private val localStoreProvider: LocalStoreProvider,
|
private val localStoreProvider: LocalStoreProvider,
|
||||||
private val specialFolderSelectionStrategy: SpecialFolderSelectionStrategy,
|
private val specialFolderSelectionStrategy: SpecialFolderSelectionStrategy,
|
||||||
private val account: Account
|
private val account: Account
|
||||||
) {
|
) {
|
||||||
private val sortForDisplay =
|
private val sortForDisplay =
|
||||||
compareByDescending<DisplayFolder> { it.folder.serverId == account.inboxFolder }
|
compareByDescending<DisplayFolder> { it.folder.serverId == account.inboxFolder }
|
||||||
|
@ -18,7 +18,6 @@ class FolderRepository(
|
||||||
.thenByDescending { it.isInTopGroup }
|
.thenByDescending { it.isInTopGroup }
|
||||||
.thenBy(String.CASE_INSENSITIVE_ORDER) { it.folder.name }
|
.thenBy(String.CASE_INSENSITIVE_ORDER) { it.folder.name }
|
||||||
|
|
||||||
|
|
||||||
fun getRemoteFolderInfo(): RemoteFolderInfo {
|
fun getRemoteFolderInfo(): RemoteFolderInfo {
|
||||||
val folders = getRemoteFolders()
|
val folders = getRemoteFolders()
|
||||||
val automaticSpecialFolders = mapOf(
|
val automaticSpecialFolders = mapOf(
|
||||||
|
@ -104,7 +103,6 @@ class FolderRepository(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun folderTypeOf(serverId: String) = when (serverId) {
|
private fun folderTypeOf(serverId: String) = when (serverId) {
|
||||||
account.inboxFolder -> FolderType.INBOX
|
account.inboxFolder -> FolderType.INBOX
|
||||||
account.outboxFolder -> FolderType.OUTBOX
|
account.outboxFolder -> FolderType.OUTBOX
|
||||||
|
@ -119,7 +117,7 @@ class FolderRepository(
|
||||||
private fun RemoteFolderType.toFolderType(): FolderType = when (this) {
|
private fun RemoteFolderType.toFolderType(): FolderType = when (this) {
|
||||||
RemoteFolderType.REGULAR -> FolderType.REGULAR
|
RemoteFolderType.REGULAR -> FolderType.REGULAR
|
||||||
RemoteFolderType.INBOX -> FolderType.INBOX
|
RemoteFolderType.INBOX -> FolderType.INBOX
|
||||||
RemoteFolderType.OUTBOX -> FolderType.REGULAR // We currently don't support remote Outbox folders
|
RemoteFolderType.OUTBOX -> FolderType.REGULAR // We currently don't support remote Outbox folders
|
||||||
RemoteFolderType.DRAFTS -> FolderType.DRAFTS
|
RemoteFolderType.DRAFTS -> FolderType.DRAFTS
|
||||||
RemoteFolderType.SENT -> FolderType.SENT
|
RemoteFolderType.SENT -> FolderType.SENT
|
||||||
RemoteFolderType.TRASH -> FolderType.TRASH
|
RemoteFolderType.TRASH -> FolderType.TRASH
|
||||||
|
@ -131,9 +129,9 @@ class FolderRepository(
|
||||||
data class Folder(val id: Long, val serverId: String, val name: String, val type: FolderType)
|
data class Folder(val id: Long, val serverId: String, val name: String, val type: FolderType)
|
||||||
|
|
||||||
data class DisplayFolder(
|
data class DisplayFolder(
|
||||||
val folder: Folder,
|
val folder: Folder,
|
||||||
val isInTopGroup: Boolean,
|
val isInTopGroup: Boolean,
|
||||||
val unreadCount: Int
|
val unreadCount: Int
|
||||||
)
|
)
|
||||||
|
|
||||||
data class RemoteFolderInfo(val folders: List<Folder>, val automaticSpecialFolders: Map<FolderType, Folder?>)
|
data class RemoteFolderInfo(val folders: List<Folder>, val automaticSpecialFolders: Map<FolderType, Folder?>)
|
||||||
|
|
|
@ -3,8 +3,8 @@ package com.fsck.k9.mailstore
|
||||||
import com.fsck.k9.Account
|
import com.fsck.k9.Account
|
||||||
|
|
||||||
class FolderRepositoryManager(
|
class FolderRepositoryManager(
|
||||||
private val localStoreProvider: LocalStoreProvider,
|
private val localStoreProvider: LocalStoreProvider,
|
||||||
private val specialFolderSelectionStrategy: SpecialFolderSelectionStrategy
|
private val specialFolderSelectionStrategy: SpecialFolderSelectionStrategy
|
||||||
) {
|
) {
|
||||||
fun getFolderRepository(account: Account) = FolderRepository(localStoreProvider, specialFolderSelectionStrategy, account)
|
fun getFolderRepository(account: Account) = FolderRepository(localStoreProvider, specialFolderSelectionStrategy, account)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.fsck.k9.mailstore
|
||||||
|
|
||||||
import com.fsck.k9.mail.Folder.FolderType
|
import com.fsck.k9.mail.Folder.FolderType
|
||||||
|
|
||||||
|
|
||||||
@JvmName("fromDatabaseFolderType")
|
@JvmName("fromDatabaseFolderType")
|
||||||
fun String.toFolderType(): FolderType {
|
fun String.toFolderType(): FolderType {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
|
|
|
@ -14,10 +14,10 @@ import com.fsck.k9.mail.Message
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
class K9BackendFolder(
|
class K9BackendFolder(
|
||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
private val account: Account,
|
private val account: Account,
|
||||||
private val localStore: LocalStore,
|
private val localStore: LocalStore,
|
||||||
private val folderServerId: String
|
private val folderServerId: String
|
||||||
) : BackendFolder {
|
) : BackendFolder {
|
||||||
private val database = localStore.database
|
private val database = localStore.database
|
||||||
private val databaseId: String
|
private val databaseId: String
|
||||||
|
@ -25,7 +25,6 @@ class K9BackendFolder(
|
||||||
override val name: String
|
override val name: String
|
||||||
override val visibleLimit: Int
|
override val visibleLimit: Int
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
data class Init(val databaseId: String, val name: String, val visibleLimit: Int)
|
data class Init(val databaseId: String, val name: String, val visibleLimit: Int)
|
||||||
|
|
||||||
|
@ -283,12 +282,11 @@ class K9BackendFolder(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun LockableDatabase.getString(
|
private fun LockableDatabase.getString(
|
||||||
table: String = "folders",
|
table: String = "folders",
|
||||||
column: String,
|
column: String,
|
||||||
selection: String = "id = ?",
|
selection: String = "id = ?",
|
||||||
vararg selectionArgs: String = arrayOf(databaseId)
|
vararg selectionArgs: String = arrayOf(databaseId)
|
||||||
): String? {
|
): String? {
|
||||||
return execute(false) { db ->
|
return execute(false) { db ->
|
||||||
val cursor = db.query(table, arrayOf(column), selection, selectionArgs, null, null, null)
|
val cursor = db.query(table, arrayOf(column), selection, selectionArgs, null, null, null)
|
||||||
|
@ -303,10 +301,10 @@ class K9BackendFolder(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LockableDatabase.getStringOrNull(
|
private fun LockableDatabase.getStringOrNull(
|
||||||
table: String = "folders",
|
table: String = "folders",
|
||||||
column: String,
|
column: String,
|
||||||
selection: String = "id = ?",
|
selection: String = "id = ?",
|
||||||
vararg selectionArgs: String = arrayOf(databaseId)
|
vararg selectionArgs: String = arrayOf(databaseId)
|
||||||
): String? {
|
): String? {
|
||||||
return execute(false) { db ->
|
return execute(false) { db ->
|
||||||
val cursor = db.query(table, arrayOf(column), selection, selectionArgs, null, null, null)
|
val cursor = db.query(table, arrayOf(column), selection, selectionArgs, null, null, null)
|
||||||
|
@ -321,11 +319,11 @@ class K9BackendFolder(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LockableDatabase.setString(
|
private fun LockableDatabase.setString(
|
||||||
table: String = "folders",
|
table: String = "folders",
|
||||||
column: String,
|
column: String,
|
||||||
value: String?,
|
value: String?,
|
||||||
selection: String = "id = ?",
|
selection: String = "id = ?",
|
||||||
vararg selectionArgs: String = arrayOf(databaseId)
|
vararg selectionArgs: String = arrayOf(databaseId)
|
||||||
) {
|
) {
|
||||||
execute(false) { db ->
|
execute(false) { db ->
|
||||||
val contentValues = ContentValues().apply {
|
val contentValues = ContentValues().apply {
|
||||||
|
@ -336,9 +334,9 @@ class K9BackendFolder(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LockableDatabase.setMessagesBoolean(
|
private fun LockableDatabase.setMessagesBoolean(
|
||||||
messageServerId: String,
|
messageServerId: String,
|
||||||
column: String,
|
column: String,
|
||||||
value: Boolean
|
value: Boolean
|
||||||
) {
|
) {
|
||||||
execute(false) { db ->
|
execute(false) { db ->
|
||||||
val contentValues = ContentValues().apply {
|
val contentValues = ContentValues().apply {
|
||||||
|
@ -349,10 +347,10 @@ class K9BackendFolder(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LockableDatabase.getLongOrNull(
|
private fun LockableDatabase.getLongOrNull(
|
||||||
table: String = "folders",
|
table: String = "folders",
|
||||||
column: String,
|
column: String,
|
||||||
selection: String = "id = ?",
|
selection: String = "id = ?",
|
||||||
vararg selectionArgs: String = arrayOf(databaseId)
|
vararg selectionArgs: String = arrayOf(databaseId)
|
||||||
): Long? {
|
): Long? {
|
||||||
return execute(false) { db ->
|
return execute(false) { db ->
|
||||||
val cursor = db.query(table, arrayOf(column), selection, selectionArgs, null, null, null)
|
val cursor = db.query(table, arrayOf(column), selection, selectionArgs, null, null, null)
|
||||||
|
@ -367,11 +365,11 @@ class K9BackendFolder(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LockableDatabase.setLong(
|
private fun LockableDatabase.setLong(
|
||||||
table: String = "folders",
|
table: String = "folders",
|
||||||
column: String,
|
column: String,
|
||||||
value: Long,
|
value: Long,
|
||||||
selection: String = "id = ?",
|
selection: String = "id = ?",
|
||||||
vararg selectionArgs: String = arrayOf(databaseId)
|
vararg selectionArgs: String = arrayOf(databaseId)
|
||||||
) {
|
) {
|
||||||
execute(false) { db ->
|
execute(false) { db ->
|
||||||
val contentValues = ContentValues().apply {
|
val contentValues = ContentValues().apply {
|
||||||
|
|
|
@ -11,14 +11,13 @@ import com.fsck.k9.backend.api.FolderInfo
|
||||||
import com.fsck.k9.mail.Folder.FolderType as RemoteFolderType
|
import com.fsck.k9.mail.Folder.FolderType as RemoteFolderType
|
||||||
|
|
||||||
class K9BackendStorage(
|
class K9BackendStorage(
|
||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
private val account: Account,
|
private val account: Account,
|
||||||
private val localStore: LocalStore,
|
private val localStore: LocalStore,
|
||||||
private val specialFolderUpdater: SpecialFolderUpdater
|
private val specialFolderUpdater: SpecialFolderUpdater
|
||||||
) : BackendStorage {
|
) : BackendStorage {
|
||||||
private val database = localStore.database
|
private val database = localStore.database
|
||||||
|
|
||||||
|
|
||||||
override fun getFolder(folderServerId: String): BackendFolder {
|
override fun getFolder(folderServerId: String): BackendFolder {
|
||||||
return K9BackendFolder(preferences, account, localStore, folderServerId)
|
return K9BackendFolder(preferences, account, localStore, folderServerId)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@ import com.fsck.k9.Account
|
||||||
import com.fsck.k9.Preferences
|
import com.fsck.k9.Preferences
|
||||||
|
|
||||||
class K9BackendStorageFactory(
|
class K9BackendStorageFactory(
|
||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
private val folderRepositoryManager: FolderRepositoryManager,
|
private val folderRepositoryManager: FolderRepositoryManager,
|
||||||
private val localStoreProvider: LocalStoreProvider
|
private val localStoreProvider: LocalStoreProvider
|
||||||
) {
|
) {
|
||||||
fun createBackendStorage(account: Account): K9BackendStorage {
|
fun createBackendStorage(account: Account): K9BackendStorage {
|
||||||
val folderRepository = folderRepositoryManager.getFolderRepository(account)
|
val folderRepository = folderRepositoryManager.getFolderRepository(account)
|
||||||
|
|
|
@ -27,4 +27,4 @@ class LocalStoreProvider {
|
||||||
val accountUuid = account.uuid
|
val accountUuid = account.uuid
|
||||||
localStores.remove(accountUuid)
|
localStores.remove(accountUuid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,12 @@ package com.fsck.k9.mailstore
|
||||||
|
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
|
|
||||||
|
|
||||||
internal fun <T> LockableDatabase.query(
|
internal fun <T> LockableDatabase.query(
|
||||||
table: String,
|
table: String,
|
||||||
columns: Array<String>,
|
columns: Array<String>,
|
||||||
selection: String?,
|
selection: String?,
|
||||||
vararg selectionArgs: String,
|
vararg selectionArgs: String,
|
||||||
block: (Cursor) -> T
|
block: (Cursor) -> T
|
||||||
): T {
|
): T {
|
||||||
return execute(false) { db ->
|
return execute(false) { db ->
|
||||||
val cursor = db.query(table, columns, selection, selectionArgs, null, null, null)
|
val cursor = db.query(table, columns, selection, selectionArgs, null, null, null)
|
||||||
|
|
|
@ -6,9 +6,9 @@ import com.fsck.k9.message.html.HtmlProcessorFactory
|
||||||
import com.fsck.k9.message.html.HtmlSettings
|
import com.fsck.k9.message.html.HtmlSettings
|
||||||
|
|
||||||
class MessageViewInfoExtractorFactory(
|
class MessageViewInfoExtractorFactory(
|
||||||
private val attachmentInfoExtractor: AttachmentInfoExtractor,
|
private val attachmentInfoExtractor: AttachmentInfoExtractor,
|
||||||
private val htmlProcessorFactory: HtmlProcessorFactory,
|
private val htmlProcessorFactory: HtmlProcessorFactory,
|
||||||
private val resourceProvider: CoreResourceProvider
|
private val resourceProvider: CoreResourceProvider
|
||||||
) {
|
) {
|
||||||
fun create(settings: HtmlSettings): MessageViewInfoExtractor {
|
fun create(settings: HtmlSettings): MessageViewInfoExtractor {
|
||||||
val htmlProcessor = htmlProcessorFactory.create(settings)
|
val htmlProcessor = htmlProcessorFactory.create(settings)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package com.fsck.k9.mailstore
|
package com.fsck.k9.mailstore
|
||||||
|
|
||||||
data class OutboxState(
|
data class OutboxState(
|
||||||
val sendState: SendState,
|
val sendState: SendState,
|
||||||
val numberOfSendAttempts: Int,
|
val numberOfSendAttempts: Int,
|
||||||
val sendError: String?,
|
val sendError: String?,
|
||||||
val sendErrorTimestamp: Long
|
val sendErrorTimestamp: Long
|
||||||
)
|
)
|
||||||
|
|
|
@ -95,7 +95,6 @@ class OutboxStateRepository(private val database: LockableDatabase, private val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TABLE_NAME = "outbox_state"
|
private const val TABLE_NAME = "outbox_state"
|
||||||
private const val COLUMN_MESSAGE_ID = "message_id"
|
private const val COLUMN_MESSAGE_ID = "message_id"
|
||||||
|
|
|
@ -9,9 +9,9 @@ import com.fsck.k9.Preferences
|
||||||
* as [SpecialFolderSelection.MANUAL] but have been deleted from the server.
|
* as [SpecialFolderSelection.MANUAL] but have been deleted from the server.
|
||||||
*/
|
*/
|
||||||
class SpecialFolderUpdater(
|
class SpecialFolderUpdater(
|
||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
private val folderRepository: FolderRepository,
|
private val folderRepository: FolderRepository,
|
||||||
private val account: Account
|
private val account: Account
|
||||||
) {
|
) {
|
||||||
fun updateSpecialFolders() {
|
fun updateSpecialFolders() {
|
||||||
val (folders, automaticSpecialFolders) = folderRepository.getRemoteFolderInfo()
|
val (folders, automaticSpecialFolders) = folderRepository.getRemoteFolderInfo()
|
||||||
|
@ -31,9 +31,9 @@ class SpecialFolderUpdater(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSpecialFolder(
|
private fun updateSpecialFolder(
|
||||||
type: FolderType,
|
type: FolderType,
|
||||||
folders: List<Folder>,
|
folders: List<Folder>,
|
||||||
automaticSpecialFolders: Map<FolderType, Folder?>
|
automaticSpecialFolders: Map<FolderType, Folder?>
|
||||||
) {
|
) {
|
||||||
when (getSpecialFolderSelection(type)) {
|
when (getSpecialFolderSelection(type)) {
|
||||||
SpecialFolderSelection.AUTOMATIC -> {
|
SpecialFolderSelection.AUTOMATIC -> {
|
||||||
|
|
|
@ -7,7 +7,6 @@ interface Attachment {
|
||||||
val name: String?
|
val name: String?
|
||||||
val size: Long?
|
val size: Long?
|
||||||
|
|
||||||
|
|
||||||
enum class LoadingState {
|
enum class LoadingState {
|
||||||
URI_ONLY,
|
URI_ONLY,
|
||||||
METADATA,
|
METADATA,
|
||||||
|
|
|
@ -11,14 +11,12 @@ internal object DividerReplacer : TextToHtml.HtmlModifier {
|
||||||
"(?:\\n|$)" +
|
"(?:\\n|$)" +
|
||||||
")+")
|
")+")
|
||||||
|
|
||||||
|
|
||||||
override fun findModifications(text: CharSequence): List<HtmlModification> {
|
override fun findModifications(text: CharSequence): List<HtmlModification> {
|
||||||
return PATTERN.findAll(text).map { matchResult ->
|
return PATTERN.findAll(text).map { matchResult ->
|
||||||
Divider(matchResult.range.start, matchResult.range.endInclusive + 1)
|
Divider(matchResult.range.start, matchResult.range.endInclusive + 1)
|
||||||
}.toList()
|
}.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Divider(startIndex: Int, endIndex: Int) : HtmlModification.Replace(startIndex, endIndex) {
|
class Divider(startIndex: Int, endIndex: Int) : HtmlModification.Replace(startIndex, endIndex) {
|
||||||
override fun replace(textToHtml: TextToHtml) {
|
override fun replace(textToHtml: TextToHtml) {
|
||||||
textToHtml.appendHtml("<hr>")
|
textToHtml.appendHtml("<hr>")
|
||||||
|
|
|
@ -90,7 +90,6 @@ class EmailSection private constructor(builder: Builder) : CharSequence {
|
||||||
}
|
}
|
||||||
}.toString()
|
}.toString()
|
||||||
|
|
||||||
|
|
||||||
internal data class Segment(val startIndex: Int, val endIndex: Int)
|
internal data class Segment(val startIndex: Int, val endIndex: Int)
|
||||||
|
|
||||||
class Builder(val text: String, val quoteDepth: Int) {
|
class Builder(val text: String, val quoteDepth: Int) {
|
||||||
|
@ -114,4 +113,3 @@ class EmailSection private constructor(builder: Builder) : CharSequence {
|
||||||
fun build() = EmailSection(this)
|
fun build() = EmailSection(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,6 @@ class EmailTextToHtml private constructor(private val text: String) {
|
||||||
else -> "#ccc"
|
else -> "#ccc"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val EXTRA_BUFFER_LENGTH = 2048
|
private const val EXTRA_BUFFER_LENGTH = 2048
|
||||||
const val K9MAIL_CSS_CLASS = "k9mail"
|
const val K9MAIL_CSS_CLASS = "k9mail"
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.fsck.k9.message.html
|
package com.fsck.k9.message.html
|
||||||
|
|
||||||
|
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,15 +12,14 @@ object HtmlConverter {
|
||||||
* define the object character and the replacement character.
|
* define the object character and the replacement character.
|
||||||
*/
|
*/
|
||||||
private const val PREVIEW_OBJECT_CHARACTER = 0xfffc.toChar()
|
private const val PREVIEW_OBJECT_CHARACTER = 0xfffc.toChar()
|
||||||
private const val PREVIEW_OBJECT_REPLACEMENT = 0x20.toChar() // space
|
private const val PREVIEW_OBJECT_REPLACEMENT = 0x20.toChar() // space
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toHtml() converts non-breaking spaces into the UTF-8 non-breaking space, which doesn't get
|
* toHtml() converts non-breaking spaces into the UTF-8 non-breaking space, which doesn't get
|
||||||
* rendered properly in some clients. Replace it with a simple space.
|
* rendered properly in some clients. Replace it with a simple space.
|
||||||
*/
|
*/
|
||||||
private const val NBSP_CHARACTER = 0x00a0.toChar() // utf-8 non-breaking space
|
private const val NBSP_CHARACTER = 0x00a0.toChar() // utf-8 non-breaking space
|
||||||
private const val NBSP_REPLACEMENT = 0x20.toChar() // space
|
private const val NBSP_REPLACEMENT = 0x20.toChar() // space
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert an HTML string to a plain text string.
|
* Convert an HTML string to a plain text string.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package com.fsck.k9.message.html
|
package com.fsck.k9.message.html
|
||||||
|
|
||||||
class HtmlProcessorFactory(
|
class HtmlProcessorFactory(
|
||||||
private val htmlSanitizer: HtmlSanitizer,
|
private val htmlSanitizer: HtmlSanitizer,
|
||||||
private val displayHtmlFactory: DisplayHtmlFactory
|
private val displayHtmlFactory: DisplayHtmlFactory
|
||||||
) {
|
) {
|
||||||
fun create(settings: HtmlSettings): HtmlProcessor {
|
fun create(settings: HtmlSettings): HtmlProcessor {
|
||||||
val displayHtml = displayHtmlFactory.create(settings)
|
val displayHtml = displayHtmlFactory.create(settings)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.fsck.k9.message.html
|
package com.fsck.k9.message.html
|
||||||
|
|
||||||
data class HtmlSettings(
|
data class HtmlSettings(
|
||||||
val useDarkMode: Boolean,
|
val useDarkMode: Boolean,
|
||||||
val useFixedWidthFont: Boolean
|
val useFixedWidthFont: Boolean
|
||||||
)
|
)
|
||||||
|
|
|
@ -117,7 +117,6 @@ private class FormattingVisitor : NodeVisitor {
|
||||||
return output.substring(0, lastIndex + 1)
|
return output.substring(0, lastIndex + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val MAX_WIDTH = 76
|
private const val MAX_WIDTH = 76
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,10 @@ internal object UriLinkifier : TextToHtml.HtmlModifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class LinkifyUri(
|
class LinkifyUri(
|
||||||
startIndex: Int,
|
startIndex: Int,
|
||||||
endIndex: Int,
|
endIndex: Int,
|
||||||
val uri: CharSequence
|
val uri: CharSequence
|
||||||
) : HtmlModification.Wrap(startIndex, endIndex) {
|
) : HtmlModification.Wrap(startIndex, endIndex) {
|
||||||
|
|
||||||
override fun appendPrefix(textToHtml: TextToHtml) {
|
override fun appendPrefix(textToHtml: TextToHtml) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.fsck.k9.message.html
|
package com.fsck.k9.message.html
|
||||||
|
|
||||||
data class UriMatch(
|
data class UriMatch(
|
||||||
val startIndex: Int,
|
val startIndex: Int,
|
||||||
val endIndex: Int,
|
val endIndex: Int,
|
||||||
val uri: CharSequence
|
val uri: CharSequence
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.fsck.k9.message.html
|
package com.fsck.k9.message.html
|
||||||
|
|
||||||
import java.util.*
|
import java.util.Locale
|
||||||
|
|
||||||
object UriMatcher {
|
object UriMatcher {
|
||||||
private val SUPPORTED_URIS = { httpUriParser: HttpUriParser ->
|
private val SUPPORTED_URIS = { httpUriParser: HttpUriParser ->
|
||||||
|
@ -20,7 +20,6 @@ object UriMatcher {
|
||||||
RegexOption.IGNORE_CASE
|
RegexOption.IGNORE_CASE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
fun findUris(text: CharSequence): List<UriMatch> {
|
fun findUris(text: CharSequence): List<UriMatch> {
|
||||||
return URI_SCHEME.findAll(text).map { matchResult ->
|
return URI_SCHEME.findAll(text).map { matchResult ->
|
||||||
val matchGroup = matchResult.groups[1]!!
|
val matchGroup = matchResult.groups[1]!!
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.fsck.k9.message.html
|
package com.fsck.k9.message.html
|
||||||
|
|
||||||
|
|
||||||
internal interface UriParser {
|
internal interface UriParser {
|
||||||
/**
|
/**
|
||||||
* Parse scheme specific URI beginning from given position.
|
* Parse scheme specific URI beginning from given position.
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
package com.fsck.k9.message.quote
|
package com.fsck.k9.message.quote
|
||||||
|
|
||||||
|
import android.content.res.Resources
|
||||||
|
import com.fsck.k9.K9
|
||||||
|
import com.fsck.k9.mail.Message
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.TimeZone
|
import java.util.TimeZone
|
||||||
|
|
||||||
import android.content.res.Resources
|
|
||||||
|
|
||||||
import com.fsck.k9.K9
|
|
||||||
import com.fsck.k9.mail.Message
|
|
||||||
|
|
||||||
|
|
||||||
class QuoteHelper(private val resources: Resources) {
|
class QuoteHelper(private val resources: Resources) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,7 +37,6 @@ class QuoteHelper(private val resources: Resources) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// amount of extra buffer to allocate to accommodate quoting headers or prefixes
|
// amount of extra buffer to allocate to accommodate quoting headers or prefixes
|
||||||
const val QUOTE_BUFFER_LENGTH = 512
|
const val QUOTE_BUFFER_LENGTH = 512
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.fsck.k9.message.quote
|
package com.fsck.k9.message.quote
|
||||||
|
|
||||||
|
|
||||||
import com.fsck.k9.Account.QuoteStyle
|
import com.fsck.k9.Account.QuoteStyle
|
||||||
import com.fsck.k9.CoreResourceProvider
|
import com.fsck.k9.CoreResourceProvider
|
||||||
import com.fsck.k9.mail.Address
|
import com.fsck.k9.mail.Address
|
||||||
|
@ -8,16 +7,14 @@ import com.fsck.k9.mail.Message
|
||||||
import com.fsck.k9.mail.Message.RecipientType
|
import com.fsck.k9.mail.Message.RecipientType
|
||||||
import com.fsck.k9.message.quote.QuoteHelper.Companion.QUOTE_BUFFER_LENGTH
|
import com.fsck.k9.message.quote.QuoteHelper.Companion.QUOTE_BUFFER_LENGTH
|
||||||
|
|
||||||
|
|
||||||
class TextQuoteCreator(private val quoteHelper: QuoteHelper, private val resourceProvider: CoreResourceProvider) {
|
class TextQuoteCreator(private val quoteHelper: QuoteHelper, private val resourceProvider: CoreResourceProvider) {
|
||||||
private val prefixInsertionRegex = Regex("(?m)^")
|
private val prefixInsertionRegex = Regex("(?m)^")
|
||||||
|
|
||||||
|
|
||||||
fun quoteOriginalTextMessage(
|
fun quoteOriginalTextMessage(
|
||||||
originalMessage: Message,
|
originalMessage: Message,
|
||||||
messageBody: String?,
|
messageBody: String?,
|
||||||
quoteStyle: QuoteStyle,
|
quoteStyle: QuoteStyle,
|
||||||
prefix: String
|
prefix: String
|
||||||
): String {
|
): String {
|
||||||
val body = messageBody ?: ""
|
val body = messageBody ?: ""
|
||||||
return when (quoteStyle) {
|
return when (quoteStyle) {
|
||||||
|
@ -96,7 +93,6 @@ class TextQuoteCreator(private val quoteHelper: QuoteHelper, private val resourc
|
||||||
|
|
||||||
private fun Array<Address>.displayString() = Address.toString(this)?.let { if (it.isEmpty()) null else it }
|
private fun Array<Address>.displayString() = Address.toString(this)?.let { if (it.isEmpty()) null else it }
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val CRLF = "\r\n"
|
private const val CRLF = "\r\n"
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ import android.app.NotificationManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import com.fsck.k9.AccountPreferenceSerializer
|
import com.fsck.k9.AccountPreferenceSerializer
|
||||||
import org.koin.dsl.module
|
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
import org.koin.dsl.module
|
||||||
|
|
||||||
val coreNotificationModule = module {
|
val coreNotificationModule = module {
|
||||||
single { NotificationController(get(), get(), get(), get(), get()) }
|
single { NotificationController(get(), get(), get(), get(), get()) }
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.fsck.k9.notification
|
package com.fsck.k9.notification
|
||||||
|
|
||||||
|
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationChannelGroup
|
import android.app.NotificationChannelGroup
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
|
@ -11,10 +10,10 @@ import com.fsck.k9.Preferences
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
|
|
||||||
class NotificationChannelManager(
|
class NotificationChannelManager(
|
||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
private val backgroundExecutor: Executor,
|
private val backgroundExecutor: Executor,
|
||||||
private val notificationManager: NotificationManager,
|
private val notificationManager: NotificationManager,
|
||||||
private val resourceProvider: NotificationResourceProvider
|
private val resourceProvider: NotificationResourceProvider
|
||||||
) {
|
) {
|
||||||
|
|
||||||
enum class ChannelType {
|
enum class ChannelType {
|
||||||
|
@ -36,12 +35,13 @@ class NotificationChannelManager(
|
||||||
removeChannelsForNonExistingOrChangedAccounts(notificationManager, accounts)
|
removeChannelsForNonExistingOrChangedAccounts(notificationManager, accounts)
|
||||||
addChannelsForAccounts(notificationManager, accounts)
|
addChannelsForAccounts(notificationManager, accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
private fun addChannelsForAccounts(
|
private fun addChannelsForAccounts(
|
||||||
notificationManager: NotificationManager, accounts: List<Account>) {
|
notificationManager: NotificationManager,
|
||||||
|
accounts: List<Account>
|
||||||
|
) {
|
||||||
for (account in accounts) {
|
for (account in accounts) {
|
||||||
val groupId = account.uuid
|
val groupId = account.uuid
|
||||||
val group = NotificationChannelGroup(groupId, account.displayName)
|
val group = NotificationChannelGroup(groupId, account.displayName)
|
||||||
|
@ -57,7 +57,9 @@ class NotificationChannelManager(
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
private fun removeChannelsForNonExistingOrChangedAccounts(
|
private fun removeChannelsForNonExistingOrChangedAccounts(
|
||||||
notificationManager: NotificationManager, accounts: List<Account>) {
|
notificationManager: NotificationManager,
|
||||||
|
accounts: List<Account>
|
||||||
|
) {
|
||||||
val existingAccounts = HashMap<String, Account>()
|
val existingAccounts = HashMap<String, Account>()
|
||||||
for (account in accounts) {
|
for (account in accounts) {
|
||||||
existingAccounts[account.uuid] = account
|
existingAccounts[account.uuid] = account
|
||||||
|
|
|
@ -2,23 +2,25 @@ package com.fsck.k9.notification
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.text.TextUtils
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import android.text.TextUtils
|
|
||||||
import com.fsck.k9.Account
|
import com.fsck.k9.Account
|
||||||
import com.fsck.k9.K9
|
import com.fsck.k9.K9
|
||||||
|
|
||||||
class NotificationHelper(
|
class NotificationHelper(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val notificationManager: NotificationManagerCompat,
|
private val notificationManager: NotificationManagerCompat,
|
||||||
private val channelUtils: NotificationChannelManager
|
private val channelUtils: NotificationChannelManager
|
||||||
) {
|
) {
|
||||||
fun configureNotification(
|
fun configureNotification(
|
||||||
builder: NotificationCompat.Builder,
|
builder: NotificationCompat.Builder,
|
||||||
ringtone: String?,
|
ringtone: String?,
|
||||||
vibrationPattern: LongArray?,
|
vibrationPattern: LongArray?,
|
||||||
ledColor: Int?, ledSpeed: Int,
|
ledColor: Int?,
|
||||||
ringAndVibrate: Boolean) {
|
ledSpeed: Int,
|
||||||
|
ringAndVibrate: Boolean
|
||||||
|
) {
|
||||||
|
|
||||||
if (K9.isQuietTime) {
|
if (K9.isQuietTime) {
|
||||||
return
|
return
|
||||||
|
@ -63,14 +65,13 @@ class NotificationHelper(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createNotificationBuilder(
|
fun createNotificationBuilder(
|
||||||
account: Account,
|
account: Account,
|
||||||
channelType: NotificationChannelManager.ChannelType
|
channelType: NotificationChannelManager.ChannelType
|
||||||
): NotificationCompat.Builder {
|
): NotificationCompat.Builder {
|
||||||
return NotificationCompat.Builder(context,
|
return NotificationCompat.Builder(context,
|
||||||
channelUtils.getChannelIdFor(account, channelType))
|
channelUtils.getChannelIdFor(account, channelType))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val NOTIFICATION_LED_ON_TIME = 500
|
private const val NOTIFICATION_LED_ON_TIME = 500
|
||||||
private const val NOTIFICATION_LED_OFF_TIME = 2000
|
private const val NOTIFICATION_LED_OFF_TIME = 2000
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
package com.fsck.k9.notification
|
package com.fsck.k9.notification
|
||||||
|
|
||||||
import com.fsck.k9.Account
|
import com.fsck.k9.Account
|
||||||
import com.fsck.k9.K9
|
|
||||||
import com.fsck.k9.helper.Contacts
|
|
||||||
import com.fsck.k9.mail.Flag
|
|
||||||
import com.fsck.k9.mail.Folder
|
|
||||||
import com.fsck.k9.mailstore.LocalFolder
|
|
||||||
import com.fsck.k9.mail.Message
|
import com.fsck.k9.mail.Message
|
||||||
|
import com.fsck.k9.mailstore.LocalFolder
|
||||||
|
|
||||||
interface NotificationStrategy {
|
interface NotificationStrategy {
|
||||||
|
|
||||||
fun shouldNotifyForMessage(account: Account,
|
fun shouldNotifyForMessage(
|
||||||
localFolder: LocalFolder,
|
account: Account,
|
||||||
message: Message,
|
localFolder: LocalFolder,
|
||||||
isOldMessage:Boolean):Boolean
|
message: Message,
|
||||||
}
|
isOldMessage: Boolean
|
||||||
|
): Boolean
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.fsck.k9.preferences
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
|
||||||
|
|
||||||
interface StorageEditor {
|
interface StorageEditor {
|
||||||
fun copy(input: SharedPreferences)
|
fun copy(input: SharedPreferences)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.fsck.k9.preferences
|
||||||
|
|
||||||
import androidx.annotation.CheckResult
|
import androidx.annotation.CheckResult
|
||||||
|
|
||||||
|
|
||||||
interface StoragePersister {
|
interface StoragePersister {
|
||||||
@CheckResult
|
@CheckResult
|
||||||
fun loadValues(): Map<String, String>
|
fun loadValues(): Map<String, String>
|
||||||
|
|
|
@ -4,7 +4,9 @@ import com.fsck.k9.Account
|
||||||
import com.fsck.k9.Account.FolderMode
|
import com.fsck.k9.Account.FolderMode
|
||||||
import com.fsck.k9.BaseAccount
|
import com.fsck.k9.BaseAccount
|
||||||
import com.fsck.k9.mail.Folder.FolderClass
|
import com.fsck.k9.mail.Folder.FolderClass
|
||||||
import com.fsck.k9.search.SearchSpecification.*
|
import com.fsck.k9.search.SearchSpecification.Attribute
|
||||||
|
import com.fsck.k9.search.SearchSpecification.SearchCondition
|
||||||
|
import com.fsck.k9.search.SearchSpecification.SearchField
|
||||||
|
|
||||||
class AccountSearchConditions {
|
class AccountSearchConditions {
|
||||||
/**
|
/**
|
||||||
|
@ -31,7 +33,8 @@ class AccountSearchConditions {
|
||||||
|
|
||||||
// TODO: Create a proper interface for creating arbitrary condition trees
|
// TODO: Create a proper interface for creating arbitrary condition trees
|
||||||
val searchCondition = SearchCondition(
|
val searchCondition = SearchCondition(
|
||||||
SearchField.DISPLAY_CLASS, Attribute.EQUALS, FolderClass.SECOND_CLASS.name)
|
SearchField.DISPLAY_CLASS, Attribute.EQUALS, FolderClass.SECOND_CLASS.name
|
||||||
|
)
|
||||||
val root = search.conditions
|
val root = search.conditions
|
||||||
if (root.mRight != null) {
|
if (root.mRight != null) {
|
||||||
root.mRight.or(searchCondition)
|
root.mRight.or(searchCondition)
|
||||||
|
@ -121,4 +124,4 @@ class AccountSearchConditions {
|
||||||
|
|
||||||
return search
|
return search
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.fsck.k9.service
|
package com.fsck.k9.service
|
||||||
|
|
||||||
|
|
||||||
import android.app.AlarmManager
|
import android.app.AlarmManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -22,8 +21,8 @@ class BootReceiver : CoreReceiver(), EarlyInit {
|
||||||
|
|
||||||
val action = intent.action
|
val action = intent.action
|
||||||
if (Intent.ACTION_BOOT_COMPLETED == action) {
|
if (Intent.ACTION_BOOT_COMPLETED == action) {
|
||||||
//K9.setServicesEnabled(context, tmpWakeLockId);
|
// K9.setServicesEnabled(context, tmpWakeLockId);
|
||||||
//tmpWakeLockId = null;
|
// tmpWakeLockId = null;
|
||||||
} else if ("com.android.sync.SYNC_CONN_STATUS_CHANGED" == action) {
|
} else if ("com.android.sync.SYNC_CONN_STATUS_CHANGED" == action) {
|
||||||
val bOps = K9.backgroundOps
|
val bOps = K9.backgroundOps
|
||||||
if (bOps == K9.BACKGROUND_OPS.WHEN_CHECKED_AUTO_SYNC) {
|
if (bOps == K9.BACKGROUND_OPS.WHEN_CHECKED_AUTO_SYNC) {
|
||||||
|
@ -47,7 +46,6 @@ class BootReceiver : CoreReceiver(), EarlyInit {
|
||||||
alarmMgr.set(AlarmManager.RTC_WAKEUP, atTime, pi)
|
alarmMgr.set(AlarmManager.RTC_WAKEUP, atTime, pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return tmpWakeLockId
|
return tmpWakeLockId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,5 +96,4 @@ class BootReceiver : CoreReceiver(), EarlyInit {
|
||||||
}, 0))
|
}, 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.fsck.k9.setup
|
||||||
|
|
||||||
import com.fsck.k9.preferences.Protocols
|
import com.fsck.k9.preferences.Protocols
|
||||||
|
|
||||||
|
|
||||||
class ServerNameSuggester {
|
class ServerNameSuggester {
|
||||||
fun suggestServerName(serverType: String, domainPart: String): String = when (serverType) {
|
fun suggestServerName(serverType: String, domainPart: String): String = when (serverType) {
|
||||||
Protocols.IMAP -> "imap.$domainPart"
|
Protocols.IMAP -> "imap.$domainPart"
|
||||||
|
|
|
@ -7,7 +7,7 @@ class EmailAddressValidatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testEmailValidation() {
|
fun testEmailValidation() {
|
||||||
//Most of the tests based on https://en.wikipedia.org/wiki/Email_address#Examples
|
// Most of the tests based on https://en.wikipedia.org/wiki/Email_address#Examples
|
||||||
val validator = EmailAddressValidator()
|
val validator = EmailAddressValidator()
|
||||||
Assert.assertTrue(validator.isValidAddressOnly("simple@example.com"))
|
Assert.assertTrue(validator.isValidAddressOnly("simple@example.com"))
|
||||||
Assert.assertTrue(validator.isValidAddressOnly("very.common@example.com"))
|
Assert.assertTrue(validator.isValidAddressOnly("very.common@example.com"))
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package com.fsck.k9
|
package com.fsck.k9
|
||||||
|
|
||||||
|
|
||||||
import com.nhaarman.mockito_kotlin.whenever
|
import com.nhaarman.mockito_kotlin.whenever
|
||||||
|
import java.util.Calendar
|
||||||
import org.junit.Assert.assertFalse
|
import org.junit.Assert.assertFalse
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.Mockito.mock
|
import org.mockito.Mockito.mock
|
||||||
import java.util.Calendar
|
|
||||||
|
|
||||||
|
|
||||||
class QuietTimeCheckerTest {
|
class QuietTimeCheckerTest {
|
||||||
private val clock = mock(Clock::class.java)
|
private val clock = mock(Clock::class.java)
|
||||||
|
@ -108,7 +106,6 @@ class QuietTimeCheckerTest {
|
||||||
assertFalse(quietTimeChecker.isQuietTime)
|
assertFalse(quietTimeChecker.isQuietTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun setClockTo(time: String) {
|
private fun setClockTo(time: String) {
|
||||||
val (hourOfDay, minute) = time.split(':').map { it.toInt() }
|
val (hourOfDay, minute) = time.split(':').map { it.toInt() }
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package com.fsck.k9.autocrypt
|
package com.fsck.k9.autocrypt
|
||||||
|
|
||||||
|
|
||||||
import com.fsck.k9.RobolectricTest
|
import com.fsck.k9.RobolectricTest
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
||||||
class AutocryptDraftStateHeaderParserTest : RobolectricTest() {
|
class AutocryptDraftStateHeaderParserTest : RobolectricTest() {
|
||||||
internal var autocryptHeaderParser = AutocryptDraftStateHeaderParser()
|
internal var autocryptHeaderParser = AutocryptDraftStateHeaderParser()
|
||||||
|
|
||||||
|
@ -18,18 +16,18 @@ class AutocryptDraftStateHeaderParserTest : RobolectricTest() {
|
||||||
assertThat(parsedHeader).isEqualTo(draftStateHeader)
|
assertThat(parsedHeader).isEqualTo(draftStateHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSignOnly() {
|
fun testSignOnly() {
|
||||||
val parsedHeader = autocryptHeaderParser.parseAutocryptDraftStateHeader("encrypt=no; _by-choice=yes; _sign-only=yes")
|
val parsedHeader = autocryptHeaderParser.parseAutocryptDraftStateHeader("encrypt=no; _by-choice=yes; _sign-only=yes")
|
||||||
|
|
||||||
with(parsedHeader!!) {
|
with(parsedHeader!!) {
|
||||||
assertThat(isEncrypt).isFalse()
|
assertThat(isEncrypt).isFalse()
|
||||||
assertThat(isByChoice).isTrue()
|
assertThat(isByChoice).isTrue()
|
||||||
assertThat(isSignOnly).isTrue()
|
assertThat(isSignOnly).isTrue()
|
||||||
assertThat(isPgpInline).isFalse()
|
assertThat(isPgpInline).isFalse()
|
||||||
assertThat(isReply).isFalse()
|
assertThat(isReply).isFalse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun badCritical() {
|
fun badCritical() {
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package com.fsck.k9.autocrypt
|
package com.fsck.k9.autocrypt
|
||||||
|
|
||||||
|
|
||||||
import com.fsck.k9.mail.filter.Base64
|
import com.fsck.k9.mail.filter.Base64
|
||||||
import com.fsck.k9.mailstore.MimePartStreamParser
|
import com.fsck.k9.mailstore.MimePartStreamParser
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.assertArrayEquals
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertNotNull
|
||||||
|
import org.junit.Assert.assertNull
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
||||||
class AutocryptGossipHeaderParserTest {
|
class AutocryptGossipHeaderParserTest {
|
||||||
val GOSSIP_DATA_BOB = Base64.decodeBase64(
|
val GOSSIP_DATA_BOB = Base64.decodeBase64(
|
||||||
"""mQGNBFoBt74BDAC8AMsjPY17kxodbfmHah38ZQipY0yfuo97WUBs2jeiFYlQdunPANi5VMgbAX+H
|
"""mQGNBFoBt74BDAC8AMsjPY17kxodbfmHah38ZQipY0yfuo97WUBs2jeiFYlQdunPANi5VMgbAX+H
|
||||||
|
@ -93,4 +94,4 @@ Alice
|
||||||
|
|
||||||
assertNull(gossipHeader)
|
assertNull(gossipHeader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package com.fsck.k9.crypto
|
package com.fsck.k9.crypto
|
||||||
|
|
||||||
|
|
||||||
import com.fsck.k9.Identity
|
import com.fsck.k9.Identity
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
||||||
class OpenPgpApiHelperTest {
|
class OpenPgpApiHelperTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -30,5 +28,4 @@ class OpenPgpApiHelperTest {
|
||||||
|
|
||||||
assertEquals("<user@domain.com>", result)
|
assertEquals("<user@domain.com>", result)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.fsck.k9.helper
|
package com.fsck.k9.helper
|
||||||
|
|
||||||
|
|
||||||
import com.fsck.k9.Account
|
import com.fsck.k9.Account
|
||||||
import com.fsck.k9.Identity
|
import com.fsck.k9.Identity
|
||||||
import com.fsck.k9.RobolectricTest
|
import com.fsck.k9.RobolectricTest
|
||||||
|
@ -10,8 +9,8 @@ import com.fsck.k9.mail.Message.RecipientType
|
||||||
import com.fsck.k9.mail.internet.AddressHeaderBuilder
|
import com.fsck.k9.mail.internet.AddressHeaderBuilder
|
||||||
import com.fsck.k9.mail.internet.MimeMessage
|
import com.fsck.k9.mail.internet.MimeMessage
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import java.util.UUID
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class IdentityHelperTest : RobolectricTest() {
|
class IdentityHelperTest : RobolectricTest() {
|
||||||
private val account = createDummyAccount()
|
private val account = createDummyAccount()
|
||||||
|
@ -109,7 +108,6 @@ class IdentityHelperTest : RobolectricTest() {
|
||||||
assertThat(identity.email).isEqualTo(DEFAULT_ADDRESS)
|
assertThat(identity.email).isEqualTo(DEFAULT_ADDRESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun createDummyAccount() = Account(UUID.randomUUID().toString()).apply {
|
private fun createDummyAccount() = Account(UUID.randomUUID().toString()).apply {
|
||||||
identities = listOf(
|
identities = listOf(
|
||||||
newIdentity("Default", DEFAULT_ADDRESS),
|
newIdentity("Default", DEFAULT_ADDRESS),
|
||||||
|
|
|
@ -31,7 +31,6 @@ class K9BackendFolderTest : K9RobolectricTest() {
|
||||||
val backendFolder = createBackendFolder()
|
val backendFolder = createBackendFolder()
|
||||||
val database: LockableDatabase = localStoreProvider.getInstance(account).database
|
val database: LockableDatabase = localStoreProvider.getInstance(account).database
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
// Set EmailProvider.CONTENT_URI so LocalStore.notifyChange() won't crash
|
// Set EmailProvider.CONTENT_URI so LocalStore.notifyChange() won't crash
|
||||||
|
@ -84,9 +83,8 @@ class K9BackendFolderTest : K9RobolectricTest() {
|
||||||
assertEquals(200L, lastUid)
|
assertEquals(200L, lastUid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun createAccount(): Account {
|
fun createAccount(): Account {
|
||||||
//FIXME: This is a hack to get Preferences into a state where it's safe to call newAccount()
|
// FIXME: This is a hack to get Preferences into a state where it's safe to call newAccount()
|
||||||
preferences.clearAccounts()
|
preferences.clearAccounts()
|
||||||
|
|
||||||
return preferences.newAccount()
|
return preferences.newAccount()
|
||||||
|
@ -136,7 +134,6 @@ class K9BackendFolderTest : K9RobolectricTest() {
|
||||||
|
|
||||||
private fun dbOperation(action: (SQLiteDatabase) -> Unit) = database.execute(false, action)
|
private fun dbOperation(action: (SQLiteDatabase) -> Unit) = database.execute(false, action)
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val FOLDER_SERVER_ID = "testFolder"
|
const val FOLDER_SERVER_ID = "testFolder"
|
||||||
const val FOLDER_NAME = "Test Folder"
|
const val FOLDER_NAME = "Test Folder"
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
package com.fsck.k9.mailstore
|
package com.fsck.k9.mailstore
|
||||||
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream
|
|
||||||
|
|
||||||
import com.fsck.k9.mail.internet.MimeBodyPart
|
import com.fsck.k9.mail.internet.MimeBodyPart
|
||||||
import com.fsck.k9.mail.internet.MimeMessage
|
import com.fsck.k9.mail.internet.MimeMessage
|
||||||
import com.fsck.k9.mail.internet.MimeMultipart
|
import com.fsck.k9.mail.internet.MimeMultipart
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
|
|
||||||
class MimePartStreamParserTest {
|
class MimePartStreamParserTest {
|
||||||
@Test
|
@Test
|
||||||
fun innerMessage_DispositionInline() {
|
fun innerMessage_DispositionInline() {
|
||||||
|
@ -72,4 +69,4 @@ inner text
|
||||||
assertEquals("message/rfc822", messagePart.mimeType)
|
assertEquals("message/rfc822", messagePart.mimeType)
|
||||||
assertTrue(messagePart.body is DeferredFileBody)
|
assertTrue(messagePart.body is DeferredFileBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import org.junit.Test
|
||||||
class DisplayHtmlTest {
|
class DisplayHtmlTest {
|
||||||
val displayHtml = DisplayHtml(HtmlSettings(useDarkMode = false, useFixedWidthFont = false))
|
val displayHtml = DisplayHtml(HtmlSettings(useDarkMode = false, useFixedWidthFont = false))
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun wrapMessageContent_addsViewportMetaElement() {
|
fun wrapMessageContent_addsViewportMetaElement() {
|
||||||
val html = displayHtml.wrapMessageContent("Some text")
|
val html = displayHtml.wrapMessageContent("Some text")
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package com.fsck.k9.message.html
|
package com.fsck.k9.message.html
|
||||||
|
|
||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
||||||
class EmailSectionExtractorTest {
|
class EmailSectionExtractorTest {
|
||||||
@Test
|
@Test
|
||||||
fun simpleMessageWithoutQuotes() {
|
fun simpleMessageWithoutQuotes() {
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package com.fsck.k9.message.html
|
package com.fsck.k9.message.html
|
||||||
|
|
||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
||||||
class EmailSectionTest {
|
class EmailSectionTest {
|
||||||
@Test
|
@Test
|
||||||
fun charAt() {
|
fun charAt() {
|
||||||
|
@ -65,7 +63,6 @@ class EmailSectionTest {
|
||||||
assertThat(section.subSequence(6, 11).asString()).isEqualTo("Three")
|
assertThat(section.subSequence(6, 11).asString()).isEqualTo("Three")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun CharSequence.asString() = StringBuilder(length).apply {
|
private fun CharSequence.asString() = StringBuilder(length).apply {
|
||||||
this@asString.forEach { append(it) }
|
this@asString.forEach { append(it) }
|
||||||
}.toString()
|
}.toString()
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.fsck.k9.message.quote
|
package com.fsck.k9.message.quote
|
||||||
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import com.fsck.k9.Account.QuoteStyle
|
import com.fsck.k9.Account.QuoteStyle
|
||||||
|
@ -14,11 +13,10 @@ import com.fsck.k9.mail.Message.RecipientType
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import com.nhaarman.mockito_kotlin.doReturn
|
import com.nhaarman.mockito_kotlin.doReturn
|
||||||
import com.nhaarman.mockito_kotlin.mock
|
import com.nhaarman.mockito_kotlin.mock
|
||||||
import org.junit.Before
|
|
||||||
import org.junit.Test
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
class TextQuoteCreatorTest : RobolectricTest() {
|
class TextQuoteCreatorTest : RobolectricTest() {
|
||||||
val resources = mock<Resources> {
|
val resources = mock<Resources> {
|
||||||
|
@ -33,7 +31,6 @@ class TextQuoteCreatorTest : RobolectricTest() {
|
||||||
}
|
}
|
||||||
val textQuoteCreator = TextQuoteCreator(QuoteHelper(resources), TestCoreResourceProvider())
|
val textQuoteCreator = TextQuoteCreator(QuoteHelper(resources), TestCoreResourceProvider())
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
K9.isHideTimeZone = true
|
K9.isHideTimeZone = true
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package com.fsck.k9.preferences
|
package com.fsck.k9.preferences
|
||||||
|
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
||||||
private const val TEST_STRING_KEY = "s"
|
private const val TEST_STRING_KEY = "s"
|
||||||
private const val TEST_STRING_VALUE = "y"
|
private const val TEST_STRING_VALUE = "y"
|
||||||
private const val TEST_INT_KEY = "i"
|
private const val TEST_INT_KEY = "i"
|
||||||
|
@ -76,4 +76,4 @@ class StorageTest {
|
||||||
// TODO is this good behavior?
|
// TODO is this good behavior?
|
||||||
assertEquals(TEST_INT_DEFAULT, storage.getInt(TEST_STRING_KEY, TEST_INT_DEFAULT))
|
assertEquals(TEST_INT_DEFAULT, storage.getInt(TEST_STRING_KEY, TEST_INT_DEFAULT))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import com.fsck.k9.mail.Message
|
||||||
import com.fsck.k9.message.extractors.TextPartFinder
|
import com.fsck.k9.message.extractors.TextPartFinder
|
||||||
|
|
||||||
class OpenPgpEncryptionExtractor internal constructor(
|
class OpenPgpEncryptionExtractor internal constructor(
|
||||||
private val encryptionDetector: EncryptionDetector
|
private val encryptionDetector: EncryptionDetector
|
||||||
) : EncryptionExtractor {
|
) : EncryptionExtractor {
|
||||||
|
|
||||||
override fun extractEncryption(message: Message): EncryptionResult? {
|
override fun extractEncryption(message: Message): EncryptionResult? {
|
||||||
|
@ -17,7 +17,6 @@ class OpenPgpEncryptionExtractor internal constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val ENCRYPTION_TYPE = "openpgp"
|
const val ENCRYPTION_TYPE = "openpgp"
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ class App : Application() {
|
||||||
private val messagingListenerProvider: MessagingListenerProvider by inject()
|
private val messagingListenerProvider: MessagingListenerProvider by inject()
|
||||||
private val themeManager: ThemeManager by inject()
|
private val themeManager: ThemeManager by inject()
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
Core.earlyInit(this)
|
Core.earlyInit(this)
|
||||||
|
|
||||||
|
@ -30,7 +29,6 @@ class App : Application() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val appConfig = AppConfig(
|
val appConfig = AppConfig(
|
||||||
componentsToDisable = listOf(MessageCompose::class.java)
|
componentsToDisable = listOf(MessageCompose::class.java)
|
||||||
|
|
|
@ -19,10 +19,10 @@ import com.fsck.k9.mail.transport.smtp.SmtpTransportUriDecoder
|
||||||
import com.fsck.k9.mailstore.K9BackendStorageFactory
|
import com.fsck.k9.mailstore.K9BackendStorageFactory
|
||||||
|
|
||||||
class ImapBackendFactory(
|
class ImapBackendFactory(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val powerManager: PowerManager,
|
private val powerManager: PowerManager,
|
||||||
private val backendStorageFactory: K9BackendStorageFactory,
|
private val backendStorageFactory: K9BackendStorageFactory,
|
||||||
private val trustedSocketFactory: TrustedSocketFactory
|
private val trustedSocketFactory: TrustedSocketFactory
|
||||||
) : BackendFactory {
|
) : BackendFactory {
|
||||||
override val transportUriPrefix = "smtp"
|
override val transportUriPrefix = "smtp"
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@ import com.fsck.k9.mail.transport.smtp.SmtpTransportUriDecoder
|
||||||
import com.fsck.k9.mailstore.K9BackendStorageFactory
|
import com.fsck.k9.mailstore.K9BackendStorageFactory
|
||||||
|
|
||||||
class Pop3BackendFactory(
|
class Pop3BackendFactory(
|
||||||
private val backendStorageFactory: K9BackendStorageFactory,
|
private val backendStorageFactory: K9BackendStorageFactory,
|
||||||
private val trustedSocketFactory: TrustedSocketFactory
|
private val trustedSocketFactory: TrustedSocketFactory
|
||||||
) : BackendFactory {
|
) : BackendFactory {
|
||||||
override val transportUriPrefix = "smtp"
|
override val transportUriPrefix = "smtp"
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ import com.fsck.k9.mail.transport.WebDavTransport
|
||||||
import com.fsck.k9.mailstore.K9BackendStorageFactory
|
import com.fsck.k9.mailstore.K9BackendStorageFactory
|
||||||
|
|
||||||
class WebDavBackendFactory(
|
class WebDavBackendFactory(
|
||||||
private val backendStorageFactory: K9BackendStorageFactory,
|
private val backendStorageFactory: K9BackendStorageFactory,
|
||||||
private val trustManagerFactory: TrustManagerFactory
|
private val trustManagerFactory: TrustManagerFactory
|
||||||
) : BackendFactory {
|
) : BackendFactory {
|
||||||
override val transportUriPrefix = "webdav"
|
override val transportUriPrefix = "webdav"
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,12 @@ import com.fsck.k9.mailstore.LocalFolder
|
||||||
|
|
||||||
class K9NotificationStrategy(val contacts: Contacts) : NotificationStrategy {
|
class K9NotificationStrategy(val contacts: Contacts) : NotificationStrategy {
|
||||||
|
|
||||||
override fun shouldNotifyForMessage(account: Account,
|
override fun shouldNotifyForMessage(
|
||||||
localFolder: LocalFolder,
|
account: Account,
|
||||||
message: Message,
|
localFolder: LocalFolder,
|
||||||
isOldMessage:Boolean):Boolean {
|
message: Message,
|
||||||
|
isOldMessage: Boolean
|
||||||
|
): Boolean {
|
||||||
|
|
||||||
// If we don't even have an account name, don't show the notification.
|
// If we don't even have an account name, don't show the notification.
|
||||||
// (This happens during initial account setup)
|
// (This happens during initial account setup)
|
||||||
|
@ -50,10 +52,10 @@ class K9NotificationStrategy(val contacts: Contacts) : NotificationStrategy {
|
||||||
val folder = message.folder
|
val folder = message.folder
|
||||||
if (folder != null) {
|
if (folder != null) {
|
||||||
val folderServerId = folder.serverId
|
val folderServerId = folder.serverId
|
||||||
if (folderServerId != account.inboxFolder && (folderServerId == account.trashFolder
|
if (folderServerId != account.inboxFolder && (folderServerId == account.trashFolder ||
|
||||||
|| folderServerId == account.draftsFolder
|
folderServerId == account.draftsFolder ||
|
||||||
|| folderServerId == account.spamFolder
|
folderServerId == account.spamFolder ||
|
||||||
|| folderServerId == account.sentFolder)) {
|
folderServerId == account.sentFolder)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +65,5 @@ class K9NotificationStrategy(val contacts: Contacts) : NotificationStrategy {
|
||||||
return if (account.isAnIdentity(message.from) && !account.isNotifySelfNewMail) {
|
return if (account.isAnIdentity(message.from) && !account.isNotifySelfNewMail) {
|
||||||
false
|
false
|
||||||
} else !account.isNotifyContactsMailOnly || contacts.isAnyInContacts(message.from)
|
} else !account.isNotifyContactsMailOnly || contacts.isAnyInContacts(message.from)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ import timber.log.Timber
|
||||||
class UnreadWidgetProvider : AppWidgetProvider(), EarlyInit {
|
class UnreadWidgetProvider : AppWidgetProvider(), EarlyInit {
|
||||||
private val repository: UnreadWidgetRepository by inject()
|
private val repository: UnreadWidgetRepository by inject()
|
||||||
|
|
||||||
|
|
||||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||||
for (widgetId in appWidgetIds) {
|
for (widgetId in appWidgetIds) {
|
||||||
val widgetData = repository.getWidgetData(widgetId)
|
val widgetData = repository.getWidgetData(widgetId)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package com.fsck.k9.resources
|
package com.fsck.k9.resources
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.fsck.k9.autocrypt.AutocryptStringProvider
|
|
||||||
import com.fsck.k9.R
|
import com.fsck.k9.R
|
||||||
|
import com.fsck.k9.autocrypt.AutocryptStringProvider
|
||||||
|
|
||||||
class K9AutocryptStringProvider(private val context: Context) : AutocryptStringProvider {
|
class K9AutocryptStringProvider(private val context: Context) : AutocryptStringProvider {
|
||||||
override fun transferMessageSubject(): String = context.getString(R.string.ac_transfer_msg_subject)
|
override fun transferMessageSubject(): String = context.getString(R.string.ac_transfer_msg_subject)
|
||||||
|
|
|
@ -9,7 +9,6 @@ import android.preference.Preference
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
|
||||||
import com.fsck.k9.Preferences
|
import com.fsck.k9.Preferences
|
||||||
import com.fsck.k9.R
|
import com.fsck.k9.R
|
||||||
import com.fsck.k9.activity.ChooseAccount
|
import com.fsck.k9.activity.ChooseAccount
|
||||||
|
@ -17,10 +16,8 @@ import com.fsck.k9.activity.ChooseFolder
|
||||||
import com.fsck.k9.activity.K9PreferenceActivity
|
import com.fsck.k9.activity.K9PreferenceActivity
|
||||||
import com.fsck.k9.search.SearchAccount
|
import com.fsck.k9.search.SearchAccount
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity to select an account for the unread widget.
|
* Activity to select an account for the unread widget.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,8 +3,8 @@ package com.fsck.k9.widget.unread
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
|
||||||
data class UnreadWidgetData(
|
data class UnreadWidgetData(
|
||||||
val configuration: UnreadWidgetConfiguration,
|
val configuration: UnreadWidgetConfiguration,
|
||||||
val title: String,
|
val title: String,
|
||||||
val unreadCount: Int,
|
val unreadCount: Int,
|
||||||
val clickIntent: Intent
|
val clickIntent: Intent
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,9 +11,9 @@ import com.fsck.k9.search.LocalSearch
|
||||||
import com.fsck.k9.search.SearchAccount
|
import com.fsck.k9.search.SearchAccount
|
||||||
|
|
||||||
class UnreadWidgetDataProvider(
|
class UnreadWidgetDataProvider(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
private val messagingController: MessagingController
|
private val messagingController: MessagingController
|
||||||
) {
|
) {
|
||||||
fun loadUnreadWidgetData(configuration: UnreadWidgetConfiguration): UnreadWidgetData? = with(configuration) {
|
fun loadUnreadWidgetData(configuration: UnreadWidgetConfiguration): UnreadWidgetData? = with(configuration) {
|
||||||
if (SearchAccount.UNIFIED_INBOX == accountUuid) {
|
if (SearchAccount.UNIFIED_INBOX == accountUuid) {
|
||||||
|
@ -59,7 +59,7 @@ class UnreadWidgetDataProvider(
|
||||||
val folderServerId = configuration.folderServerId ?: return null
|
val folderServerId = configuration.folderServerId ?: return null
|
||||||
|
|
||||||
val accountName = account.description
|
val accountName = account.description
|
||||||
//FIXME: Use folder display name instead of folderServerId for title
|
// FIXME: Use folder display name instead of folderServerId for title
|
||||||
val title = context.getString(R.string.unread_widget_title, accountName, folderServerId)
|
val title = context.getString(R.string.unread_widget_title, accountName, folderServerId)
|
||||||
|
|
||||||
val unreadCount = messagingController.getFolderUnreadMessageCount(account, folderServerId)
|
val unreadCount = messagingController.getFolderUnreadMessageCount(account, folderServerId)
|
||||||
|
|
|
@ -3,8 +3,8 @@ package com.fsck.k9.widget.unread
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|
||||||
class UnreadWidgetRepository(
|
class UnreadWidgetRepository(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val dataRetriever: UnreadWidgetDataProvider
|
private val dataRetriever: UnreadWidgetDataProvider
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun saveWidgetConfiguration(configuration: UnreadWidgetConfiguration) {
|
fun saveWidgetConfiguration(configuration: UnreadWidgetConfiguration) {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import com.fsck.k9.provider.UnreadWidgetProvider
|
||||||
class UnreadWidgetUpdater(private val context: Context) {
|
class UnreadWidgetUpdater(private val context: Context) {
|
||||||
private val appWidgetManager = AppWidgetManager.getInstance(context)
|
private val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||||
|
|
||||||
|
|
||||||
fun updateAll() {
|
fun updateAll() {
|
||||||
val thisWidget = ComponentName(context, UnreadWidgetProvider::class.java)
|
val thisWidget = ComponentName(context, UnreadWidgetProvider::class.java)
|
||||||
val widgetIds = appWidgetManager.getAppWidgetIds(thisWidget)
|
val widgetIds = appWidgetManager.getAppWidgetIds(thisWidget)
|
||||||
|
|
|
@ -2,8 +2,8 @@ package com.fsck.k9.widget.unread
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.fsck.k9.Account
|
import com.fsck.k9.Account
|
||||||
import com.fsck.k9.Preferences
|
|
||||||
import com.fsck.k9.AppRobolectricTest
|
import com.fsck.k9.AppRobolectricTest
|
||||||
|
import com.fsck.k9.Preferences
|
||||||
import com.fsck.k9.controller.MessagingController
|
import com.fsck.k9.controller.MessagingController
|
||||||
import com.fsck.k9.search.SearchAccount
|
import com.fsck.k9.search.SearchAccount
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
@ -14,7 +14,6 @@ import org.junit.Test
|
||||||
import org.mockito.ArgumentMatchers.eq
|
import org.mockito.ArgumentMatchers.eq
|
||||||
import org.robolectric.RuntimeEnvironment
|
import org.robolectric.RuntimeEnvironment
|
||||||
|
|
||||||
|
|
||||||
class UnreadWidgetDataProviderTest : AppRobolectricTest() {
|
class UnreadWidgetDataProviderTest : AppRobolectricTest() {
|
||||||
val context: Context = RuntimeEnvironment.application
|
val context: Context = RuntimeEnvironment.application
|
||||||
val account = createAccount()
|
val account = createAccount()
|
||||||
|
@ -22,7 +21,6 @@ class UnreadWidgetDataProviderTest : AppRobolectricTest() {
|
||||||
val messagingController = createMessagingController()
|
val messagingController = createMessagingController()
|
||||||
val provider = UnreadWidgetDataProvider(context, preferences, messagingController)
|
val provider = UnreadWidgetDataProvider(context, preferences, messagingController)
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun unifiedInbox() {
|
fun unifiedInbox() {
|
||||||
val configuration = UnreadWidgetConfiguration(
|
val configuration = UnreadWidgetConfiguration(
|
||||||
|
@ -71,7 +69,6 @@ class UnreadWidgetDataProviderTest : AppRobolectricTest() {
|
||||||
assertThat(widgetData).isNull()
|
assertThat(widgetData).isNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun createAccount(): Account = mock {
|
fun createAccount(): Account = mock {
|
||||||
on { uuid } doReturn ACCOUNT_UUID
|
on { uuid } doReturn ACCOUNT_UUID
|
||||||
on { description } doReturn ACCOUNT_DESCRIPTION
|
on { description } doReturn ACCOUNT_DESCRIPTION
|
||||||
|
|
|
@ -6,8 +6,8 @@ import android.database.sqlite.SQLiteDatabase
|
||||||
* Rewrite folder name values of "-NONE-" to `null`
|
* Rewrite folder name values of "-NONE-" to `null`
|
||||||
*/
|
*/
|
||||||
class StorageMigrationTo3(
|
class StorageMigrationTo3(
|
||||||
private val db: SQLiteDatabase,
|
private val db: SQLiteDatabase,
|
||||||
private val migrationsHelper: StorageMigrationsHelper
|
private val migrationsHelper: StorageMigrationsHelper
|
||||||
) {
|
) {
|
||||||
fun rewriteFolderNone() {
|
fun rewriteFolderNone() {
|
||||||
val accountUuidsListValue = migrationsHelper.readValue(db, "accountUuids")
|
val accountUuidsListValue = migrationsHelper.readValue(db, "accountUuids")
|
||||||
|
@ -37,7 +37,6 @@ class StorageMigrationTo3(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val OLD_FOLDER_VALUE = "-NONE-"
|
private const val OLD_FOLDER_VALUE = "-NONE-"
|
||||||
private val NEW_FOLDER_VALUE = null
|
private val NEW_FOLDER_VALUE = null
|
||||||
|
|
|
@ -6,8 +6,8 @@ import android.database.sqlite.SQLiteDatabase
|
||||||
* Add `*FolderSelection` values of "MANUAL" for existing accounts (default for new accounts is "AUTOMATIC").
|
* Add `*FolderSelection` values of "MANUAL" for existing accounts (default for new accounts is "AUTOMATIC").
|
||||||
*/
|
*/
|
||||||
class StorageMigrationTo4(
|
class StorageMigrationTo4(
|
||||||
private val db: SQLiteDatabase,
|
private val db: SQLiteDatabase,
|
||||||
private val migrationsHelper: StorageMigrationsHelper
|
private val migrationsHelper: StorageMigrationsHelper
|
||||||
) {
|
) {
|
||||||
fun insertSpecialFolderSelectionValues() {
|
fun insertSpecialFolderSelectionValues() {
|
||||||
val accountUuidsListValue = migrationsHelper.readValue(db, "accountUuids")
|
val accountUuidsListValue = migrationsHelper.readValue(db, "accountUuids")
|
||||||
|
|
|
@ -6,8 +6,8 @@ import android.database.sqlite.SQLiteDatabase
|
||||||
* Rewrite frequencies lower than LOWEST_FREQUENCY_SUPPORTED
|
* Rewrite frequencies lower than LOWEST_FREQUENCY_SUPPORTED
|
||||||
*/
|
*/
|
||||||
class StorageMigrationTo5(
|
class StorageMigrationTo5(
|
||||||
private val db: SQLiteDatabase,
|
private val db: SQLiteDatabase,
|
||||||
private val migrationsHelper: StorageMigrationsHelper
|
private val migrationsHelper: StorageMigrationsHelper
|
||||||
) {
|
) {
|
||||||
fun fixMailCheckFrequencies() {
|
fun fixMailCheckFrequencies() {
|
||||||
val accountUuidsListValue = migrationsHelper.readValue(db, "accountUuids")
|
val accountUuidsListValue = migrationsHelper.readValue(db, "accountUuids")
|
||||||
|
@ -29,7 +29,6 @@ class StorageMigrationTo5(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// see: https://github.com/evernote/android-job/wiki/FAQ#why-cant-an-interval-be-smaller-than-15-minutes-for-periodic-jobs
|
// see: https://github.com/evernote/android-job/wiki/FAQ#why-cant-an-interval-be-smaller-than-15-minutes-for-periodic-jobs
|
||||||
private const val LOWEST_FREQUENCY_SUPPORTED = 15
|
private const val LOWEST_FREQUENCY_SUPPORTED = 15
|
||||||
|
|
|
@ -6,8 +6,8 @@ import android.database.sqlite.SQLiteDatabase
|
||||||
* Perform legacy conversions that previously lived in `K9`.
|
* Perform legacy conversions that previously lived in `K9`.
|
||||||
*/
|
*/
|
||||||
class StorageMigrationTo6(
|
class StorageMigrationTo6(
|
||||||
private val db: SQLiteDatabase,
|
private val db: SQLiteDatabase,
|
||||||
private val migrationsHelper: StorageMigrationsHelper
|
private val migrationsHelper: StorageMigrationsHelper
|
||||||
) {
|
) {
|
||||||
fun performLegacyMigrations() {
|
fun performLegacyMigrations() {
|
||||||
rewriteKeyguardPrivacy()
|
rewriteKeyguardPrivacy()
|
||||||
|
|
|
@ -6,8 +6,8 @@ import android.database.sqlite.SQLiteDatabase
|
||||||
* Rewrite settings to use enum names instead of ordinals.
|
* Rewrite settings to use enum names instead of ordinals.
|
||||||
*/
|
*/
|
||||||
class StorageMigrationTo7(
|
class StorageMigrationTo7(
|
||||||
private val db: SQLiteDatabase,
|
private val db: SQLiteDatabase,
|
||||||
private val migrationsHelper: StorageMigrationsHelper
|
private val migrationsHelper: StorageMigrationsHelper
|
||||||
) {
|
) {
|
||||||
fun rewriteEnumOrdinalsToNames() {
|
fun rewriteEnumOrdinalsToNames() {
|
||||||
rewriteTheme()
|
rewriteTheme()
|
||||||
|
|
|
@ -6,8 +6,8 @@ import android.database.sqlite.SQLiteDatabase
|
||||||
* Rewrite theme setting to use `FOLLOW_SYSTEM` when it's currently set to `LIGHT`.
|
* Rewrite theme setting to use `FOLLOW_SYSTEM` when it's currently set to `LIGHT`.
|
||||||
*/
|
*/
|
||||||
class StorageMigrationTo8(
|
class StorageMigrationTo8(
|
||||||
private val db: SQLiteDatabase,
|
private val db: SQLiteDatabase,
|
||||||
private val migrationsHelper: StorageMigrationsHelper
|
private val migrationsHelper: StorageMigrationsHelper
|
||||||
) {
|
) {
|
||||||
fun rewriteTheme() {
|
fun rewriteTheme() {
|
||||||
val theme = migrationsHelper.readValue(db, "theme")
|
val theme = migrationsHelper.readValue(db, "theme")
|
||||||
|
|
|
@ -9,8 +9,8 @@ import android.database.sqlite.SQLiteDatabase
|
||||||
* configure "poll folders" so folders that have previously used Push will now be polled.
|
* configure "poll folders" so folders that have previously used Push will now be polled.
|
||||||
*/
|
*/
|
||||||
class StorageMigrationTo9(
|
class StorageMigrationTo9(
|
||||||
private val db: SQLiteDatabase,
|
private val db: SQLiteDatabase,
|
||||||
private val migrationsHelper: StorageMigrationsHelper
|
private val migrationsHelper: StorageMigrationsHelper
|
||||||
) {
|
) {
|
||||||
fun disablePush() {
|
fun disablePush() {
|
||||||
val accountUuidsListValue = migrationsHelper.readValue(db, "accountUuids")
|
val accountUuidsListValue = migrationsHelper.readValue(db, "accountUuids")
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.fsck.k9.storage.migrations
|
package com.fsck.k9.storage.migrations
|
||||||
|
|
||||||
|
|
||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
import android.database.sqlite.SQLiteDatabase
|
import android.database.sqlite.SQLiteDatabase
|
||||||
import com.fsck.k9.mail.FetchProfile
|
import com.fsck.k9.mail.FetchProfile
|
||||||
|
@ -9,7 +8,6 @@ import com.fsck.k9.mailstore.LocalFolder
|
||||||
import com.fsck.k9.mailstore.LocalStore
|
import com.fsck.k9.mailstore.LocalStore
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
|
|
||||||
internal class FullTextIndexer(val localStore: LocalStore, val database: SQLiteDatabase) {
|
internal class FullTextIndexer(val localStore: LocalStore, val database: SQLiteDatabase) {
|
||||||
private val fulltextCreator = localStore.messageFulltextCreator
|
private val fulltextCreator = localStore.messageFulltextCreator
|
||||||
private val fetchProfile = FetchProfile().apply { add(FetchProfile.Item.BODY) }
|
private val fetchProfile = FetchProfile().apply { add(FetchProfile.Item.BODY) }
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package com.fsck.k9.storage.migrations
|
package com.fsck.k9.storage.migrations
|
||||||
|
|
||||||
|
|
||||||
import android.database.sqlite.SQLiteDatabase
|
import android.database.sqlite.SQLiteDatabase
|
||||||
|
|
||||||
|
|
||||||
internal object MigrationTo64 {
|
internal object MigrationTo64 {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun addExtraValuesTables(db: SQLiteDatabase) {
|
fun addExtraValuesTables(db: SQLiteDatabase) {
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.fsck.k9.storage.migrations
|
||||||
import android.database.sqlite.SQLiteDatabase
|
import android.database.sqlite.SQLiteDatabase
|
||||||
import com.fsck.k9.mailstore.MigrationsHelper
|
import com.fsck.k9.mailstore.MigrationsHelper
|
||||||
|
|
||||||
|
|
||||||
internal object MigrationTo65 {
|
internal object MigrationTo65 {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun addLocalOnlyColumnToFoldersTable(db: SQLiteDatabase, migrationsHelper: MigrationsHelper) {
|
fun addLocalOnlyColumnToFoldersTable(db: SQLiteDatabase, migrationsHelper: MigrationsHelper) {
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.fsck.k9.storage.migrations
|
||||||
|
|
||||||
import android.database.sqlite.SQLiteDatabase
|
import android.database.sqlite.SQLiteDatabase
|
||||||
|
|
||||||
|
|
||||||
internal object MigrationTo66 {
|
internal object MigrationTo66 {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun addEncryptionTypeColumnToMessagesTable(db: SQLiteDatabase) {
|
fun addEncryptionTypeColumnToMessagesTable(db: SQLiteDatabase) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue