From 697f201c151047d3f54bd168559b8d138b1fd3b2 Mon Sep 17 00:00:00 2001 From: cketti Date: Fri, 3 Feb 2023 12:32:09 +0100 Subject: [PATCH 001/317] Prepare for version 6.507 --- app/k9mail/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/k9mail/build.gradle b/app/k9mail/build.gradle index 074462f534..37c4d2c4bc 100644 --- a/app/k9mail/build.gradle +++ b/app/k9mail/build.gradle @@ -54,7 +54,7 @@ android { testApplicationId "com.fsck.k9.tests" versionCode 35006 - versionName '6.506' + versionName '6.507-SNAPSHOT' // Keep in sync with the resource string array 'supported_languages' resConfigs "in", "br", "ca", "cs", "cy", "da", "de", "et", "en", "en_GB", "es", "eo", "eu", "fr", "gd", "gl", -- GitLab From 713dbf9462369db80af16145b9dde06883f3cba2 Mon Sep 17 00:00:00 2001 From: Wolf Montwe Date: Fri, 3 Feb 2023 16:49:14 +0100 Subject: [PATCH 002/317] Add spotless plugin for code formatting and rule for Kotlin sources --- build.gradle | 12 ++++++++++++ gradle/libs.versions.toml | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d54924e0bb..077dd8721b 100644 --- a/build.gradle +++ b/build.gradle @@ -11,6 +11,7 @@ plugins { alias(libs.plugins.kotlin.parcelize) apply false alias(libs.plugins.kotlin.jvm) apply false alias(libs.plugins.ktlint) apply false + alias(libs.plugins.spotless) } project.ext { @@ -101,6 +102,17 @@ allprojects { } } +spotless { + kotlin { + ktlint(libs.versions.ktlint.get()) + .setEditorConfigPath("$projectDir/.editorconfig") + target("**/*.kt") + targetExclude("**/build/", "**/resources/") + trimTrailingWhitespace() + endWithNewline() + } +} + tasks.register('testsOnCi') { dependsOn getSubprojects() .collect { project -> project.tasks.withType(Test) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dff73ab629..a0d6f08e35 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,8 @@ [versions] androidGradlePlugin = "7.4.0" -ktlint = "0.44.0" +ktlint = "0.47.1" +spotless = "6.14.0" kotlin = "1.8.0" kotlinCoroutines = "1.6.4" @@ -39,6 +40,7 @@ kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } ktlint = "org.jlleitschuh.gradle.ktlint:11.0.0" +spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } [libraries] desugar = "com.android.tools:desugar_jdk_libs:1.1.8" -- GitLab From 4a1d7f1d39c49568e542153605e1b30b94477b2e Mon Sep 17 00:00:00 2001 From: Wolf Montwe Date: Fri, 3 Feb 2023 17:17:42 +0100 Subject: [PATCH 003/317] Remove Gradle ktlint plugin --- build.gradle | 6 ------ gradle/libs.versions.toml | 1 - 2 files changed, 7 deletions(-) diff --git a/build.gradle b/build.gradle index 077dd8721b..23eeb67bd4 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,6 @@ plugins { alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.kotlin.parcelize) apply false alias(libs.plugins.kotlin.jvm) apply false - alias(libs.plugins.ktlint) apply false alias(libs.plugins.spotless) } @@ -95,11 +94,6 @@ allprojects { jvmTarget = jvmTargetVersion } } - - apply plugin: 'org.jlleitschuh.gradle.ktlint' - ktlint { - version = libs.versions.ktlint.get() - } } spotless { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a0d6f08e35..dfab2102d5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,7 +39,6 @@ ksp = "com.google.devtools.ksp:1.8.0-1.0.8" kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -ktlint = "org.jlleitschuh.gradle.ktlint:11.0.0" spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } [libraries] -- GitLab From 1854a2c91166fdd53dd02e29ed893d4050b25fe2 Mon Sep 17 00:00:00 2001 From: Wolf Montwe Date: Fri, 3 Feb 2023 17:23:57 +0100 Subject: [PATCH 004/317] Change Kotlin code format --- .../providersxml/ProvidersXmlDiscoveryTest.kt | 2 +- app/core/src/main/java/com/fsck/k9/Account.kt | 14 ++++--- .../fsck/k9/AccountPreferenceSerializer.kt | 22 ++++++---- app/core/src/main/java/com/fsck/k9/Core.kt | 7 ++-- .../k9/autocrypt/AutocryptDraftStateHeader.kt | 16 ++++++-- .../com/fsck/k9/mailstore/FolderSettings.kt | 2 +- .../k9/mailstore/FolderSettingsProvider.kt | 2 +- .../fsck/k9/mailstore/MessageRepository.kt | 2 +- .../k9/mailstore/OutboxStateRepository.kt | 5 ++- .../com/fsck/k9/message/html/UriMatcher.kt | 2 +- .../fsck/k9/notification/CoreKoinModule.kt | 4 +- .../SingleMessageNotificationDataCreator.kt | 4 +- .../com/fsck/k9/power/AndroidPowerManager.kt | 5 ++- .../fsck/k9/preferences/SettingsExporter.kt | 13 ++++-- .../fsck/k9/search/AccountSearchConditions.kt | 4 +- .../fsck/k9/mailstore/K9BackendStorageTest.kt | 2 +- .../k9/mailstore/MessageListRepositoryTest.kt | 2 +- .../fsck/k9/message/html/DisplayHtmlTest.kt | 3 +- ...tificateErrorNotificationControllerTest.kt | 4 +- .../NewMailNotificationManagerTest.kt | 10 ++++- .../k9/notification/NotificationIdsTest.kt | 10 ++--- .../app/k9mail/html/cleaner/BodyCleaner.kt | 8 +++- app/k9mail/src/main/java/com/fsck/k9/App.kt | 2 +- .../src/main/java/com/fsck/k9/Dependencies.kt | 2 +- .../com/fsck/k9/auth/OAuthConfigurations.kt | 2 +- .../K9NotificationResourceProvider.kt | 3 +- .../k9/notification/K9NotificationStrategy.kt | 1 - .../unread/UnreadWidgetDataProviderTest.kt | 16 ++++++-- .../storage/messages/CheckFolderOperations.kt | 3 +- .../storage/messages/CopyMessageOperations.kt | 4 +- .../messages/KeyValueStoreOperations.kt | 16 ++++++-- .../storage/messages/MoveMessageOperations.kt | 4 +- .../messages/RetrieveMessageListOperations.kt | 4 +- .../messages/RetrieveMessageOperations.kt | 6 ++- .../k9/storage/migrations/MigrationTo84.kt | 1 - .../fsck/k9/storage/messages/FolderHelpers.kt | 2 +- .../messages/MessagePartDatabaseHelpers.kt | 2 +- .../messages/RetrieveFolderOperationsTest.kt | 10 ++--- .../NotificationsTableHelpers.kt | 2 +- .../java/com/fsck/k9/ui/base/ThemeManager.kt | 2 +- .../extensions/TextInputLayoutExtensions.kt | 2 +- .../com/fsck/k9/activity/FolderInfoHolder.kt | 3 ++ .../java/com/fsck/k9/activity/MessageList.kt | 4 +- .../k9/activity/MessageListActivityConfig.kt | 4 +- .../k9/activity/compose/RecipientPresenter.kt | 3 +- .../k9/contacts/ContactLetterBitmapCreator.kt | 3 +- .../src/main/java/com/fsck/k9/ui/K9Drawer.kt | 5 ++- .../k9/ui/account/AccountImageModelLoader.kt | 2 +- .../fsck/k9/ui/helper/ContextExtensions.kt | 1 + .../k9/ui/messagelist/MessageListFragment.kt | 5 ++- .../k9/ui/messageview/MessageViewFragment.kt | 32 +++++++++++---- .../k9/ui/messageview/RecipientNamesView.kt | 10 ++++- .../fsck/k9/ui/settings/SettingsViewModel.kt | 2 +- .../account/AccountSettingsDataStore.kt | 2 +- .../AutocryptPreferEncryptPreference.kt | 6 ++- .../settings/account/FolderListPreference.kt | 3 +- .../account/NotificationsPreference.kt | 6 ++- .../settings/account/VibrationPreference.kt | 3 +- .../compose/AttachmentPresenterTest.kt | 23 ++++++++--- .../compose/RecipientPresenterTest.kt | 18 ++++++--- .../fsck/k9/message/PgpMessageBuilderTest.kt | 40 +++++++++++++------ .../k9mail/ui/widget/list/MessageListItem.kt | 2 +- .../ui/widget/list/MessageListItemMapper.kt | 2 +- .../widget/list/MessageListWidgetManager.kt | 2 +- .../backend/imap/CommandMoveOrCopyMessages.kt | 8 +++- .../java/com/fsck/k9/backend/imap/ImapSync.kt | 24 ++++++++--- .../k9/mail/internet/MimeParameterDecoder.kt | 7 +++- .../fsck/k9/mail/internet/PartExtensions.kt | 1 + .../main/java/com/fsck/k9/sasl/OAuthBearer.kt | 1 + .../k9/mail/store/imap/RealImapConnection.kt | 9 ++++- .../fsck/k9/mail/store/imap/RealImapFolder.kt | 20 +++++++--- .../k9/mail/store/imap/UidValidityResponse.kt | 4 +- .../mail/store/imap/RealImapConnectionTest.kt | 2 +- .../k9/mail/store/imap/RealImapFolderTest.kt | 4 +- .../k9/mail/store/imap/RealImapStoreTest.kt | 5 ++- .../k9/mail/transport/smtp/SmtpTransport.kt | 3 +- 76 files changed, 343 insertions(+), 153 deletions(-) diff --git a/app/autodiscovery/providersxml/src/test/java/com/fsck/k9/autodiscovery/providersxml/ProvidersXmlDiscoveryTest.kt b/app/autodiscovery/providersxml/src/test/java/com/fsck/k9/autodiscovery/providersxml/ProvidersXmlDiscoveryTest.kt index f91ce3b38d..d37fae5611 100644 --- a/app/autodiscovery/providersxml/src/test/java/com/fsck/k9/autodiscovery/providersxml/ProvidersXmlDiscoveryTest.kt +++ b/app/autodiscovery/providersxml/src/test/java/com/fsck/k9/autodiscovery/providersxml/ProvidersXmlDiscoveryTest.kt @@ -53,7 +53,7 @@ class ProvidersXmlDiscoveryTest : RobolectricTest() { return OAuthConfigurationProvider( configurations = mapOf( - listOf("imap.gmail.com", "smtp.gmail.com") to googleConfig, + listOf("imap.gmail.com", "smtp.gmail.com") to googleConfig ), googleConfiguration = googleConfig ) diff --git a/app/core/src/main/java/com/fsck/k9/Account.kt b/app/core/src/main/java/com/fsck/k9/Account.kt index 7f155d5cf5..9dc569a0b8 100644 --- a/app/core/src/main/java/com/fsck/k9/Account.kt +++ b/app/core/src/main/java/com/fsck/k9/Account.kt @@ -551,12 +551,14 @@ class Account(override val uuid: String) : BaseAccount { if (age < 28) { now.add(Calendar.DATE, age * -1) - } else when (age) { - 28 -> now.add(Calendar.MONTH, -1) - 56 -> now.add(Calendar.MONTH, -2) - 84 -> now.add(Calendar.MONTH, -3) - 168 -> now.add(Calendar.MONTH, -6) - 365 -> now.add(Calendar.YEAR, -1) + } else { + when (age) { + 28 -> now.add(Calendar.MONTH, -1) + 56 -> now.add(Calendar.MONTH, -2) + 84 -> now.add(Calendar.MONTH, -3) + 168 -> now.add(Calendar.MONTH, -6) + 365 -> now.add(Calendar.YEAR, -1) + } } return now.time diff --git a/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt b/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt index e9b8ffe31a..851bf8d9e3 100644 --- a/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt +++ b/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt @@ -67,35 +67,40 @@ class AccountPreferenceSerializer( val draftsFolderId = storage.getString("$accountUuid.draftsFolderId", null)?.toLongOrNull() val draftsFolderSelection = getEnumStringPref( - storage, "$accountUuid.draftsFolderSelection", + storage, + "$accountUuid.draftsFolderSelection", SpecialFolderSelection.AUTOMATIC ) setDraftsFolderId(draftsFolderId, draftsFolderSelection) val sentFolderId = storage.getString("$accountUuid.sentFolderId", null)?.toLongOrNull() val sentFolderSelection = getEnumStringPref( - storage, "$accountUuid.sentFolderSelection", + storage, + "$accountUuid.sentFolderSelection", SpecialFolderSelection.AUTOMATIC ) setSentFolderId(sentFolderId, sentFolderSelection) val trashFolderId = storage.getString("$accountUuid.trashFolderId", null)?.toLongOrNull() val trashFolderSelection = getEnumStringPref( - storage, "$accountUuid.trashFolderSelection", + storage, + "$accountUuid.trashFolderSelection", SpecialFolderSelection.AUTOMATIC ) setTrashFolderId(trashFolderId, trashFolderSelection) val archiveFolderId = storage.getString("$accountUuid.archiveFolderId", null)?.toLongOrNull() val archiveFolderSelection = getEnumStringPref( - storage, "$accountUuid.archiveFolderSelection", + storage, + "$accountUuid.archiveFolderSelection", SpecialFolderSelection.AUTOMATIC ) setArchiveFolderId(archiveFolderId, archiveFolderSelection) val spamFolderId = storage.getString("$accountUuid.spamFolderId", null)?.toLongOrNull() val spamFolderSelection = getEnumStringPref( - storage, "$accountUuid.spamFolderSelection", + storage, + "$accountUuid.spamFolderSelection", SpecialFolderSelection.AUTOMATIC ) setSpamFolderId(spamFolderId, spamFolderSelection) @@ -524,8 +529,11 @@ class AccountPreferenceSerializer( java.lang.Enum.valueOf(defaultEnum.declaringJavaClass, stringPref) } catch (ex: IllegalArgumentException) { Timber.w( - ex, "Unable to convert preference key [%s] value [%s] to enum of type %s", - key, stringPref, defaultEnum.declaringJavaClass + ex, + "Unable to convert preference key [%s] value [%s] to enum of type %s", + key, + stringPref, + defaultEnum.declaringJavaClass ) defaultEnum diff --git a/app/core/src/main/java/com/fsck/k9/Core.kt b/app/core/src/main/java/com/fsck/k9/Core.kt index 75e8201ec3..ea140fe371 100644 --- a/app/core/src/main/java/com/fsck/k9/Core.kt +++ b/app/core/src/main/java/com/fsck/k9/Core.kt @@ -65,10 +65,11 @@ object Core : EarlyInit { if (enabled != alreadyEnabled) { pm.setComponentEnabledSetting( ComponentName(context, clazz), - if (enabled) + if (enabled) { PackageManager.COMPONENT_ENABLED_STATE_ENABLED - else - PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + } else { + PackageManager.COMPONENT_ENABLED_STATE_DISABLED + }, PackageManager.DONT_KILL_APP ) } diff --git a/app/core/src/main/java/com/fsck/k9/autocrypt/AutocryptDraftStateHeader.kt b/app/core/src/main/java/com/fsck/k9/autocrypt/AutocryptDraftStateHeader.kt index e3711c4cfb..bcb3f09d46 100644 --- a/app/core/src/main/java/com/fsck/k9/autocrypt/AutocryptDraftStateHeader.kt +++ b/app/core/src/main/java/com/fsck/k9/autocrypt/AutocryptDraftStateHeader.kt @@ -49,13 +49,21 @@ data class AutocryptDraftStateHeader( fun fromCryptoStatus(cryptoStatus: CryptoStatus): AutocryptDraftStateHeader { if (cryptoStatus.isSignOnly) { return AutocryptDraftStateHeader( - false, true, cryptoStatus.isReplyToEncrypted, - cryptoStatus.isUserChoice(), cryptoStatus.isPgpInlineModeEnabled, mapOf() + false, + true, + cryptoStatus.isReplyToEncrypted, + cryptoStatus.isUserChoice(), + cryptoStatus.isPgpInlineModeEnabled, + mapOf() ) } return AutocryptDraftStateHeader( - cryptoStatus.isEncryptionEnabled, false, cryptoStatus.isReplyToEncrypted, - cryptoStatus.isUserChoice(), cryptoStatus.isPgpInlineModeEnabled, mapOf() + cryptoStatus.isEncryptionEnabled, + false, + cryptoStatus.isReplyToEncrypted, + cryptoStatus.isUserChoice(), + cryptoStatus.isPgpInlineModeEnabled, + mapOf() ) } } diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/FolderSettings.kt b/app/core/src/main/java/com/fsck/k9/mailstore/FolderSettings.kt index 0aa6ab7809..11d046e298 100644 --- a/app/core/src/main/java/com/fsck/k9/mailstore/FolderSettings.kt +++ b/app/core/src/main/java/com/fsck/k9/mailstore/FolderSettings.kt @@ -9,5 +9,5 @@ data class FolderSettings( val notifyClass: FolderClass, val pushClass: FolderClass, val inTopGroup: Boolean, - val integrate: Boolean, + val integrate: Boolean ) diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/FolderSettingsProvider.kt b/app/core/src/main/java/com/fsck/k9/mailstore/FolderSettingsProvider.kt index ef5dd3363f..cc8125d2c7 100644 --- a/app/core/src/main/java/com/fsck/k9/mailstore/FolderSettingsProvider.kt +++ b/app/core/src/main/java/com/fsck/k9/mailstore/FolderSettingsProvider.kt @@ -19,7 +19,7 @@ class FolderSettingsProvider(val preferences: Preferences, val account: Account) notifyClass = storage.getString("$prefix.notifyMode", null).toFolderClass(FolderClass.INHERITED), pushClass = storage.getString("$prefix.pushMode", null).toFolderClass(FolderClass.SECOND_CLASS), inTopGroup = storage.getBoolean("$prefix.inTopGroup", false), - integrate = storage.getBoolean("$prefix.integrate", false), + integrate = storage.getBoolean("$prefix.integrate", false) ).also { removeImportedFolderSettings(prefix) } diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/MessageRepository.kt b/app/core/src/main/java/com/fsck/k9/mailstore/MessageRepository.kt index e2fc950b16..a73c67010e 100644 --- a/app/core/src/main/java/com/fsck/k9/mailstore/MessageRepository.kt +++ b/app/core/src/main/java/com/fsck/k9/mailstore/MessageRepository.kt @@ -63,7 +63,7 @@ class MessageRepository(private val messageStoreManager: MessageStoreManager) { "reply-to", "to", "cc", - "bcc", + "bcc" ) } } diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/OutboxStateRepository.kt b/app/core/src/main/java/com/fsck/k9/mailstore/OutboxStateRepository.kt index c2c11aa932..360b9a1b51 100644 --- a/app/core/src/main/java/com/fsck/k9/mailstore/OutboxStateRepository.kt +++ b/app/core/src/main/java/com/fsck/k9/mailstore/OutboxStateRepository.kt @@ -15,7 +15,10 @@ class OutboxStateRepository(private val database: LockableDatabase, private val TABLE_NAME, COLUMNS, "$COLUMN_MESSAGE_ID = ?", - arrayOf(messageId.toString()), null, null, null + arrayOf(messageId.toString()), + null, + null, + null ).use { cursor -> if (!cursor.moveToFirst()) { throw IllegalStateException("No outbox_state entry for message with id $messageId") diff --git a/app/core/src/main/java/com/fsck/k9/message/html/UriMatcher.kt b/app/core/src/main/java/com/fsck/k9/message/html/UriMatcher.kt index 44329acfdb..2d29463e8a 100644 --- a/app/core/src/main/java/com/fsck/k9/message/html/UriMatcher.kt +++ b/app/core/src/main/java/com/fsck/k9/message/html/UriMatcher.kt @@ -10,7 +10,7 @@ object UriMatcher { "mailto:" to genericUriParser, "matrix:" to genericUriParser, "rtsp:" to httpUriParser, - "xmpp:" to genericUriParser, + "xmpp:" to genericUriParser ) } diff --git a/app/core/src/main/java/com/fsck/k9/notification/CoreKoinModule.kt b/app/core/src/main/java/com/fsck/k9/notification/CoreKoinModule.kt index f0ac2f20ec..6b1ce14839 100644 --- a/app/core/src/main/java/com/fsck/k9/notification/CoreKoinModule.kt +++ b/app/core/src/main/java/com/fsck/k9/notification/CoreKoinModule.kt @@ -120,7 +120,9 @@ val coreNotificationModule = module { } factory { NotificationSettingsUpdater( - preferences = get(), notificationChannelManager = get(), notificationConfigurationConverter = get() + preferences = get(), + notificationChannelManager = get(), + notificationConfigurationConverter = get() ) } } diff --git a/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotificationDataCreator.kt b/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotificationDataCreator.kt index d095ef00b6..f693ab39f1 100644 --- a/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotificationDataCreator.kt +++ b/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotificationDataCreator.kt @@ -36,8 +36,8 @@ internal class SingleMessageNotificationDataCreator { content = data.activeNotifications.first().content, actions = createSingleNotificationActions(), wearActions = createSingleNotificationWearActions(data.account), - addLockScreenNotification = false, - ), + addLockScreenNotification = false + ) ) } diff --git a/app/core/src/main/java/com/fsck/k9/power/AndroidPowerManager.kt b/app/core/src/main/java/com/fsck/k9/power/AndroidPowerManager.kt index fbf30c048d..51546280ee 100644 --- a/app/core/src/main/java/com/fsck/k9/power/AndroidPowerManager.kt +++ b/app/core/src/main/java/com/fsck/k9/power/AndroidPowerManager.kt @@ -70,7 +70,10 @@ internal class AndroidPowerManager(private val systemPowerManager: SystemPowerMa Timber.v( "AndroidWakeLock for tag %s / id %d: releasing after %d ms, timeout = %d ms", - tag, id, endTime - startTime, timeout + tag, + id, + endTime - startTime, + timeout ) } else { Timber.v("AndroidWakeLock for tag %s / id %d, timeout = %d ms: releasing", tag, id, timeout) diff --git a/app/core/src/main/java/com/fsck/k9/preferences/SettingsExporter.kt b/app/core/src/main/java/com/fsck/k9/preferences/SettingsExporter.kt index 08bc5bbefc..0098813b3f 100644 --- a/app/core/src/main/java/com/fsck/k9/preferences/SettingsExporter.kt +++ b/app/core/src/main/java/com/fsck/k9/preferences/SettingsExporter.kt @@ -105,7 +105,8 @@ class SettingsExporter( } catch (e: InvalidSettingValueException) { Timber.w( "Global setting \"%s\" has invalid value \"%s\" in preference storage. This shouldn't happen!", - key, valueString + key, + valueString ) } } else { @@ -271,7 +272,9 @@ class SettingsExporter( Timber.w( "Account setting \"%s\" (%s) has invalid value \"%s\" in preference storage. " + "This shouldn't happen!", - keyPart, account, valueString + keyPart, + account, + valueString ) } } @@ -375,7 +378,8 @@ class SettingsExporter( Timber.w( "Identity setting \"%s\" has invalid value \"%s\" in preference storage. " + "This shouldn't happen!", - identityKey, valueString + identityKey, + valueString ) } } @@ -413,7 +417,8 @@ class SettingsExporter( } catch (e: InvalidSettingValueException) { Timber.w( "Folder setting \"%s\" has invalid value \"%s\" in preference storage. This shouldn't happen!", - key, value + key, + value ) } } diff --git a/app/core/src/main/java/com/fsck/k9/search/AccountSearchConditions.kt b/app/core/src/main/java/com/fsck/k9/search/AccountSearchConditions.kt index 51e80f8d95..3a0beef26c 100644 --- a/app/core/src/main/java/com/fsck/k9/search/AccountSearchConditions.kt +++ b/app/core/src/main/java/com/fsck/k9/search/AccountSearchConditions.kt @@ -25,7 +25,9 @@ fun LocalSearch.limitToDisplayableFolders(account: Account) { // TODO: Create a proper interface for creating arbitrary condition trees val searchCondition = SearchCondition( - SearchField.DISPLAY_CLASS, Attribute.EQUALS, FolderClass.SECOND_CLASS.name + SearchField.DISPLAY_CLASS, + Attribute.EQUALS, + FolderClass.SECOND_CLASS.name ) val root = conditions if (root.mRight != null) { diff --git a/app/core/src/test/java/com/fsck/k9/mailstore/K9BackendStorageTest.kt b/app/core/src/test/java/com/fsck/k9/mailstore/K9BackendStorageTest.kt index ed0009a78e..ccd2fee8cb 100644 --- a/app/core/src/test/java/com/fsck/k9/mailstore/K9BackendStorageTest.kt +++ b/app/core/src/test/java/com/fsck/k9/mailstore/K9BackendStorageTest.kt @@ -86,7 +86,7 @@ internal fun createFolderSettingsProvider(): FolderSettingsProvider { notifyClass = FolderClass.INHERITED, pushClass = FolderClass.SECOND_CLASS, inTopGroup = false, - integrate = false, + integrate = false ) } } diff --git a/app/core/src/test/java/com/fsck/k9/mailstore/MessageListRepositoryTest.kt b/app/core/src/test/java/com/fsck/k9/mailstore/MessageListRepositoryTest.kt index 300356f22f..f9284a768a 100644 --- a/app/core/src/test/java/com/fsck/k9/mailstore/MessageListRepositoryTest.kt +++ b/app/core/src/test/java/com/fsck/k9/mailstore/MessageListRepositoryTest.kt @@ -429,5 +429,5 @@ private data class MessageData( val isRead: Boolean = false, val isStarred: Boolean = false, val isAnswered: Boolean = false, - val isForwarded: Boolean = false, + val isForwarded: Boolean = false ) diff --git a/app/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt b/app/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt index eeca7b4477..080355a4db 100644 --- a/app/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt +++ b/app/core/src/test/java/com/fsck/k9/message/html/DisplayHtmlTest.kt @@ -51,7 +51,8 @@ class DisplayHtmlTest { val numberOfFoundElements = document.select(cssQuery).size assertEquals( "Expected to find '$cssQuery' $numberOfExpectedOccurrences time(s) in:\n$html", - numberOfExpectedOccurrences, numberOfFoundElements + numberOfExpectedOccurrences, + numberOfFoundElements ) } } diff --git a/app/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt b/app/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt index 74c18c892d..3681ff4a00 100644 --- a/app/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt +++ b/app/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt @@ -113,7 +113,9 @@ class CertificateErrorNotificationControllerTest : RobolectricTest() { } internal inner class TestCertificateErrorNotificationController : CertificateErrorNotificationController( - notificationHelper, mock(), resourceProvider + notificationHelper, + mock(), + resourceProvider ) { override fun createContentIntent(account: Account, incoming: Boolean): PendingIntent { return contentIntent diff --git a/app/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt b/app/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt index 105f49649b..dda7ca6afc 100644 --- a/app/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt +++ b/app/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt @@ -382,7 +382,10 @@ class NewMailNotificationManagerTest { on { createFromMessage(account, message) } doReturn NotificationContent( messageReference = createMessageReference(messageUid), - sender, subject, preview, summary + sender, + subject, + preview, + summary ) } @@ -407,7 +410,10 @@ class NewMailNotificationManagerTest { on { createFromMessage(account, message) } doReturn NotificationContent( messageReference = createMessageReference(messageUid), - sender, subject, preview, summary + sender, + subject, + preview, + summary ) } } diff --git a/app/core/src/test/java/com/fsck/k9/notification/NotificationIdsTest.kt b/app/core/src/test/java/com/fsck/k9/notification/NotificationIdsTest.kt index 9c326bc522..dcc9a67c1a 100644 --- a/app/core/src/test/java/com/fsck/k9/notification/NotificationIdsTest.kt +++ b/app/core/src/test/java/com/fsck/k9/notification/NotificationIdsTest.kt @@ -41,9 +41,9 @@ class NotificationIdsTest { } @Test - // We avoid gaps. So this test failing is an indication that getGeneralNotificationIds() and/or - // getAccountNotificationIds() need to be updated. fun `no gaps between general and account notification IDs`() { + // We avoid gaps. So this test failing is an indication that getGeneralNotificationIds() and/or + // getAccountNotificationIds() need to be updated. val account = createAccount(0) val generalNotificationIds = getGeneralNotificationIds() @@ -55,8 +55,8 @@ class NotificationIdsTest { } @Test - // We avoid gaps. So this test failing is an indication that getAccountNotificationIds() needs to be updated. fun `no gaps in notification IDs of an account`() { + // We avoid gaps. So this test failing is an indication that getAccountNotificationIds() needs to be updated. val account = createAccount(0) val notificationIds = getAccountNotificationIds(account) @@ -68,8 +68,8 @@ class NotificationIdsTest { } @Test - // We avoid gaps. So this test failing is an indication that getAccountNotificationIds() needs to be updated. fun `no gap between notification IDs of adjacent accounts`() { + // We avoid gaps. So this test failing is an indication that getAccountNotificationIds() needs to be updated. val account1 = createAccount(1) val account2 = createAccount(2) @@ -104,7 +104,7 @@ class NotificationIdsTest { NotificationIds.getAuthenticationErrorNotificationId(account, true), NotificationIds.getAuthenticationErrorNotificationId(account, false), NotificationIds.getFetchingMailNotificationId(account), - NotificationIds.getNewMailSummaryNotificationId(account), + NotificationIds.getNewMailSummaryNotificationId(account) ) + getNewMessageNotificationIds(account) } diff --git a/app/html-cleaner/src/main/java/app/k9mail/html/cleaner/BodyCleaner.kt b/app/html-cleaner/src/main/java/app/k9mail/html/cleaner/BodyCleaner.kt index 43a6d82738..0f0e5cd779 100644 --- a/app/html-cleaner/src/main/java/app/k9mail/html/cleaner/BodyCleaner.kt +++ b/app/html-cleaner/src/main/java/app/k9mail/html/cleaner/BodyCleaner.kt @@ -18,7 +18,13 @@ internal class BodyCleaner { .addAttributes("a", "name") .addAttributes("div", "align") .addAttributes( - "table", "align", "background", "bgcolor", "border", "cellpadding", "cellspacing", + "table", + "align", + "background", + "bgcolor", + "border", + "cellpadding", + "cellspacing", "width" ) .addAttributes("tr", "align", "background", "bgcolor", "valign") diff --git a/app/k9mail/src/main/java/com/fsck/k9/App.kt b/app/k9mail/src/main/java/com/fsck/k9/App.kt index 7f87dcfe2b..c48017178d 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/App.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/App.kt @@ -138,7 +138,7 @@ class App : Application(), WorkManagerConfiguration.Provider { MessageCompose::class.java, LauncherShortcuts::class.java, UnreadWidgetProvider::class.java, - MessageListWidgetProvider::class.java, + MessageListWidgetProvider::class.java ) ) } diff --git a/app/k9mail/src/main/java/com/fsck/k9/Dependencies.kt b/app/k9mail/src/main/java/com/fsck/k9/Dependencies.kt index 8967c972a6..76936bbbc1 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/Dependencies.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/Dependencies.kt @@ -22,7 +22,7 @@ private val mainAppModule = module { single { MessagingListenerProvider( listOf( - get(), + get() ) ) } diff --git a/app/k9mail/src/main/java/com/fsck/k9/auth/OAuthConfigurations.kt b/app/k9mail/src/main/java/com/fsck/k9/auth/OAuthConfigurations.kt index 639a1934aa..4f1b5f47b5 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/auth/OAuthConfigurations.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/auth/OAuthConfigurations.kt @@ -39,7 +39,7 @@ fun createOAuthConfigurationProvider(): OAuthConfigurationProvider { authorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token", redirectUri = BuildConfig.OAUTH_MICROSOFT_REDIRECT_URI - ), + ) ), googleConfiguration = googleConfig ) diff --git a/app/k9mail/src/main/java/com/fsck/k9/notification/K9NotificationResourceProvider.kt b/app/k9mail/src/main/java/com/fsck/k9/notification/K9NotificationResourceProvider.kt index 917d492c3d..2c1eea2603 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/notification/K9NotificationResourceProvider.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/notification/K9NotificationResourceProvider.kt @@ -50,7 +50,8 @@ class K9NotificationResourceProvider(private val context: Context) : Notificatio override fun newMessagesTitle(newMessagesCount: Int): String = context.resources.getQuantityString( R.plurals.notification_new_messages_title, - newMessagesCount, newMessagesCount + newMessagesCount, + newMessagesCount ) override fun additionalMessages(overflowMessagesCount: Int, accountName: String): String = diff --git a/app/k9mail/src/main/java/com/fsck/k9/notification/K9NotificationStrategy.kt b/app/k9mail/src/main/java/com/fsck/k9/notification/K9NotificationStrategy.kt index 222c54c65d..2221cd0e6a 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/notification/K9NotificationStrategy.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/notification/K9NotificationStrategy.kt @@ -19,7 +19,6 @@ class K9NotificationStrategy(private val contacts: Contacts) : NotificationStrat message: LocalMessage, isOldMessage: Boolean ): Boolean { - if (!K9.isNotificationDuringQuietTimeEnabled && K9.isQuietTime) { Timber.v("No notification: Quiet time is active") return false diff --git a/app/k9mail/src/test/java/com/fsck/k9/widget/unread/UnreadWidgetDataProviderTest.kt b/app/k9mail/src/test/java/com/fsck/k9/widget/unread/UnreadWidgetDataProviderTest.kt index 1af67b3dc4..42bda43286 100644 --- a/app/k9mail/src/test/java/com/fsck/k9/widget/unread/UnreadWidgetDataProviderTest.kt +++ b/app/k9mail/src/test/java/com/fsck/k9/widget/unread/UnreadWidgetDataProviderTest.kt @@ -29,14 +29,20 @@ class UnreadWidgetDataProviderTest : AppRobolectricTest() { private val folderRepository = createFolderRepository() private val folderNameFormatterFactory = createFolderNameFormatterFactory() private val provider = UnreadWidgetDataProvider( - context, preferences, messageCountsProvider, defaultFolderStrategy, - folderRepository, folderNameFormatterFactory + context, + preferences, + messageCountsProvider, + defaultFolderStrategy, + folderRepository, + folderNameFormatterFactory ) @Test fun unifiedInbox() { val configuration = UnreadWidgetConfiguration( - appWidgetId = 1, accountUuid = SearchAccount.UNIFIED_INBOX, folderId = null + appWidgetId = 1, + accountUuid = SearchAccount.UNIFIED_INBOX, + folderId = null ) val widgetData = provider.loadUnreadWidgetData(configuration) @@ -50,7 +56,9 @@ class UnreadWidgetDataProviderTest : AppRobolectricTest() { @Test fun regularAccount() { val configuration = UnreadWidgetConfiguration( - appWidgetId = 3, accountUuid = ACCOUNT_UUID, folderId = null + appWidgetId = 3, + accountUuid = ACCOUNT_UUID, + folderId = null ) val widgetData = provider.loadUnreadWidgetData(configuration) diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/CheckFolderOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/CheckFolderOperations.kt index c7975042d8..37e0a87452 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/messages/CheckFolderOperations.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/CheckFolderOperations.kt @@ -13,7 +13,8 @@ internal class CheckFolderOperations(private val lockableDatabase: LockableDatab ) { selectionSet, selectionArguments -> if (allIncludedInUnifiedInbox) { database.rawQuery( - "SELECT COUNT(id) FROM folders WHERE integrate = 1 AND id $selectionSet", selectionArguments + "SELECT COUNT(id) FROM folders WHERE integrate = 1 AND id $selectionSet", + selectionArguments ).use { cursor -> if (cursor.moveToFirst()) { val count = cursor.getInt(0) diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/CopyMessageOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/CopyMessageOperations.kt index 71afa9ae61..a01b2a3d4d 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/messages/CopyMessageOperations.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/CopyMessageOperations.kt @@ -236,7 +236,9 @@ ORDER BY message_parts.seq ), "id = ?", arrayOf(messageId.toString()), - null, null, null + null, + null, + null ).use { cursor -> if (!cursor.moveToNext()) error("Message with ID $messageId not found") diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/KeyValueStoreOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/KeyValueStoreOperations.kt index 7d02438a8d..cb2e4e4fad 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/messages/KeyValueStoreOperations.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/KeyValueStoreOperations.kt @@ -14,7 +14,9 @@ internal class KeyValueStoreOperations(private val lockableDatabase: LockableDat arrayOf("value_text"), "name = ?", arrayOf(name), - null, null, null + null, + null, + null ).use { cursor -> if (cursor.moveToFirst()) { cursor.getStringOrNull(0) @@ -42,7 +44,9 @@ internal class KeyValueStoreOperations(private val lockableDatabase: LockableDat arrayOf("value_integer"), "name = ?", arrayOf(name), - null, null, null + null, + null, + null ).use { cursor -> if (cursor.moveToFirst()) { cursor.getLongOrNull(0) @@ -70,7 +74,9 @@ internal class KeyValueStoreOperations(private val lockableDatabase: LockableDat arrayOf("value_text"), "name = ? AND folder_id = ?", arrayOf(name, folderId.toString()), - null, null, null + null, + null, + null ).use { cursor -> if (cursor.moveToFirst()) { cursor.getStringOrNull(0) @@ -99,7 +105,9 @@ internal class KeyValueStoreOperations(private val lockableDatabase: LockableDat arrayOf("value_integer"), "name = ? AND folder_id = ?", arrayOf(name, folderId.toString()), - null, null, null + null, + null, + null ).use { cursor -> if (cursor.moveToFirst()) { cursor.getLongOrNull(0) diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/MoveMessageOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/MoveMessageOperations.kt index 62ae5124ed..10792153b6 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/messages/MoveMessageOperations.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/MoveMessageOperations.kt @@ -55,7 +55,9 @@ internal class MoveMessageOperations( ), "id = ?", arrayOf(messageId.toString()), - null, null, null + null, + null, + null ).use { cursor -> if (!cursor.moveToFirst()) { error("Couldn't find local message [ID: $messageId]") diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageListOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageListOperations.kt index d84480e44f..ddf0a397a9 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageListOperations.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageListOperations.kt @@ -46,7 +46,7 @@ WHERE AND empty = 0 AND deleted = 0 ORDER BY $sortOrder """, - selectionArgs, + selectionArgs ).use { cursor -> val cursorMessageAccessor = CursorMessageAccessor(cursor, includesThreadCount = false) buildList { @@ -171,7 +171,7 @@ WHERE AND empty = 0 AND deleted = 0 ORDER BY $sortOrder """, - arrayOf(threadId.toString()), + arrayOf(threadId.toString()) ).use { cursor -> val cursorMessageAccessor = CursorMessageAccessor(cursor, includesThreadCount = false) buildList { diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageOperations.kt index 041dda7474..49e39e7ab8 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageOperations.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageOperations.kt @@ -20,7 +20,9 @@ internal class RetrieveMessageOperations(private val lockableDatabase: LockableD arrayOf("uid"), "id = ?", arrayOf(messageId.toString()), - null, null, null + null, + null, + null ).use { cursor -> if (cursor.moveToFirst()) { cursor.getString(0) @@ -174,7 +176,7 @@ internal class RetrieveMessageOperations(private val lockableDatabase: LockableD "SELECT message_parts.header FROM messages" + " LEFT JOIN message_parts ON (messages.message_part_id = message_parts.id)" + " WHERE messages.folder_id = ? AND messages.uid = ?", - arrayOf(folderId.toString(), messageServerId), + arrayOf(folderId.toString(), messageServerId) ).use { cursor -> if (!cursor.moveToFirst()) throw MessageNotFoundException(folderId, messageServerId) diff --git a/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo84.kt b/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo84.kt index 01db3ebd80..c1b2326a4d 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo84.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo84.kt @@ -17,7 +17,6 @@ internal class MigrationTo84(private val db: SQLiteDatabase) { null ).use { cursor -> cursor.map { - val messageId = it.getLong(0) messageId to AddressSet( diff --git a/app/storage/src/test/java/com/fsck/k9/storage/messages/FolderHelpers.kt b/app/storage/src/test/java/com/fsck/k9/storage/messages/FolderHelpers.kt index b2ea71b55d..56d6165496 100644 --- a/app/storage/src/test/java/com/fsck/k9/storage/messages/FolderHelpers.kt +++ b/app/storage/src/test/java/com/fsck/k9/storage/messages/FolderHelpers.kt @@ -23,7 +23,7 @@ fun SQLiteDatabase.createFolder( visibleLimit: Int = 25, status: String? = null, flaggedCount: Int = 0, - moreMessages: String = "unknown", + moreMessages: String = "unknown" ): Long { val values = ContentValues().apply { put("name", name) diff --git a/app/storage/src/test/java/com/fsck/k9/storage/messages/MessagePartDatabaseHelpers.kt b/app/storage/src/test/java/com/fsck/k9/storage/messages/MessagePartDatabaseHelpers.kt index 6aadf98f39..d155a0b4e8 100644 --- a/app/storage/src/test/java/com/fsck/k9/storage/messages/MessagePartDatabaseHelpers.kt +++ b/app/storage/src/test/java/com/fsck/k9/storage/messages/MessagePartDatabaseHelpers.kt @@ -71,7 +71,7 @@ fun SQLiteDatabase.readMessageParts(): List { epilogue = cursor.getStringOrNull("epilogue"), boundary = cursor.getStringOrNull("boundary"), contentId = cursor.getStringOrNull("content_id"), - serverExtra = cursor.getStringOrNull("server_extra"), + serverExtra = cursor.getStringOrNull("server_extra") ) } } diff --git a/app/storage/src/test/java/com/fsck/k9/storage/messages/RetrieveFolderOperationsTest.kt b/app/storage/src/test/java/com/fsck/k9/storage/messages/RetrieveFolderOperationsTest.kt index 4b4c6ed8e7..41d1e9006a 100644 --- a/app/storage/src/test/java/com/fsck/k9/storage/messages/RetrieveFolderOperationsTest.kt +++ b/app/storage/src/test/java/com/fsck/k9/storage/messages/RetrieveFolderOperationsTest.kt @@ -197,7 +197,7 @@ class RetrieveFolderOperationsTest : RobolectricTest() { val (folderId1, folderId2, _) = listOf( sqliteDatabase.createFolder(name = "Folder 1", displayClass = "FIRST_CLASS"), sqliteDatabase.createFolder(name = "Folder 2", displayClass = "SECOND_CLASS"), - sqliteDatabase.createFolder(name = "Folder 3", displayClass = "NO_CLASS"), + sqliteDatabase.createFolder(name = "Folder 3", displayClass = "NO_CLASS") ) val result = retrieveFolderOperations.getDisplayFolders( @@ -215,7 +215,7 @@ class RetrieveFolderOperationsTest : RobolectricTest() { val (folderId1, _, folderId3) = listOf( sqliteDatabase.createFolder(name = "Folder 1", displayClass = "FIRST_CLASS"), sqliteDatabase.createFolder(name = "Folder 2", displayClass = "SECOND_CLASS"), - sqliteDatabase.createFolder(name = "Folder 3", displayClass = "NO_CLASS"), + sqliteDatabase.createFolder(name = "Folder 3", displayClass = "NO_CLASS") ) val result = retrieveFolderOperations.getDisplayFolders( @@ -238,7 +238,7 @@ class RetrieveFolderOperationsTest : RobolectricTest() { val (folderId1, folderId2, _) = listOf( sqliteDatabase.createFolder(name = "Folder 1", displayClass = "FIRST_CLASS"), sqliteDatabase.createFolder(name = "Folder 2", displayClass = "SECOND_CLASS"), - sqliteDatabase.createFolder(name = "Folder 3", displayClass = "NO_CLASS"), + sqliteDatabase.createFolder(name = "Folder 3", displayClass = "NO_CLASS") ) val result = retrieveFolderOperations.getDisplayFolders( @@ -292,7 +292,7 @@ class RetrieveFolderOperationsTest : RobolectricTest() { fun `get folder id`() { val (_, folderId2) = listOf( sqliteDatabase.createFolder(serverId = "folder1"), - sqliteDatabase.createFolder(serverId = "folder2"), + sqliteDatabase.createFolder(serverId = "folder2") ) val result = retrieveFolderOperations.getFolderId(folderServerId = "folder2") @@ -311,7 +311,7 @@ class RetrieveFolderOperationsTest : RobolectricTest() { fun `get folder server id`() { val (_, folderId2) = listOf( sqliteDatabase.createFolder(serverId = "folder1"), - sqliteDatabase.createFolder(serverId = "folder2"), + sqliteDatabase.createFolder(serverId = "folder2") ) val result = retrieveFolderOperations.getFolderServerId(folderId2) diff --git a/app/storage/src/test/java/com/fsck/k9/storage/notifications/NotificationsTableHelpers.kt b/app/storage/src/test/java/com/fsck/k9/storage/notifications/NotificationsTableHelpers.kt index 80f0461e4d..d31b531980 100644 --- a/app/storage/src/test/java/com/fsck/k9/storage/notifications/NotificationsTableHelpers.kt +++ b/app/storage/src/test/java/com/fsck/k9/storage/notifications/NotificationsTableHelpers.kt @@ -36,5 +36,5 @@ fun SQLiteDatabase.readNotifications(): List { data class NotificationEntry( val messageId: Long?, val notificationId: Int?, - val timestamp: Long?, + val timestamp: Long? ) diff --git a/app/ui/base/src/main/java/com/fsck/k9/ui/base/ThemeManager.kt b/app/ui/base/src/main/java/com/fsck/k9/ui/base/ThemeManager.kt index 4eef05baf5..87d3a32229 100644 --- a/app/ui/base/src/main/java/com/fsck/k9/ui/base/ThemeManager.kt +++ b/app/ui/base/src/main/java/com/fsck/k9/ui/base/ThemeManager.kt @@ -21,7 +21,7 @@ class ThemeManager( private val context: Context, private val themeProvider: ThemeProvider, private val generalSettingsManager: GeneralSettingsManager, - private val appCoroutineScope: CoroutineScope, + private val appCoroutineScope: CoroutineScope ) { private val generalSettings: GeneralSettings diff --git a/app/ui/base/src/main/java/com/fsck/k9/ui/base/extensions/TextInputLayoutExtensions.kt b/app/ui/base/src/main/java/com/fsck/k9/ui/base/extensions/TextInputLayoutExtensions.kt index ca4f4305b3..a5d6577c31 100644 --- a/app/ui/base/src/main/java/com/fsck/k9/ui/base/extensions/TextInputLayoutExtensions.kt +++ b/app/ui/base/src/main/java/com/fsck/k9/ui/base/extensions/TextInputLayoutExtensions.kt @@ -32,7 +32,7 @@ fun TextInputLayout.configureAuthenticatedPasswordToggle( activity: FragmentActivity, title: String, subtitle: String, - needScreenLockMessage: String, + needScreenLockMessage: String ) { val viewModel = ViewModelProvider(activity).get() viewModel.textInputLayout = this diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/FolderInfoHolder.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/FolderInfoHolder.kt index 1442065b80..4ccc496e7f 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/FolderInfoHolder.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/FolderInfoHolder.kt @@ -12,8 +12,11 @@ class FolderInfoHolder( account: Account ) { @JvmField val databaseId = localFolder.databaseId + @JvmField val displayName = getDisplayName(account, localFolder) + @JvmField var loading = false + @JvmField var moreMessages = localFolder.hasMoreMessages() private fun getDisplayName(account: Account, localFolder: LocalFolder): String { diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt index f8a1b5b2af..a806a996b0 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt @@ -274,7 +274,9 @@ open class MessageList : if (!hasMessageListFragment) { val fragmentTransaction = fragmentManager.beginTransaction() val messageListFragment = MessageListFragment.newInstance( - search!!, false, K9.isThreadedViewEnabled && !noThreading + search!!, + false, + K9.isThreadedViewEnabled && !noThreading ) fragmentTransaction.add(R.id.message_list_container, messageListFragment) fragmentTransaction.commitNow() diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageListActivityConfig.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageListActivityConfig.kt index ba099bca56..0e33ac5442 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageListActivityConfig.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageListActivityConfig.kt @@ -32,7 +32,7 @@ data class MessageListActivityConfig( val fontSizeMessageViewDate: Int, val fontSizeMessageViewContentAsPercent: Int, val swipeRightAction: SwipeAction, - val swipeLeftAction: SwipeAction, + val swipeLeftAction: SwipeAction ) { companion object { @@ -64,7 +64,7 @@ data class MessageListActivityConfig( fontSizeMessageViewDate = K9.fontSizes.messageViewDate, fontSizeMessageViewContentAsPercent = K9.fontSizes.messageViewContentAsPercent, swipeRightAction = K9.swipeRightAction, - swipeLeftAction = K9.swipeLeftAction, + swipeLeftAction = K9.swipeLeftAction ) } } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.kt index f847caeac7..813337fdd7 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.kt @@ -580,7 +580,8 @@ class RecipientPresenter( if (currentCryptoMode == CryptoMode.NO_CHOICE) { if (currentCryptoStatus.hasAutocryptPendingIntent()) { recipientMvpView.launchUserInteractionPendingIntent( - currentCryptoStatus.autocryptPendingIntent, REQUEST_CODE_AUTOCRYPT + currentCryptoStatus.autocryptPendingIntent, + REQUEST_CODE_AUTOCRYPT ) } else if (isEncryptOnNoChoice) { // TODO warning dialog if we override, especially from reply! diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/contacts/ContactLetterBitmapCreator.kt b/app/ui/legacy/src/main/java/com/fsck/k9/contacts/ContactLetterBitmapCreator.kt index 935bdf01c9..eab56cc7fd 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/contacts/ContactLetterBitmapCreator.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/contacts/ContactLetterBitmapCreator.kt @@ -35,7 +35,8 @@ class ContactLetterBitmapCreator( canvas.drawText( letter, pictureSizeInPx / 2f - width / 2f, - pictureSizeInPx / 2f + rect.height() / 2f, paint + pictureSizeInPx / 2f + rect.height() / 2f, + paint ) return bitmap diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/K9Drawer.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/K9Drawer.kt index 33ea62825a..f2a66eeee7 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/K9Drawer.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/K9Drawer.kt @@ -313,7 +313,10 @@ class K9Drawer(private val parent: MessageList, savedInstanceState: Bundle?) : K swipeRefreshLayout.setOnRefreshListener { val accountToRefresh = if (headerView.selectionListShown) null else account messagingController.checkMail( - accountToRefresh, true, true, true, + accountToRefresh, + true, + true, + true, object : SimpleMessagingListener() { override fun checkMailFinished(context: Context?, account: Account?) { swipeRefreshLayout.post { diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountImageModelLoader.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountImageModelLoader.kt index 4bc81b4910..2b52817b19 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountImageModelLoader.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountImageModelLoader.kt @@ -18,7 +18,7 @@ import java.security.MessageDigest */ internal class AccountImageModelLoader( private val contactPhotoLoader: ContactPhotoLoader, - private val accountFallbackImageProvider: AccountFallbackImageProvider, + private val accountFallbackImageProvider: AccountFallbackImageProvider ) : ModelLoader { override fun buildLoadData( accountImage: AccountImage, diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/helper/ContextExtensions.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/helper/ContextExtensions.kt index 08b8115fe2..4d439fa656 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/helper/ContextExtensions.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/helper/ContextExtensions.kt @@ -1,4 +1,5 @@ @file:JvmName("ContextHelper") + package com.fsck.k9.ui.helper import android.app.Activity diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt index efc851840c..4b6b914e91 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt @@ -1156,7 +1156,8 @@ class MessageListFragment : operation == FolderOperation.COPY && !messagingController.isCopyCapable(message) ) { val toast = Toast.makeText( - activity, R.string.move_copy_cannot_copy_unsynced_message, + activity, + R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG ) toast.show() @@ -2064,7 +2065,7 @@ class MessageListFragment : arguments = bundleOf( ARG_SEARCH to search, ARG_IS_THREAD_DISPLAY to isThreadDisplay, - ARG_THREADED_LIST to threadedList, + ARG_THREADED_LIST to threadedList ) } } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt index b1d70c222c..3600125e3d 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.kt @@ -338,7 +338,9 @@ class MessageViewFragment : hideKeyboard() val handledByCryptoPresenter = messageCryptoPresenter.maybeHandleShowMessage( - messageTopView, account, messageViewInfo + messageTopView, + account, + messageViewInfo ) if (!handledByCryptoPresenter) { @@ -673,8 +675,11 @@ class MessageViewFragment : val confirmText = getString(R.string.dialog_confirm_delete_confirm_button) val cancelText = getString(R.string.dialog_confirm_delete_cancel_button) ConfirmationDialogFragment.newInstance( - dialogId, title, message, - confirmText, cancelText + dialogId, + title, + message, + confirmText, + cancelText ) } R.id.dialog_confirm_spam -> { @@ -683,8 +688,11 @@ class MessageViewFragment : val confirmText = getString(R.string.dialog_confirm_spam_confirm_button) val cancelText = getString(R.string.dialog_confirm_spam_cancel_button) ConfirmationDialogFragment.newInstance( - dialogId, title, message, - confirmText, cancelText + dialogId, + title, + message, + confirmText, + cancelText ) } R.id.dialog_attachment_progress -> { @@ -827,7 +835,12 @@ class MessageViewFragment : val maskedRequestCode = requestCode or REQUEST_MASK_CRYPTO_PRESENTER requireActivity().startIntentSenderForResult( - intentSender, maskedRequestCode, fillIntent, flagsMask, flagValues, extraFlags + intentSender, + maskedRequestCode, + fillIntent, + flagsMask, + flagValues, + extraFlags ) } @@ -917,7 +930,12 @@ class MessageViewFragment : try { val maskedRequestCode = requestCode or REQUEST_MASK_LOADER_HELPER requireActivity().startIntentSenderForResult( - intentSender, maskedRequestCode, fillIntent, flagsMask, flagValues, extraFlags + intentSender, + maskedRequestCode, + fillIntent, + flagsMask, + flagValues, + extraFlags ) } catch (e: SendIntentException) { Timber.e(e, "Irrecoverable error calling PendingIntent!") diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/RecipientNamesView.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/RecipientNamesView.kt index c1c1c89a02..9c8eb53ccf 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/RecipientNamesView.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/RecipientNamesView.kt @@ -75,7 +75,11 @@ class RecipientNamesView(context: Context, attrs: AttributeSet?) : ViewGroup(con if (isInEditMode) { recipientNames = listOf( - "Grace Hopper", "Katherine Johnson", "Margaret Hamilton", "Adele Goldberg", "Steve Shirley" + "Grace Hopper", + "Katherine Johnson", + "Margaret Hamilton", + "Adele Goldberg", + "Steve Shirley" ) numberOfRecipients = 8 } @@ -116,7 +120,9 @@ class RecipientNamesView(context: Context, attrs: AttributeSet?) : ViewGroup(con val availableWidth = width val recipientLayoutData = recipientLayoutCreator.createRecipientLayout( - recipientNames, numberOfRecipients, availableWidth + recipientNames, + numberOfRecipients, + availableWidth ) recipientNameTextView.text = recipientLayoutData.recipientNames diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/SettingsViewModel.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/SettingsViewModel.kt index 5036cd72a7..bd87290d6e 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/SettingsViewModel.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/SettingsViewModel.kt @@ -14,7 +14,7 @@ import kotlinx.coroutines.launch internal class SettingsViewModel( private val accountManager: AccountManager, private val coroutineScope: CoroutineScope = GlobalScope, - private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO, + private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO ) : ViewModel() { val accounts = accountManager.getAccountsFlow().asLiveData() diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt index 9672c89366..31551ec120 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt @@ -280,7 +280,7 @@ class AccountSettingsDataStore( vibration = NotificationVibration( isEnabled = isVibrationEnabled, pattern = vibrationPattern, - repeatCount = vibrationTimes, + repeatCount = vibrationTimes ) ) } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AutocryptPreferEncryptPreference.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AutocryptPreferEncryptPreference.kt index ab7f345cf2..c14928dae4 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AutocryptPreferEncryptPreference.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AutocryptPreferEncryptPreference.kt @@ -17,7 +17,8 @@ constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = TypedArrayUtils.getAttr( - context, androidx.preference.R.attr.preferenceStyle, + context, + androidx.preference.R.attr.preferenceStyle, android.R.attr.preferenceStyle ), defStyleRes: Int = 0 @@ -48,7 +49,8 @@ constructor( companion object { init { PreferenceFragmentCompat.registerPreferenceFragment( - AutocryptPreferEncryptPreference::class.java, AutocryptPreferEncryptDialogFragment::class.java + AutocryptPreferEncryptPreference::class.java, + AutocryptPreferEncryptDialogFragment::class.java ) } } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/FolderListPreference.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/FolderListPreference.kt index 8f6677ac5c..24a3a70eb1 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/FolderListPreference.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/FolderListPreference.kt @@ -25,7 +25,8 @@ constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = TypedArrayUtils.getAttr( - context, androidx.preference.R.attr.dialogPreferenceStyle, + context, + androidx.preference.R.attr.dialogPreferenceStyle, android.R.attr.dialogPreferenceStyle ), defStyleRes: Int = 0 diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/NotificationsPreference.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/NotificationsPreference.kt index 4322a6051a..9361ab1f2e 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/NotificationsPreference.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/NotificationsPreference.kt @@ -23,7 +23,8 @@ constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = TypedArrayUtils.getAttr( - context, androidx.preference.R.attr.preferenceStyle, + context, + androidx.preference.R.attr.preferenceStyle, android.R.attr.preferenceStyle ), defStyleRes: Int = 0 @@ -49,7 +50,8 @@ constructor( companion object { init { PreferenceFragmentCompat.registerPreferenceFragment( - NotificationsPreference::class.java, DialogFragment::class.java + NotificationsPreference::class.java, + DialogFragment::class.java ) } } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationPreference.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationPreference.kt index d8ea240f18..8784906cfb 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationPreference.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationPreference.kt @@ -75,7 +75,8 @@ constructor( init { PreferenceFragmentCompat.registerPreferenceFragment( - VibrationPreference::class.java, VibrationDialogFragment::class.java + VibrationPreference::class.java, + VibrationDialogFragment::class.java ) } diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/AttachmentPresenterTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/AttachmentPresenterTest.kt index 6a1f04a0c5..e67ec906ce 100644 --- a/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/AttachmentPresenterTest.kt +++ b/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/AttachmentPresenterTest.kt @@ -47,7 +47,10 @@ class AttachmentPresenterTest : K9RobolectricTest() { @Before fun setUp() { attachmentPresenter = AttachmentPresenter( - ApplicationProvider.getApplicationContext(), attachmentMvpView, loaderManager, listener + ApplicationProvider.getApplicationContext(), + attachmentMvpView, + loaderManager, + listener ) } @@ -57,8 +60,13 @@ class AttachmentPresenterTest : K9RobolectricTest() { val message = MimeMessage() MimeMessageHelper.setBody(message, TextBody(TEXT)) val attachmentViewInfo = AttachmentViewInfo( - MIME_TYPE, ATTACHMENT_NAME, size, URI, false, - LocalBodyPart(ACCOUNT_UUID, mock(), MESSAGE_ID, size), true + MIME_TYPE, + ATTACHMENT_NAME, + size, + URI, + false, + LocalBodyPart(ACCOUNT_UUID, mock(), MESSAGE_ID, size), + true ) val messageViewInfo = MessageViewInfo( message, false, message, SUBJECT, false, TEXT, listOf(attachmentViewInfo), null, attachmentResolver, @@ -85,8 +93,13 @@ class AttachmentPresenterTest : K9RobolectricTest() { val message = MimeMessage() MimeMessageHelper.setBody(message, TextBody(TEXT)) val attachmentViewInfo = AttachmentViewInfo( - MIME_TYPE, ATTACHMENT_NAME, size, URI, false, - LocalBodyPart(ACCOUNT_UUID, mock(), MESSAGE_ID, size), false + MIME_TYPE, + ATTACHMENT_NAME, + size, + URI, + false, + LocalBodyPart(ACCOUNT_UUID, mock(), MESSAGE_ID, size), + false ) val messageViewInfo = MessageViewInfo( message, false, message, SUBJECT, false, TEXT, listOf(attachmentViewInfo), null, attachmentResolver, diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/RecipientPresenterTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/RecipientPresenterTest.kt index 853170cba7..6d15ffb5dd 100644 --- a/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/RecipientPresenterTest.kt +++ b/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/RecipientPresenterTest.kt @@ -155,7 +155,8 @@ class RecipientPresenterTest : K9RobolectricTest() { @Test fun getCurrentCryptoStatus_withOpportunistic() { val recipientAutocryptStatus = RecipientAutocryptStatus( - RecipientAutocryptStatusType.AVAILABLE_UNCONFIRMED, null + RecipientAutocryptStatusType.AVAILABLE_UNCONFIRMED, + null ) setupCryptoProvider(recipientAutocryptStatus) @@ -170,7 +171,8 @@ class RecipientPresenterTest : K9RobolectricTest() { @Test fun getCurrentCryptoStatus_withOpportunistic__confirmed() { val recipientAutocryptStatus = RecipientAutocryptStatus( - RecipientAutocryptStatusType.AVAILABLE_CONFIRMED, null + RecipientAutocryptStatusType.AVAILABLE_CONFIRMED, + null ) setupCryptoProvider(recipientAutocryptStatus) @@ -185,7 +187,8 @@ class RecipientPresenterTest : K9RobolectricTest() { @Test fun getCurrentCryptoStatus_withOpportunistic__missingKeys() { val recipientAutocryptStatus = RecipientAutocryptStatus( - RecipientAutocryptStatusType.UNAVAILABLE, null + RecipientAutocryptStatusType.UNAVAILABLE, + null ) setupCryptoProvider(recipientAutocryptStatus) @@ -200,7 +203,8 @@ class RecipientPresenterTest : K9RobolectricTest() { @Test fun getCurrentCryptoStatus_withOpportunistic__privateMissingKeys() { val recipientAutocryptStatus = RecipientAutocryptStatus( - RecipientAutocryptStatusType.UNAVAILABLE, null + RecipientAutocryptStatusType.UNAVAILABLE, + null ) setupCryptoProvider(recipientAutocryptStatus) @@ -217,7 +221,8 @@ class RecipientPresenterTest : K9RobolectricTest() { @Test fun getCurrentCryptoStatus_withModeDisabled() { val recipientAutocryptStatus = RecipientAutocryptStatus( - RecipientAutocryptStatusType.AVAILABLE_UNCONFIRMED, null + RecipientAutocryptStatusType.AVAILABLE_UNCONFIRMED, + null ) setupCryptoProvider(recipientAutocryptStatus) @@ -234,7 +239,8 @@ class RecipientPresenterTest : K9RobolectricTest() { @Test fun getCurrentCryptoStatus_withModePrivate() { val recipientAutocryptStatus = RecipientAutocryptStatus( - RecipientAutocryptStatusType.AVAILABLE_UNCONFIRMED, null + RecipientAutocryptStatusType.AVAILABLE_UNCONFIRMED, + null ) setupCryptoProvider(recipientAutocryptStatus) diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt index a2c91597ee..a37f1db7ff 100644 --- a/app/ui/legacy/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt +++ b/app/ui/legacy/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.kt @@ -192,7 +192,8 @@ class PgpMessageBuilderTest : K9RobolectricTest() { `when`( openPgpApi.executeApi( capturedApiIntent.capture(), - any(), anyOrNull() + any(), + anyOrNull() ) ).thenReturn(returnIntent) @@ -217,7 +218,8 @@ class PgpMessageBuilderTest : K9RobolectricTest() { val contentBodyPart = multipart.getBodyPart(0) Assert.assertEquals( "first part must have content type text/plain", - "text/plain", MimeUtility.getHeaderParameter(contentBodyPart.contentType, null) + "text/plain", + MimeUtility.getHeaderParameter(contentBodyPart.contentType, null) ) assertTrue("signed message body must be TextBody", contentBodyPart.body is TextBody) Assert.assertEquals(MimeUtil.ENC_QUOTED_PRINTABLE, (contentBodyPart.body as TextBody).encoding) @@ -226,16 +228,19 @@ class PgpMessageBuilderTest : K9RobolectricTest() { val signatureBodyPart = multipart.getBodyPart(1) val contentType = signatureBodyPart.contentType Assert.assertEquals( - "second part must be pgp signature", "application/pgp-signature", + "second part must be pgp signature", + "application/pgp-signature", MimeUtility.getHeaderParameter(contentType, null) ) Assert.assertEquals( - "second part must be called signature.asc", "signature.asc", + "second part must be called signature.asc", + "signature.asc", MimeUtility.getHeaderParameter(contentType, "name") ) assertContentOfBodyPartEquals( "content must match the supplied detached signature", - signatureBodyPart, byteArrayOf(1, 2, 3) + signatureBodyPart, + byteArrayOf(1, 2, 3) ) assertMessageHasAutocryptHeader(message, SENDER_EMAIL, false, AUTOCRYPT_KEY_MATERIAL) @@ -483,7 +488,8 @@ class PgpMessageBuilderTest : K9RobolectricTest() { `when`( openPgpApi.executeApi( - capturedApiIntent.capture(), any(OpenPgpDataSource::class.java), + capturedApiIntent.capture(), + any(OpenPgpDataSource::class.java), any(OutputStream::class.java) ) ).thenReturn(returnIntent) @@ -512,17 +518,20 @@ class PgpMessageBuilderTest : K9RobolectricTest() { val dummyBodyPart = multipart.getBodyPart(0) Assert.assertEquals( "first part must be pgp encrypted dummy part", - "application/pgp-encrypted", dummyBodyPart.contentType + "application/pgp-encrypted", + dummyBodyPart.contentType ) assertContentOfBodyPartEquals( "content must match the supplied detached signature", - dummyBodyPart, "Version: 1" + dummyBodyPart, + "Version: 1" ) val encryptedBodyPart = multipart.getBodyPart(1) Assert.assertEquals( "second part must be octet-stream of encrypted data", - "application/octet-stream; name=\"encrypted.asc\"", encryptedBodyPart.contentType + "application/octet-stream; name=\"encrypted.asc\"", + encryptedBodyPart.contentType ) assertTrue( "message body must be BinaryTempFileBody", @@ -550,7 +559,8 @@ class PgpMessageBuilderTest : K9RobolectricTest() { `when`( openPgpApi.executeApi( - capturedApiIntent.capture(), any(OpenPgpDataSource::class.java), + capturedApiIntent.capture(), + any(OpenPgpDataSource::class.java), any(OutputStream::class.java) ) ).thenReturn(returnIntent) @@ -595,7 +605,8 @@ class PgpMessageBuilderTest : K9RobolectricTest() { `when`( openPgpApi.executeApi( - capturedApiIntent.capture(), any(OpenPgpDataSource::class.java), + capturedApiIntent.capture(), + any(OpenPgpDataSource::class.java), any(OutputStream::class.java) ) ).thenReturn(returnIntent) @@ -707,8 +718,11 @@ class PgpMessageBuilderTest : K9RobolectricTest() { resourceProvider: CoreResourceProvider ): PgpMessageBuilder { val builder = PgpMessageBuilder( - MessageIdGenerator.getInstance(), BoundaryGenerator.getInstance(), - AutocryptOperations.getInstance(), autocryptOpenPgpApiInteractor, resourceProvider + MessageIdGenerator.getInstance(), + BoundaryGenerator.getInstance(), + AutocryptOperations.getInstance(), + autocryptOpenPgpApiInteractor, + resourceProvider ) builder.setOpenPgpApi(openPgpApi) diff --git a/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListItem.kt b/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListItem.kt index 19c266df10..230fe6cf07 100644 --- a/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListItem.kt +++ b/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListItem.kt @@ -18,5 +18,5 @@ internal data class MessageListItem( val sortMessageDate: Long, val sortInternalDate: Long, val sortIsStarred: Boolean, - val sortDatabaseId: Long, + val sortDatabaseId: Long ) diff --git a/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListItemMapper.kt b/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListItemMapper.kt index e0f7653590..bac2745fbd 100644 --- a/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListItemMapper.kt +++ b/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListItemMapper.kt @@ -44,7 +44,7 @@ internal class MessageListItemMapper( sortMessageDate = message.messageDate, sortInternalDate = message.internalDate, sortIsStarred = message.isStarred, - sortDatabaseId = message.id, + sortDatabaseId = message.id ) } diff --git a/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListWidgetManager.kt b/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListWidgetManager.kt index 6eab9f1d38..e503d1ce58 100644 --- a/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListWidgetManager.kt +++ b/app/ui/message-list-widget/src/main/java/app/k9mail/ui/widget/list/MessageListWidgetManager.kt @@ -12,7 +12,7 @@ import timber.log.Timber class MessageListWidgetManager( private val context: Context, private val messageListRepository: MessageListRepository, - private val config: MessageListWidgetConfig, + private val config: MessageListWidgetConfig ) { private lateinit var appWidgetManager: AppWidgetManager diff --git a/backend/imap/src/main/java/com/fsck/k9/backend/imap/CommandMoveOrCopyMessages.kt b/backend/imap/src/main/java/com/fsck/k9/backend/imap/CommandMoveOrCopyMessages.kt index c3b92903aa..b834f9a3b3 100644 --- a/backend/imap/src/main/java/com/fsck/k9/backend/imap/CommandMoveOrCopyMessages.kt +++ b/backend/imap/src/main/java/com/fsck/k9/backend/imap/CommandMoveOrCopyMessages.kt @@ -48,7 +48,8 @@ internal class CommandMoveOrCopyMessages(private val imapStore: ImapStore) { remoteSrcFolder.open(OpenMode.READ_WRITE) if (remoteSrcFolder.mode != OpenMode.READ_WRITE) { throw MessagingException( - "moveOrCopyMessages: could not open remoteSrcFolder $srcFolder read/write", true + "moveOrCopyMessages: could not open remoteSrcFolder $srcFolder read/write", + true ) } @@ -56,7 +57,10 @@ internal class CommandMoveOrCopyMessages(private val imapStore: ImapStore) { Timber.d( "moveOrCopyMessages: source folder = %s, %d messages, destination folder = %s, isCopy = %s", - srcFolder, messages.size, destFolder, isCopy + srcFolder, + messages.size, + destFolder, + isCopy ) remoteDestFolder = imapStore.getFolder(destFolder) diff --git a/backend/imap/src/main/java/com/fsck/k9/backend/imap/ImapSync.kt b/backend/imap/src/main/java/com/fsck/k9/backend/imap/ImapSync.kt index 66d703092f..f5276a9006 100644 --- a/backend/imap/src/main/java/com/fsck/k9/backend/imap/ImapSync.kt +++ b/backend/imap/src/main/java/com/fsck/k9/backend/imap/ImapSync.kt @@ -131,7 +131,9 @@ internal class ImapSync( Timber.v( "SYNC: About to get messages %d through %d for folder %s", - remoteStart, remoteMessageCount, folder + remoteStart, + remoteMessageCount, + folder ) val headerProgress = AtomicInteger(0) @@ -235,7 +237,9 @@ internal class ImapSync( listener.syncFailed(folder, rootMessage, e) Timber.e( - "Failed synchronizing folder %s:%s @ %tc", accountName, folder, + "Failed synchronizing folder %s:%s @ %tc", + accountName, + folder, System.currentTimeMillis() ) } finally { @@ -337,7 +341,9 @@ internal class ImapSync( Timber.d( "SYNC: Have %d large messages and %d small messages out of %d unsynced messages", - largeMessages.size, smallMessages.size, unsyncedMessages.size + largeMessages.size, + smallMessages.size, + unsyncedMessages.size ) unsyncedMessages.clear() @@ -458,7 +464,9 @@ internal class ImapSync( if (message.isSet(Flag.DELETED)) { Timber.v( "Newly downloaded message %s:%s:%s was marked deleted on server, skipping", - accountName, folder, message.uid + accountName, + folder, + message.uid ) if (isFirstResponse) { @@ -521,7 +529,9 @@ internal class ImapSync( val messageServerId = message.uid Timber.v( "About to notify listeners that we got a new small message %s:%s:%s", - accountName, folder, messageServerId + accountName, + folder, + messageServerId ) // Update the listener with what we've found @@ -569,7 +579,9 @@ internal class ImapSync( val messageServerId = message.uid Timber.v( "About to notify listeners that we got a new large message %s:%s:%s", - accountName, folder, messageServerId + accountName, + folder, + messageServerId ) // Update the listener with what we've found diff --git a/mail/common/src/main/java/com/fsck/k9/mail/internet/MimeParameterDecoder.kt b/mail/common/src/main/java/com/fsck/k9/mail/internet/MimeParameterDecoder.kt index 5f4fc4d446..ebe89d3b9d 100644 --- a/mail/common/src/main/java/com/fsck/k9/mail/internet/MimeParameterDecoder.kt +++ b/mail/common/src/main/java/com/fsck/k9/mail/internet/MimeParameterDecoder.kt @@ -218,7 +218,12 @@ object MimeParameterDecoder { parser.readExtendedParameterValueInto(data) InitialExtendedValueParameterSection( - newParameterName, parameterName, section, charsetName, language, data + newParameterName, + parameterName, + section, + charsetName, + language, + data ) } else { val encodedParameterText = parameterText.substring(parser.position()) diff --git a/mail/common/src/main/java/com/fsck/k9/mail/internet/PartExtensions.kt b/mail/common/src/main/java/com/fsck/k9/mail/internet/PartExtensions.kt index a91d7db833..dbae2e262e 100644 --- a/mail/common/src/main/java/com/fsck/k9/mail/internet/PartExtensions.kt +++ b/mail/common/src/main/java/com/fsck/k9/mail/internet/PartExtensions.kt @@ -1,4 +1,5 @@ @file:JvmName("PartExtensions") + package com.fsck.k9.mail.internet import com.fsck.k9.mail.Part diff --git a/mail/common/src/main/java/com/fsck/k9/sasl/OAuthBearer.kt b/mail/common/src/main/java/com/fsck/k9/sasl/OAuthBearer.kt index 7ad04e03c4..531e5b683d 100644 --- a/mail/common/src/main/java/com/fsck/k9/sasl/OAuthBearer.kt +++ b/mail/common/src/main/java/com/fsck/k9/sasl/OAuthBearer.kt @@ -1,4 +1,5 @@ @file:JvmName("OAuthBearer") + package com.fsck.k9.sasl import okio.ByteString.Companion.encodeUtf8 diff --git a/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapConnection.kt b/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapConnection.kt index b27bc038a9..b4d28facc5 100644 --- a/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapConnection.kt +++ b/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapConnection.kt @@ -710,7 +710,10 @@ internal class RealImapConnection( ): List { val groupedIds = IdGrouper.groupIds(ids) val splitCommands = ImapCommandSplitter.splitCommand( - commandPrefix, commandSuffix, groupedIds, lineLengthLimit + commandPrefix, + commandSuffix, + groupedIds, + lineLengthLimit ) return splitCommands.flatMap { splitCommand -> @@ -831,7 +834,9 @@ internal class RealImapConnection( } else { Timber.w( "After sending tag %s, got tag response from previous command %s for %s", - tag, response, logId + tag, + response, + logId ) } } diff --git a/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapFolder.kt b/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapFolder.kt index 472c054a1b..46e132efb5 100644 --- a/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapFolder.kt +++ b/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/RealImapFolder.kt @@ -292,7 +292,8 @@ internal class RealImapFolder( if (K9MailLib.isDebug()) { Timber.i( "ImapFolder.copyMessages: couldn't find remote folder '%s' for %s", - escapedDestinationFolderName, logId + escapedDestinationFolderName, + logId ) } @@ -399,7 +400,8 @@ internal class RealImapFolder( val dateSearchString = getDateSearchString(earliestDate) val command = String.format( - Locale.US, "UID SEARCH %d:%d%s%s", + Locale.US, + "UID SEARCH %d:%d%s%s", start, end, dateSearchString, @@ -448,8 +450,11 @@ internal class RealImapFolder( @Throws(MessagingException::class, IOException::class) private fun existsNonDeletedMessageInRange(startIndex: Int, endIndex: Int, dateSearchString: String): Boolean { val command = String.format( - Locale.US, "SEARCH %d:%d%s NOT DELETED", - startIndex, endIndex, dateSearchString + Locale.US, + "SEARCH %d:%d%s NOT DELETED", + startIndex, + endIndex, + dateSearchString ) val imapResponses = executeSimpleCommand(command) @@ -969,8 +974,11 @@ internal class RealImapFolder( canCreateKeywords || internalImapStore.getPermanentFlagsIndex().contains(Flag.FORWARDED) ) val command = String.format( - Locale.US, "APPEND %s (%s) {%d}", - escapedFolderName, combinedFlags, messageSize + Locale.US, + "APPEND %s (%s) {%d}", + escapedFolderName, + combinedFlags, + messageSize ) connection!!.sendCommand(command, false) diff --git a/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/UidValidityResponse.kt b/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/UidValidityResponse.kt index 9652b5ba60..5a84abda0e 100644 --- a/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/UidValidityResponse.kt +++ b/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/UidValidityResponse.kt @@ -11,7 +11,9 @@ internal class UidValidityResponse private constructor(val uidValidity: Long) { val responseTextList = response.getList(1) if (responseTextList.size < 2 || !equalsIgnoreCase(responseTextList[0], Responses.UIDVALIDITY) || !responseTextList.isLong(1) - ) return null + ) { + return null + } val uidValidity = responseTextList.getLong(1) if (uidValidity !in 0L..0xFFFFFFFFL) return null diff --git a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapConnectionTest.kt b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapConnectionTest.kt index 570e3f2990..d6a6eb2931 100644 --- a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapConnectionTest.kt +++ b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapConnectionTest.kt @@ -697,7 +697,7 @@ class RealImapConnectionTest { } val imapConnection = startServerAndCreateImapConnection( server, - connectionSecurity = ConnectionSecurity.STARTTLS_REQUIRED, + connectionSecurity = ConnectionSecurity.STARTTLS_REQUIRED ) try { diff --git a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapFolderTest.kt b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapFolderTest.kt index ff3e5b6dfd..9289e7e706 100644 --- a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapFolderTest.kt +++ b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapFolderTest.kt @@ -1171,7 +1171,9 @@ class RealImapFolderTest { val commandSuffixCaptor = argumentCaptor() val commandUidsCaptor = argumentCaptor>() verify(imapConnection, atLeastOnce()).executeCommandWithIdSet( - commandPrefixCaptor.capture(), commandSuffixCaptor.capture(), commandUidsCaptor.capture() + commandPrefixCaptor.capture(), + commandSuffixCaptor.capture(), + commandUidsCaptor.capture() ) val commandPrefixes = commandPrefixCaptor.allValues diff --git a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapStoreTest.kt b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapStoreTest.kt index 113b42f209..e03414d513 100644 --- a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapStoreTest.kt +++ b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/RealImapStoreTest.kt @@ -413,7 +413,10 @@ class RealImapStoreTest { trustedSocketFactory: TrustedSocketFactory, oauth2TokenProvider: OAuth2TokenProvider? ) : RealImapStore( - serverSettings, config, trustedSocketFactory, oauth2TokenProvider + serverSettings, + config, + trustedSocketFactory, + oauth2TokenProvider ) { private val imapConnections: Deque = ArrayDeque() private var testCombinedPrefix: String? = null diff --git a/mail/protocols/smtp/src/main/java/com/fsck/k9/mail/transport/smtp/SmtpTransport.kt b/mail/protocols/smtp/src/main/java/com/fsck/k9/mail/transport/smtp/SmtpTransport.kt index 773e515e30..790fb569cc 100644 --- a/mail/protocols/smtp/src/main/java/com/fsck/k9/mail/transport/smtp/SmtpTransport.kt +++ b/mail/protocols/smtp/src/main/java/com/fsck/k9/mail/transport/smtp/SmtpTransport.kt @@ -414,7 +414,8 @@ class SmtpTransport( val msgOut = EOLConvertingOutputStream( LineWrapOutputStream( - SmtpDataStuffing(outputStream), 1000 + SmtpDataStuffing(outputStream), + 1000 ) ) -- GitLab From 71ba065d765fda280a9570284aa9acf6754a7551 Mon Sep 17 00:00:00 2001 From: Wolf Montwe Date: Fri, 3 Feb 2023 17:25:07 +0100 Subject: [PATCH 005/317] Add Markdown format rules --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 23eeb67bd4..136a83eacc 100644 --- a/build.gradle +++ b/build.gradle @@ -105,6 +105,12 @@ spotless { trimTrailingWhitespace() endWithNewline() } + format("markdown") { + prettier() + target("**/*.md") + trimTrailingWhitespace() + endWithNewline() + } } tasks.register('testsOnCi') { -- GitLab From 0bf2b31d8553c2d6748461ed48e07bc538e66f69 Mon Sep 17 00:00:00 2001 From: Wolf Montwe Date: Fri, 3 Feb 2023 17:28:34 +0100 Subject: [PATCH 006/317] Change format of Markdown files --- .github/CONTRIBUTING.md | 16 +++--- .github/pull_request_template.md | 16 +++--- README.md | 11 +--- cli/html-cleaner-cli/README.md | 2 +- docs/DESIGN.md | 2 +- plugins/openpgp-api-lib/CHANGELOG.md | 70 +++++++++++++----------- plugins/openpgp-api-lib/README.md | 79 ++++++++++++++++------------ 7 files changed, 102 insertions(+), 94 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 143e5414ce..130810bbd9 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -3,23 +3,21 @@ If the app is not behaving like it should, it's not necessarily a bug. Please consult the following resources before submitting a new issue. -* [User Manual](https://docs.k9mail.app/) -* [Frequently Asked Questions](https://forum.k9mail.app/c/faq) -* [Support Forum](https://forum.k9mail.app/) +- [User Manual](https://docs.k9mail.app/) +- [Frequently Asked Questions](https://forum.k9mail.app/c/faq) +- [Support Forum](https://forum.k9mail.app/) ### Bug report guidelines -* The issue tracker is solely for bug reports and feature/enhancement requests. If you have a question of any kind, -please use the [support forum](https://forum.k9mail.app/c/support) instead. -* Search the [existing issues](https://github.com/thundernest/k-9/issues?q=) first to make sure your issue hasn't been -reported before. - +- The issue tracker is solely for bug reports and feature/enhancement requests. If you have a question of any kind, + please use the [support forum](https://forum.k9mail.app/c/support) instead. +- Search the [existing issues](https://github.com/thundernest/k-9/issues?q=) first to make sure your issue hasn't been + reported before. ## Translations We're using [Transifex](https://www.transifex.com/k-9/k9mail/) to manage translations. - ## Contributing code We love [pull requests](https://github.com/thundernest/k-9/pulls) from everyone! diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4bd7a7ac85..6b2d7e0587 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,12 +1,12 @@ Please ensure that your pull request meets the following requirements - thanks! -* Does not contain merge commits. Rebase instead. -* Contains commits with descriptive titles. -* New code is written in Kotlin whenever possible. -* Follows our existing codestyle (`gradlew ktlintCheck`; will be checked by CI). -* Does not break any unit tests (`gradlew testDebugUnitTest`; will be checked by CI). -* Uses a descriptive title; don't put issue numbers in there. -* Contains a reference to the issue that it fixes (e.g. *Closes #XXX* or *Fixes #XXX*) in the body text. -* For cosmetic changes add one or multiple images, if possible. +- Does not contain merge commits. Rebase instead. +- Contains commits with descriptive titles. +- New code is written in Kotlin whenever possible. +- Follows our existing codestyle (`gradlew ktlintCheck`; will be checked by CI). +- Does not break any unit tests (`gradlew testDebugUnitTest`; will be checked by CI). +- Uses a descriptive title; don't put issue numbers in there. +- Contains a reference to the issue that it fixes (e.g. _Closes #XXX_ or _Fixes #XXX_) in the body text. +- For cosmetic changes add one or multiple images, if possible. Finally, please replace this template text with a description of the change and additional context if necessary. diff --git a/README.md b/README.md index 707cd6501f..9e6532e527 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # K-9 Mail + [![Latest release](https://img.shields.io/github/release/thundernest/k-9.svg?style=flat-square)](https://github.com/thundernest/k-9/releases/latest) [![Latest beta release](https://img.shields.io/github/v/release/thundernest/k-9.svg?include_prereleases&style=flat-square)](https://github.com/thundernest/k-9/releases) K-9 Mail is an open-source email client for Android. - ## Download K-9 Mail can be downloaded from a couple of sources: @@ -15,13 +15,11 @@ K-9 Mail can be downloaded from a couple of sources: You might also be interested in becoming a [tester](https://forum.k9mail.app/t/how-do-i-become-a-beta-tester/68) to get an early look at new versions. - ## Release Notes Check out the [Release Notes](https://github.com/thundernest/k-9/wiki/ReleaseNotes) to find out what changed in each version of K-9 Mail. - ## Need Help? If the app is not behaving like it should, you might find these resources helpful: @@ -30,18 +28,15 @@ If the app is not behaving like it should, you might find these resources helpfu - [Frequently Asked Questions](https://forum.k9mail.app/c/faq) - [Support Forum](https://forum.k9mail.app/) - ## Translations Interested in helping to translate K-9 Mail? Contribute here: https://www.transifex.com/projects/p/k9mail/ - ## Contributing -Thank you for contributing! If you're unfamiliar with the code, -start by reading the [developer documentation](docs/DESIGN.md) +Thank you for contributing! If you're unfamiliar with the code, start by reading the [developer documentation](docs/DESIGN.md) Please fork this repository and contribute back using [pull requests](https://github.com/thundernest/k-9/pulls). @@ -49,7 +44,6 @@ Any contributions, large or small, major features, bug fixes, unit/integration t but will be thoroughly reviewed and discussed. Please make sure you read the [Code Style Guidelines](https://github.com/thundernest/k-9/wiki/CodeStyle). - ## Communication Aside from discussing changes in [pull requests](https://github.com/thundernest/k-9/pulls) and @@ -59,7 +53,6 @@ Aside from discussing changes in [pull requests](https://github.com/thundernest/ - IRC: [#k9mail on Libera Chat](https://web.libera.chat/#k9mail) - [Developer mailing list](https://groups.google.com/forum/#!forum/k-9-dev) - ## License Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cli/html-cleaner-cli/README.md b/cli/html-cleaner-cli/README.md index 9bf6ab1b78..2b10cb31e8 100644 --- a/cli/html-cleaner-cli/README.md +++ b/cli/html-cleaner-cli/README.md @@ -12,6 +12,6 @@ Arguments: OUTPUT Output file ``` -You can run this tool using the [html-cleaner](../../html-cleaner) script in the root directory of this repository. +You can run this tool using the [html-cleaner](../../html-cleaner) script in the root directory of this repository. It will compile the application and then run it using the given arguments. This allows you to make modifications to the [HTML cleaning code](../../app/html-cleaner/src/main/java/app/k9mail/html/cleaner) and test the changes right away. diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 6b44c2db4c..f5445dc267 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -23,7 +23,7 @@ Additional, standalone, libraries used by K-9 # Walkthrough To help you understand the design, the following sequence diagrams show typical flows through the -classes. Each class is colour-coded by its top-level project. +classes. Each class is colour-coded by its top-level project. ## Reading email diff --git a/plugins/openpgp-api-lib/CHANGELOG.md b/plugins/openpgp-api-lib/CHANGELOG.md index 93b6824eac..24d48b88a6 100644 --- a/plugins/openpgp-api-lib/CHANGELOG.md +++ b/plugins/openpgp-api-lib/CHANGELOG.md @@ -1,48 +1,56 @@ # Version history ## Version 10 - * Retrieve whole public key via ACTION_GET_KEY + +- Retrieve whole public key via ACTION_GET_KEY ## Version 9 - * AIDL Service has been changed from IOpenPgpService.aidl to IOpenPgpService2.aidl - This fixes truncated data streams (thanks to 'mgeier63'). - * Fix for OpenPgpKeyPreference: Properly execute pending user interactions - * Charset moved to OpenPgpMetadata + +- AIDL Service has been changed from IOpenPgpService.aidl to IOpenPgpService2.aidl + This fixes truncated data streams (thanks to 'mgeier63'). +- Fix for OpenPgpKeyPreference: Properly execute pending user interactions +- Charset moved to OpenPgpMetadata ## Version 8 - * OpenPgpSignatureResult: - method getStatus() renamed to getResult() - constants have been renamed for clarity - new constants: RESULT_NO_SIGNATURE, RESULT_INVALID_INSECURE - isSignatureOnly() has been deprecated - * RESULT_TYPES have been removed - * new OpenPgpDecryptionResult returned via RESULT_DECRYPTION - * OpenPgpSignatureResult and OpenPgpDecryptionResult are never null, they are always returned. + +- OpenPgpSignatureResult: + method getStatus() renamed to getResult() + constants have been renamed for clarity + new constants: RESULT_NO_SIGNATURE, RESULT_INVALID_INSECURE + isSignatureOnly() has been deprecated +- RESULT_TYPES have been removed +- new OpenPgpDecryptionResult returned via RESULT_DECRYPTION +- OpenPgpSignatureResult and OpenPgpDecryptionResult are never null, they are always returned. ## Version 7 - * Deprecation of ACCOUNT_NAME, please use ACTION_GET_SIGN_KEY_ID to get key id - * Introduce EXTRA_SIGN_KEY_ID - * New extra for ACTION_ENCRYPT and ACTION_SIGN_AND_ENCRYPT: EXTRA_ENABLE_COMPRESSION (default to true) - * Return PendingIntent to view key for signatures - * New result for ACTION_DECRYPT_VERIFY: RESULT_TYPE - * New ACTION_GET_SIGN_KEY_ID - * EXTRA_PASSPHRASE changed from String to char[] + +- Deprecation of ACCOUNT_NAME, please use ACTION_GET_SIGN_KEY_ID to get key id +- Introduce EXTRA_SIGN_KEY_ID +- New extra for ACTION_ENCRYPT and ACTION_SIGN_AND_ENCRYPT: EXTRA_ENABLE_COMPRESSION (default to true) +- Return PendingIntent to view key for signatures +- New result for ACTION_DECRYPT_VERIFY: RESULT_TYPE +- New ACTION_GET_SIGN_KEY_ID +- EXTRA_PASSPHRASE changed from String to char[] ## Version 6 - * Deprecate ACTION_SIGN - * Introduce ACTION_CLEARTEXT_SIGN and ACTION_DETACHED_SIGN - * New extra for ACTION_DETACHED_SIGN: EXTRA_DETACHED_SIGNATURE - * New result for ACTION_DECRYPT_VERIFY: RESULT_DETACHED_SIGNATURE - * New result for ACTION_DECRYPT_VERIFY: RESULT_CHARSET + +- Deprecate ACTION_SIGN +- Introduce ACTION_CLEARTEXT_SIGN and ACTION_DETACHED_SIGN +- New extra for ACTION_DETACHED_SIGN: EXTRA_DETACHED_SIGNATURE +- New result for ACTION_DECRYPT_VERIFY: RESULT_DETACHED_SIGNATURE +- New result for ACTION_DECRYPT_VERIFY: RESULT_CHARSET ## Version 5 - * OpenPgpSignatureResult: new consts RESULT_INVALID_KEY_REVOKED and RESULT_INVALID_KEY_EXPIRED - * OpenPgpSignatureResult: ArrayList userIds + +- OpenPgpSignatureResult: new consts RESULT_INVALID_KEY_REVOKED and RESULT_INVALID_KEY_EXPIRED +- OpenPgpSignatureResult: ArrayList userIds ## Version 4 - * No changes to existing methods -> backward compatible - * Introduction of ACTION_DECRYPT_METADATA, RESULT_METADATA, EXTRA_ORIGINAL_FILENAME, and OpenPgpMetadata parcel - * Introduction of internal NFC extras: EXTRA_NFC_SIGNED_HASH, EXTRA_NFC_SIG_CREATION_TIMESTAMP + +- No changes to existing methods -> backward compatible +- Introduction of ACTION_DECRYPT_METADATA, RESULT_METADATA, EXTRA_ORIGINAL_FILENAME, and OpenPgpMetadata parcel +- Introduction of internal NFC extras: EXTRA_NFC_SIGNED_HASH, EXTRA_NFC_SIG_CREATION_TIMESTAMP ## Version 3 - * First public stable version \ No newline at end of file + +- First public stable version diff --git a/plugins/openpgp-api-lib/README.md b/plugins/openpgp-api-lib/README.md index 8cb6e5e6d0..5aee294d51 100644 --- a/plugins/openpgp-api-lib/README.md +++ b/plugins/openpgp-api-lib/README.md @@ -5,11 +5,13 @@ The OpenPGP API provides methods to execute OpenPGP operations, such as sign, en ### News #### Version 10 - * Retrieve whole public key via ACTION_GET_KEY + +- Retrieve whole public key via ACTION_GET_KEY [Full changelog here…](https://github.com/open-keychain/openpgp-api/blob/master/CHANGELOG.md) ### License + While OpenKeychain itself is GPLv3+, the API library is licensed under Apache License v2. Thus, you are allowed to also use it in closed source applications as long as you respect the [Apache License v2](https://github.com/open-keychain/openpgp-api/blob/master/LICENSE). @@ -28,7 +30,8 @@ dependencies { ``` ### Full example -A full working example is available in the [example project](https://github.com/open-keychain/openpgp-api/blob/master/example). The [``OpenPgpApiActivity.java``](https://github.com/open-keychain/openpgp-api/blob/master/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java) contains most relevant sourcecode. + +A full working example is available in the [example project](https://github.com/open-keychain/openpgp-api/blob/master/example). The [`OpenPgpApiActivity.java`](https://github.com/open-keychain/openpgp-api/blob/master/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java) contains most relevant sourcecode. ### API @@ -38,21 +41,24 @@ A full working example is available in the [example project](https://github.com/ **This tutorial only covers the basics, please consult the full example for a complete overview over all methods** -The API is **not** designed around ``Intents`` which are started via ``startActivityForResult``. These Intent actions typically start an activity for user interaction, so they are not suitable for background tasks. Most API design decisions are explained at [the bottom of this wiki page](https://github.com/open-keychain/open-keychain/wiki/OpenPGP-API#internal-design-decisions). +The API is **not** designed around `Intents` which are started via `startActivityForResult`. These Intent actions typically start an activity for user interaction, so they are not suitable for background tasks. Most API design decisions are explained at [the bottom of this wiki page](https://github.com/open-keychain/open-keychain/wiki/OpenPGP-API#internal-design-decisions). We will go through the basic steps to understand how this API works, following this (greatly simplified) sequence diagram: ![](https://github.com/open-keychain/open-keychain/raw/master/Resources/docs/openpgp_api_1.jpg) In this diagram the client app is depicted on the left side, the OpenPGP provider (in this case OpenKeychain) is depicted on the right. -The remote service is defined via the [AIDL](http://developer.android.com/guide/components/aidl.html) file [``IOpenPgpService``](https://github.com/open-keychain/openpgp-api/blob/master/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl). +The remote service is defined via the [AIDL](http://developer.android.com/guide/components/aidl.html) file [`IOpenPgpService`](https://github.com/open-keychain/openpgp-api/blob/master/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl). It contains only one exposed method which can be invoked remotely: + ```java interface IOpenPgpService { Intent execute(in Intent data, in ParcelFileDescriptor input, in ParcelFileDescriptor output); } ``` + The interaction between the apps is done by binding from your client app to the remote service of OpenKeychain. -``OpenPgpServiceConnection`` is a helper class from the library to ease this step: +`OpenPgpServiceConnection` is a helper class from the library to ease this step: + ```java OpenPgpServiceConnection mServiceConnection; @@ -72,36 +78,38 @@ public void onDestroy() { Following the sequence diagram, these steps are executed: -1. Define an ``Intent`` containing the actual PGP instructions which should be done, e.g. - ```java +1. Define an `Intent` containing the actual PGP instructions which should be done, e.g. + `java Intent data = new Intent(); data.setAction(OpenPgpApi.ACTION_ENCRYPT); data.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[]{"dominik@dominikschuermann.de"}); data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); - ``` - Define an ``InputStream`` currently holding the plaintext, and an ``OutputStream`` where you want the ciphertext to be written by OpenKeychain's remote service: - ```java + ` + Define an `InputStream` currently holding the plaintext, and an `OutputStream` where you want the ciphertext to be written by OpenKeychain's remote service: + `java InputStream is = new ByteArrayInputStream("Hello world!".getBytes("UTF-8")); ByteArrayOutputStream os = new ByteArrayOutputStream(); - ``` - Using a helper class from the library, ``is`` and ``os`` are passed via ``ParcelFileDescriptors`` as ``input`` and ``output`` together with ``Intent data``, as depicted in the sequence diagram, from the client to the remote service. + ` + Using a helper class from the library, `is` and `os` are passed via `ParcelFileDescriptors` as `input` and `output` together with `Intent data`, as depicted in the sequence diagram, from the client to the remote service. Programmatically, this can be done with: - ```java + `java OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService()); Intent result = api.executeApi(data, is, os); - ``` + ` -2. The PGP operation is executed by OpenKeychain and the produced ciphertext is written into ``os`` which can then be accessed by the client app. +2. The PGP operation is executed by OpenKeychain and the produced ciphertext is written into `os` which can then be accessed by the client app. 3. A result Intent is returned containing one of these result codes: - * ``OpenPgpApi.RESULT_CODE_ERROR`` - * ``OpenPgpApi.RESULT_CODE_SUCCESS`` - * ``OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED`` - If ``RESULT_CODE_USER_INTERACTION_REQUIRED`` is returned, an additional ``PendingIntent`` is returned to the client, which must be used to get user input required to process the request. - A ``PendingIntent`` is executed with ``startIntentSenderForResult``, which starts an activity, originally belonging to OpenKeychain, on the [task stack](http://developer.android.com/guide/components/tasks-and-back-stack.html) of the client. - Only if ``RESULT_CODE_SUCCESS`` is returned, ``os`` actually contains data. + - `OpenPgpApi.RESULT_CODE_ERROR` + - `OpenPgpApi.RESULT_CODE_SUCCESS` + - `OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED` + + If `RESULT_CODE_USER_INTERACTION_REQUIRED` is returned, an additional `PendingIntent` is returned to the client, which must be used to get user input required to process the request. + A `PendingIntent` is executed with `startIntentSenderForResult`, which starts an activity, originally belonging to OpenKeychain, on the [task stack](http://developer.android.com/guide/components/tasks-and-back-stack.html) of the client. + Only if `RESULT_CODE_SUCCESS` is returned, `os` actually contains data. A nearly complete example looks like this: + ```java switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { case OpenPgpApi.RESULT_CODE_SUCCESS: { @@ -135,10 +143,10 @@ Intent result = api.executeApi(data, is, os); } ``` -4. Results from a ``PendingIntent`` are returned in ``onActivityResult`` of the activity, which executed ``startIntentSenderForResult``. - The returned ``Intent data`` in ``onActivityResult`` contains the original PGP operation definition and new values acquired from the user interaction. - Thus, you can now execute the ``Intent`` again, like done in step 1. - This time it should return with ``RESULT_CODE_SUCCESS`` because all required information has been obtained by the previous user interaction stored in this ``Intent``. +4. Results from a `PendingIntent` are returned in `onActivityResult` of the activity, which executed `startIntentSenderForResult`. + The returned `Intent data` in `onActivityResult` contains the original PGP operation definition and new values acquired from the user interaction. + Thus, you can now execute the `Intent` again, like done in step 1. + This time it should return with `RESULT_CODE_SUCCESS` because all required information has been obtained by the previous user interaction stored in this `Intent`. ```java protected void onActivityResult(int requestCode, int resultCode, Intent data) { [...] @@ -154,16 +162,17 @@ Intent result = api.executeApi(data, is, os); } ``` - ### Tipps -* ``api.executeApi(data, is, os);`` is a blocking call. If you want a convenient asynchronous call, use ``api.executeApiAsync(data, is, os, new MyCallback([... ]));``, where ``MyCallback`` is an private class implementing ``OpenPgpApi.IOpenPgpCallback``. - See [``OpenPgpApiActivity.java``](https://github.com/open-keychain/openpgp-api/blob/master/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java) for an example. -* Using - ```java - mServiceConnection = new OpenPgpServiceConnection(this, "org.sufficientlysecure.keychain"); - ``` - connects to OpenKeychain directly. - If you want to let the user choose between OpenPGP providers, you can implement the [``OpenPgpAppPreference.java``](https://github.com/open-keychain/openpgp-api/tree/master/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java) like done in the example app. +- `api.executeApi(data, is, os);` is a blocking call. If you want a convenient asynchronous call, use `api.executeApiAsync(data, is, os, new MyCallback([... ]));`, where `MyCallback` is an private class implementing `OpenPgpApi.IOpenPgpCallback`. + See [`OpenPgpApiActivity.java`](https://github.com/open-keychain/openpgp-api/blob/master/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java) for an example. +- Using + + ```java + mServiceConnection = new OpenPgpServiceConnection(this, "org.sufficientlysecure.keychain"); + ``` + + connects to OpenKeychain directly. + If you want to let the user choose between OpenPGP providers, you can implement the [`OpenPgpAppPreference.java`](https://github.com/open-keychain/openpgp-api/tree/master/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java) like done in the example app. -* To enable installing a debug and release version at the same time, the `debug` build of OpenKeychain uses `org.sufficientlysecure.keychain.debug` as a package name. Make sure you connect to the right one during development! +- To enable installing a debug and release version at the same time, the `debug` build of OpenKeychain uses `org.sufficientlysecure.keychain.debug` as a package name. Make sure you connect to the right one during development! -- GitLab From 43213136bebd1d6ab25ed44a2865f9851a2768c9 Mon Sep 17 00:00:00 2001 From: Wolf Montwe Date: Mon, 6 Feb 2023 10:27:42 +0100 Subject: [PATCH 007/317] Add exception for 'plugins/openpgp-api-lib' and revert changes --- build.gradle | 3 +- plugins/openpgp-api-lib/CHANGELOG.md | 70 +++++++++++------------- plugins/openpgp-api-lib/README.md | 79 ++++++++++++---------------- 3 files changed, 68 insertions(+), 84 deletions(-) diff --git a/build.gradle b/build.gradle index 136a83eacc..c5fd81a399 100644 --- a/build.gradle +++ b/build.gradle @@ -101,13 +101,14 @@ spotless { ktlint(libs.versions.ktlint.get()) .setEditorConfigPath("$projectDir/.editorconfig") target("**/*.kt") - targetExclude("**/build/", "**/resources/") + targetExclude("**/build/", "**/resources/", "plugins/openpgp-api-lib/") trimTrailingWhitespace() endWithNewline() } format("markdown") { prettier() target("**/*.md") + targetExclude("plugins/openpgp-api-lib/") trimTrailingWhitespace() endWithNewline() } diff --git a/plugins/openpgp-api-lib/CHANGELOG.md b/plugins/openpgp-api-lib/CHANGELOG.md index 24d48b88a6..93b6824eac 100644 --- a/plugins/openpgp-api-lib/CHANGELOG.md +++ b/plugins/openpgp-api-lib/CHANGELOG.md @@ -1,56 +1,48 @@ # Version history ## Version 10 - -- Retrieve whole public key via ACTION_GET_KEY + * Retrieve whole public key via ACTION_GET_KEY ## Version 9 - -- AIDL Service has been changed from IOpenPgpService.aidl to IOpenPgpService2.aidl - This fixes truncated data streams (thanks to 'mgeier63'). -- Fix for OpenPgpKeyPreference: Properly execute pending user interactions -- Charset moved to OpenPgpMetadata + * AIDL Service has been changed from IOpenPgpService.aidl to IOpenPgpService2.aidl + This fixes truncated data streams (thanks to 'mgeier63'). + * Fix for OpenPgpKeyPreference: Properly execute pending user interactions + * Charset moved to OpenPgpMetadata ## Version 8 - -- OpenPgpSignatureResult: - method getStatus() renamed to getResult() - constants have been renamed for clarity - new constants: RESULT_NO_SIGNATURE, RESULT_INVALID_INSECURE - isSignatureOnly() has been deprecated -- RESULT_TYPES have been removed -- new OpenPgpDecryptionResult returned via RESULT_DECRYPTION -- OpenPgpSignatureResult and OpenPgpDecryptionResult are never null, they are always returned. + * OpenPgpSignatureResult: + method getStatus() renamed to getResult() + constants have been renamed for clarity + new constants: RESULT_NO_SIGNATURE, RESULT_INVALID_INSECURE + isSignatureOnly() has been deprecated + * RESULT_TYPES have been removed + * new OpenPgpDecryptionResult returned via RESULT_DECRYPTION + * OpenPgpSignatureResult and OpenPgpDecryptionResult are never null, they are always returned. ## Version 7 - -- Deprecation of ACCOUNT_NAME, please use ACTION_GET_SIGN_KEY_ID to get key id -- Introduce EXTRA_SIGN_KEY_ID -- New extra for ACTION_ENCRYPT and ACTION_SIGN_AND_ENCRYPT: EXTRA_ENABLE_COMPRESSION (default to true) -- Return PendingIntent to view key for signatures -- New result for ACTION_DECRYPT_VERIFY: RESULT_TYPE -- New ACTION_GET_SIGN_KEY_ID -- EXTRA_PASSPHRASE changed from String to char[] + * Deprecation of ACCOUNT_NAME, please use ACTION_GET_SIGN_KEY_ID to get key id + * Introduce EXTRA_SIGN_KEY_ID + * New extra for ACTION_ENCRYPT and ACTION_SIGN_AND_ENCRYPT: EXTRA_ENABLE_COMPRESSION (default to true) + * Return PendingIntent to view key for signatures + * New result for ACTION_DECRYPT_VERIFY: RESULT_TYPE + * New ACTION_GET_SIGN_KEY_ID + * EXTRA_PASSPHRASE changed from String to char[] ## Version 6 - -- Deprecate ACTION_SIGN -- Introduce ACTION_CLEARTEXT_SIGN and ACTION_DETACHED_SIGN -- New extra for ACTION_DETACHED_SIGN: EXTRA_DETACHED_SIGNATURE -- New result for ACTION_DECRYPT_VERIFY: RESULT_DETACHED_SIGNATURE -- New result for ACTION_DECRYPT_VERIFY: RESULT_CHARSET + * Deprecate ACTION_SIGN + * Introduce ACTION_CLEARTEXT_SIGN and ACTION_DETACHED_SIGN + * New extra for ACTION_DETACHED_SIGN: EXTRA_DETACHED_SIGNATURE + * New result for ACTION_DECRYPT_VERIFY: RESULT_DETACHED_SIGNATURE + * New result for ACTION_DECRYPT_VERIFY: RESULT_CHARSET ## Version 5 - -- OpenPgpSignatureResult: new consts RESULT_INVALID_KEY_REVOKED and RESULT_INVALID_KEY_EXPIRED -- OpenPgpSignatureResult: ArrayList userIds + * OpenPgpSignatureResult: new consts RESULT_INVALID_KEY_REVOKED and RESULT_INVALID_KEY_EXPIRED + * OpenPgpSignatureResult: ArrayList userIds ## Version 4 - -- No changes to existing methods -> backward compatible -- Introduction of ACTION_DECRYPT_METADATA, RESULT_METADATA, EXTRA_ORIGINAL_FILENAME, and OpenPgpMetadata parcel -- Introduction of internal NFC extras: EXTRA_NFC_SIGNED_HASH, EXTRA_NFC_SIG_CREATION_TIMESTAMP + * No changes to existing methods -> backward compatible + * Introduction of ACTION_DECRYPT_METADATA, RESULT_METADATA, EXTRA_ORIGINAL_FILENAME, and OpenPgpMetadata parcel + * Introduction of internal NFC extras: EXTRA_NFC_SIGNED_HASH, EXTRA_NFC_SIG_CREATION_TIMESTAMP ## Version 3 - -- First public stable version + * First public stable version \ No newline at end of file diff --git a/plugins/openpgp-api-lib/README.md b/plugins/openpgp-api-lib/README.md index 5aee294d51..8cb6e5e6d0 100644 --- a/plugins/openpgp-api-lib/README.md +++ b/plugins/openpgp-api-lib/README.md @@ -5,13 +5,11 @@ The OpenPGP API provides methods to execute OpenPGP operations, such as sign, en ### News #### Version 10 - -- Retrieve whole public key via ACTION_GET_KEY + * Retrieve whole public key via ACTION_GET_KEY [Full changelog here…](https://github.com/open-keychain/openpgp-api/blob/master/CHANGELOG.md) ### License - While OpenKeychain itself is GPLv3+, the API library is licensed under Apache License v2. Thus, you are allowed to also use it in closed source applications as long as you respect the [Apache License v2](https://github.com/open-keychain/openpgp-api/blob/master/LICENSE). @@ -30,8 +28,7 @@ dependencies { ``` ### Full example - -A full working example is available in the [example project](https://github.com/open-keychain/openpgp-api/blob/master/example). The [`OpenPgpApiActivity.java`](https://github.com/open-keychain/openpgp-api/blob/master/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java) contains most relevant sourcecode. +A full working example is available in the [example project](https://github.com/open-keychain/openpgp-api/blob/master/example). The [``OpenPgpApiActivity.java``](https://github.com/open-keychain/openpgp-api/blob/master/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java) contains most relevant sourcecode. ### API @@ -41,24 +38,21 @@ A full working example is available in the [example project](https://github.com/ **This tutorial only covers the basics, please consult the full example for a complete overview over all methods** -The API is **not** designed around `Intents` which are started via `startActivityForResult`. These Intent actions typically start an activity for user interaction, so they are not suitable for background tasks. Most API design decisions are explained at [the bottom of this wiki page](https://github.com/open-keychain/open-keychain/wiki/OpenPGP-API#internal-design-decisions). +The API is **not** designed around ``Intents`` which are started via ``startActivityForResult``. These Intent actions typically start an activity for user interaction, so they are not suitable for background tasks. Most API design decisions are explained at [the bottom of this wiki page](https://github.com/open-keychain/open-keychain/wiki/OpenPGP-API#internal-design-decisions). We will go through the basic steps to understand how this API works, following this (greatly simplified) sequence diagram: ![](https://github.com/open-keychain/open-keychain/raw/master/Resources/docs/openpgp_api_1.jpg) In this diagram the client app is depicted on the left side, the OpenPGP provider (in this case OpenKeychain) is depicted on the right. -The remote service is defined via the [AIDL](http://developer.android.com/guide/components/aidl.html) file [`IOpenPgpService`](https://github.com/open-keychain/openpgp-api/blob/master/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl). +The remote service is defined via the [AIDL](http://developer.android.com/guide/components/aidl.html) file [``IOpenPgpService``](https://github.com/open-keychain/openpgp-api/blob/master/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl). It contains only one exposed method which can be invoked remotely: - ```java interface IOpenPgpService { Intent execute(in Intent data, in ParcelFileDescriptor input, in ParcelFileDescriptor output); } ``` - The interaction between the apps is done by binding from your client app to the remote service of OpenKeychain. -`OpenPgpServiceConnection` is a helper class from the library to ease this step: - +``OpenPgpServiceConnection`` is a helper class from the library to ease this step: ```java OpenPgpServiceConnection mServiceConnection; @@ -78,38 +72,36 @@ public void onDestroy() { Following the sequence diagram, these steps are executed: -1. Define an `Intent` containing the actual PGP instructions which should be done, e.g. - `java +1. Define an ``Intent`` containing the actual PGP instructions which should be done, e.g. + ```java Intent data = new Intent(); data.setAction(OpenPgpApi.ACTION_ENCRYPT); data.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[]{"dominik@dominikschuermann.de"}); data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); - ` - Define an `InputStream` currently holding the plaintext, and an `OutputStream` where you want the ciphertext to be written by OpenKeychain's remote service: - `java + ``` + Define an ``InputStream`` currently holding the plaintext, and an ``OutputStream`` where you want the ciphertext to be written by OpenKeychain's remote service: + ```java InputStream is = new ByteArrayInputStream("Hello world!".getBytes("UTF-8")); ByteArrayOutputStream os = new ByteArrayOutputStream(); - ` - Using a helper class from the library, `is` and `os` are passed via `ParcelFileDescriptors` as `input` and `output` together with `Intent data`, as depicted in the sequence diagram, from the client to the remote service. + ``` + Using a helper class from the library, ``is`` and ``os`` are passed via ``ParcelFileDescriptors`` as ``input`` and ``output`` together with ``Intent data``, as depicted in the sequence diagram, from the client to the remote service. Programmatically, this can be done with: - `java + ```java OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService()); Intent result = api.executeApi(data, is, os); - ` + ``` -2. The PGP operation is executed by OpenKeychain and the produced ciphertext is written into `os` which can then be accessed by the client app. +2. The PGP operation is executed by OpenKeychain and the produced ciphertext is written into ``os`` which can then be accessed by the client app. 3. A result Intent is returned containing one of these result codes: + * ``OpenPgpApi.RESULT_CODE_ERROR`` + * ``OpenPgpApi.RESULT_CODE_SUCCESS`` + * ``OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED`` - - `OpenPgpApi.RESULT_CODE_ERROR` - - `OpenPgpApi.RESULT_CODE_SUCCESS` - - `OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED` - - If `RESULT_CODE_USER_INTERACTION_REQUIRED` is returned, an additional `PendingIntent` is returned to the client, which must be used to get user input required to process the request. - A `PendingIntent` is executed with `startIntentSenderForResult`, which starts an activity, originally belonging to OpenKeychain, on the [task stack](http://developer.android.com/guide/components/tasks-and-back-stack.html) of the client. - Only if `RESULT_CODE_SUCCESS` is returned, `os` actually contains data. + If ``RESULT_CODE_USER_INTERACTION_REQUIRED`` is returned, an additional ``PendingIntent`` is returned to the client, which must be used to get user input required to process the request. + A ``PendingIntent`` is executed with ``startIntentSenderForResult``, which starts an activity, originally belonging to OpenKeychain, on the [task stack](http://developer.android.com/guide/components/tasks-and-back-stack.html) of the client. + Only if ``RESULT_CODE_SUCCESS`` is returned, ``os`` actually contains data. A nearly complete example looks like this: - ```java switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { case OpenPgpApi.RESULT_CODE_SUCCESS: { @@ -143,10 +135,10 @@ Intent result = api.executeApi(data, is, os); } ``` -4. Results from a `PendingIntent` are returned in `onActivityResult` of the activity, which executed `startIntentSenderForResult`. - The returned `Intent data` in `onActivityResult` contains the original PGP operation definition and new values acquired from the user interaction. - Thus, you can now execute the `Intent` again, like done in step 1. - This time it should return with `RESULT_CODE_SUCCESS` because all required information has been obtained by the previous user interaction stored in this `Intent`. +4. Results from a ``PendingIntent`` are returned in ``onActivityResult`` of the activity, which executed ``startIntentSenderForResult``. + The returned ``Intent data`` in ``onActivityResult`` contains the original PGP operation definition and new values acquired from the user interaction. + Thus, you can now execute the ``Intent`` again, like done in step 1. + This time it should return with ``RESULT_CODE_SUCCESS`` because all required information has been obtained by the previous user interaction stored in this ``Intent``. ```java protected void onActivityResult(int requestCode, int resultCode, Intent data) { [...] @@ -162,17 +154,16 @@ Intent result = api.executeApi(data, is, os); } ``` -### Tipps - -- `api.executeApi(data, is, os);` is a blocking call. If you want a convenient asynchronous call, use `api.executeApiAsync(data, is, os, new MyCallback([... ]));`, where `MyCallback` is an private class implementing `OpenPgpApi.IOpenPgpCallback`. - See [`OpenPgpApiActivity.java`](https://github.com/open-keychain/openpgp-api/blob/master/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java) for an example. -- Using - ```java - mServiceConnection = new OpenPgpServiceConnection(this, "org.sufficientlysecure.keychain"); - ``` +### Tipps +* ``api.executeApi(data, is, os);`` is a blocking call. If you want a convenient asynchronous call, use ``api.executeApiAsync(data, is, os, new MyCallback([... ]));``, where ``MyCallback`` is an private class implementing ``OpenPgpApi.IOpenPgpCallback``. + See [``OpenPgpApiActivity.java``](https://github.com/open-keychain/openpgp-api/blob/master/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java) for an example. +* Using - connects to OpenKeychain directly. - If you want to let the user choose between OpenPGP providers, you can implement the [`OpenPgpAppPreference.java`](https://github.com/open-keychain/openpgp-api/tree/master/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java) like done in the example app. + ```java + mServiceConnection = new OpenPgpServiceConnection(this, "org.sufficientlysecure.keychain"); + ``` + connects to OpenKeychain directly. + If you want to let the user choose between OpenPGP providers, you can implement the [``OpenPgpAppPreference.java``](https://github.com/open-keychain/openpgp-api/tree/master/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java) like done in the example app. -- To enable installing a debug and release version at the same time, the `debug` build of OpenKeychain uses `org.sufficientlysecure.keychain.debug` as a package name. Make sure you connect to the right one during development! +* To enable installing a debug and release version at the same time, the `debug` build of OpenKeychain uses `org.sufficientlysecure.keychain.debug` as a package name. Make sure you connect to the right one during development! -- GitLab From 0d030aab6dc8eab6fe0081c95244b5af0af56738 Mon Sep 17 00:00:00 2001 From: Wolf Montwe Date: Mon, 6 Feb 2023 10:49:21 +0100 Subject: [PATCH 008/317] Remove trimTrailingWhitespace as not needed for ktlint --- .../fsck/k9/storage/messages/RetrieveMessageListOperations.kt | 2 +- .../com/fsck/k9/storage/messages/ThreadMessageOperations.kt | 2 +- build.gradle | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageListOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageListOperations.kt index ddf0a397a9..01b0d93e53 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageListOperations.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveMessageListOperations.kt @@ -126,7 +126,7 @@ JOIN folders ON (folders.id = messages.folder_id) GROUP BY threads.root ORDER BY $orderBy """, - selectionArgs, + selectionArgs ).use { cursor -> val cursorMessageAccessor = CursorMessageAccessor(cursor, includesThreadCount = true) buildList { diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/ThreadMessageOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/ThreadMessageOperations.kt index 21491c98fe..e032756abc 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/messages/ThreadMessageOperations.kt +++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/ThreadMessageOperations.kt @@ -25,7 +25,7 @@ FROM messages LEFT JOIN message_parts ON (messages.message_part_id = message_parts.id) WHERE messages.id = ? """, - arrayOf(messageId.toString()), + arrayOf(messageId.toString()) ).use { cursor -> if (!cursor.moveToFirst()) error("Message not found: $messageId") diff --git a/build.gradle b/build.gradle index c5fd81a399..6cb56a34f4 100644 --- a/build.gradle +++ b/build.gradle @@ -102,7 +102,6 @@ spotless { .setEditorConfigPath("$projectDir/.editorconfig") target("**/*.kt") targetExclude("**/build/", "**/resources/", "plugins/openpgp-api-lib/") - trimTrailingWhitespace() endWithNewline() } format("markdown") { -- GitLab From 11819232ea84b6c2cf93c1eab0078baccef9231b Mon Sep 17 00:00:00 2001 From: Wolf Montwe Date: Mon, 6 Feb 2023 11:35:18 +0100 Subject: [PATCH 009/317] Add formatter rules for kts and misc files --- build.gradle | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/build.gradle b/build.gradle index 6cb56a34f4..1f70bad190 100644 --- a/build.gradle +++ b/build.gradle @@ -104,6 +104,13 @@ spotless { targetExclude("**/build/", "**/resources/", "plugins/openpgp-api-lib/") endWithNewline() } + kotlinGradle { + ktlint(libs.versions.ktlint.get()) + .setEditorConfigPath("$projectDir/.editorconfig") + target("**/*.gradle.kts") + targetExclude("**/build/") + endWithNewline() + } format("markdown") { prettier() target("**/*.md") @@ -111,6 +118,12 @@ spotless { trimTrailingWhitespace() endWithNewline() } + format("misc") { + target("**/*.gradle", "**/.gitignore") + trimTrailingWhitespace() + indentWithSpaces(4) + endWithNewline() + } } tasks.register('testsOnCi') { -- GitLab From 80b35d6fa7683e8896ed27c8825643c8a72dc425 Mon Sep 17 00:00:00 2001 From: Wolf Montwe Date: Mon, 6 Feb 2023 11:54:56 +0100 Subject: [PATCH 010/317] Change Android CI workflow to use spotlessCheck --- .github/workflows/android.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 9121b5b7c6..8fc1ce8b3a 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -28,4 +28,4 @@ jobs: distribution: 'zulu' java-version: 17 - uses: gradle/gradle-build-action@v2 - - run: ./gradlew assembleDebug ktlintCheck testsOnCi + - run: ./gradlew assembleDebug spotlessCheck testsOnCi -- GitLab From 64c4bbe8247ece112ad0775a68a834673ebdb171 Mon Sep 17 00:00:00 2001 From: Wolf Montwe Date: Mon, 6 Feb 2023 12:16:15 +0100 Subject: [PATCH 011/317] Change pull_request_template to include spotless formatter instructions --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 6b2d7e0587..2a7da388ea 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -3,7 +3,7 @@ Please ensure that your pull request meets the following requirements - thanks! - Does not contain merge commits. Rebase instead. - Contains commits with descriptive titles. - New code is written in Kotlin whenever possible. -- Follows our existing codestyle (`gradlew ktlintCheck`; will be checked by CI). +- Follows our existing codestyle (`gradlew spotlessCheck` to check and `gradlew spotlessFormat` to format your source code; will be checked by CI). - Does not break any unit tests (`gradlew testDebugUnitTest`; will be checked by CI). - Uses a descriptive title; don't put issue numbers in there. - Contains a reference to the issue that it fixes (e.g. _Closes #XXX_ or _Fixes #XXX_) in the body text. -- GitLab From f91f3e268b7763614b27fabe06928315ae915110 Mon Sep 17 00:00:00 2001 From: cketti Date: Mon, 6 Feb 2023 19:43:02 +0100 Subject: [PATCH 012/317] Add abstraction for Android's vibrator service --- .../com/fsck/k9/ui/settings/KoinModule.kt | 2 ++ .../account/AccountSettingsFragment.kt | 6 ++-- .../account/VibrationDialogFragment.kt | 14 ++------ .../fsck/k9/ui/settings/account/Vibrator.kt | 32 +++++++++++++++++++ 4 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/Vibrator.kt diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt index 01df8c35ea..52498229f5 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt @@ -3,6 +3,7 @@ package com.fsck.k9.ui.settings import com.fsck.k9.helper.NamedThreadFactory import com.fsck.k9.ui.settings.account.AccountSettingsDataStoreFactory import com.fsck.k9.ui.settings.account.AccountSettingsViewModel +import com.fsck.k9.ui.settings.account.getSystemVibrator import com.fsck.k9.ui.settings.export.SettingsExportViewModel import com.fsck.k9.ui.settings.general.GeneralSettingsDataStore import com.fsck.k9.ui.settings.general.GeneralSettingsViewModel @@ -33,6 +34,7 @@ val settingsUiModule = module { notificationController = get() ) } + factory { getSystemVibrator(context = get()) } viewModel { SettingsExportViewModel(context = get(), preferences = get(), settingsExporter = get()) } viewModel { SettingsImportViewModel(get(), get()) } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsFragment.kt index 8ae3d7cabe..50050a97f6 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsFragment.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsFragment.kt @@ -4,12 +4,10 @@ import android.annotation.SuppressLint import android.content.Intent import android.os.Build import android.os.Bundle -import android.os.Vibrator import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import android.widget.Toast -import androidx.core.content.getSystemService import androidx.core.net.toUri import androidx.preference.ListPreference import androidx.preference.Preference @@ -53,8 +51,8 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr private val accountRemover: BackgroundAccountRemover by inject() private val notificationChannelManager: NotificationChannelManager by inject() private val notificationSettingsUpdater: NotificationSettingsUpdater by inject() + private val vibrator: Vibrator by inject() - private val vibrator by lazy { requireContext().getSystemService() } private lateinit var dataStore: AccountSettingsDataStore private var notificationSoundPreference: NotificationSoundPreference? = null @@ -203,7 +201,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr } private fun initializeNotifications(account: Account) { - if (vibrator?.hasVibrator() != true) { + if (!vibrator.hasVibrator) { findPreference(PREFERENCE_NOTIFICATION_VIBRATION)?.remove() } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationDialogFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationDialogFragment.kt index 4ecedb8baa..00f43bfd53 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationDialogFragment.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationDialogFragment.kt @@ -3,8 +3,6 @@ package com.fsck.k9.ui.settings.account import android.app.Dialog import android.os.Build import android.os.Bundle -import android.os.VibrationEffect -import android.os.Vibrator import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter @@ -14,16 +12,16 @@ import android.widget.SeekBar.OnSeekBarChangeListener import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.SwitchCompat -import androidx.core.content.getSystemService import androidx.preference.PreferenceDialogFragmentCompat import com.fsck.k9.NotificationVibration import com.fsck.k9.VibratePattern import com.fsck.k9.ui.R import com.fsck.k9.ui.getEnum import com.fsck.k9.ui.putEnum +import org.koin.android.ext.android.inject class VibrationDialogFragment : PreferenceDialogFragmentCompat() { - private val vibrator by lazy { requireContext().getSystemService() ?: error("Vibrator service missing") } + private val vibrator: Vibrator by inject() private val vibrationPreference: VibrationPreference get() = preference as VibrationPreference @@ -83,13 +81,7 @@ class VibrationDialogFragment : PreferenceDialogFragmentCompat() { val vibrationTimes = adapter.vibrationTimes val vibrationPattern = NotificationVibration.getSystemPattern(vibratePattern, vibrationTimes) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val vibrationEffect = VibrationEffect.createWaveform(vibrationPattern, -1) - vibrator.vibrate(vibrationEffect) - } else { - @Suppress("DEPRECATION") - vibrator.vibrate(vibrationPattern, -1) - } + vibrator.vibrate(vibrationPattern) } private inner class VibrationPatternAdapter( diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/Vibrator.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/Vibrator.kt new file mode 100644 index 0000000000..544b71f05e --- /dev/null +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/Vibrator.kt @@ -0,0 +1,32 @@ +package com.fsck.k9.ui.settings.account + +import android.content.Context +import android.os.Build +import android.os.VibrationEffect +import androidx.core.content.getSystemService +import android.os.Vibrator as VibratorService + +interface Vibrator { + val hasVibrator: Boolean + fun vibrate(vibrationPattern: LongArray) +} + +internal class AndroidVibrator(private val vibrator: VibratorService) : Vibrator { + override val hasVibrator: Boolean + get() = vibrator.hasVibrator() + + override fun vibrate(vibrationPattern: LongArray) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val vibrationEffect = VibrationEffect.createWaveform(vibrationPattern, -1) + vibrator.vibrate(vibrationEffect) + } else { + @Suppress("DEPRECATION") + vibrator.vibrate(vibrationPattern, -1) + } + } +} + +internal fun getSystemVibrator(context: Context): Vibrator { + val vibratorService = context.getSystemService() ?: error("Vibrator service missing") + return AndroidVibrator(vibratorService) +} -- GitLab From 125e1af9d6f35ebbc563a3775fbb464120790de7 Mon Sep 17 00:00:00 2001 From: cketti Date: Mon, 6 Feb 2023 19:45:09 +0100 Subject: [PATCH 013/317] Use Koin instead of custom `by lazy` code --- .../src/test/java/com/fsck/k9/DependencyInjectionTest.kt | 6 ++++++ app/ui/legacy/src/main/java/com/fsck/k9/ui/KoinModule.kt | 2 ++ .../com/fsck/k9/ui/choosefolder/ChooseFolderActivity.kt | 2 +- .../src/main/java/com/fsck/k9/ui/folders/KoinModule.kt | 2 ++ .../com/fsck/k9/ui/managefolders/ManageFoldersFragment.kt | 2 +- .../com/fsck/k9/ui/messagelist/MessageListFragment.kt | 5 ++--- .../com/fsck/k9/ui/messageview/MessageContainerView.kt | 8 +++----- 7 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt b/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt index 09f3508db3..1c73b1dd3e 100644 --- a/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt +++ b/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt @@ -1,12 +1,15 @@ package com.fsck.k9 +import android.view.ContextThemeWrapper import androidx.lifecycle.LifecycleOwner import androidx.work.WorkerParameters import com.fsck.k9.job.MailSyncWorker +import com.fsck.k9.ui.R import com.fsck.k9.ui.changelog.ChangeLogMode import com.fsck.k9.ui.changelog.ChangelogViewModel import com.fsck.k9.ui.endtoend.AutocryptKeyTransferActivity import com.fsck.k9.ui.endtoend.AutocryptKeyTransferPresenter +import com.fsck.k9.ui.folders.FolderIconProvider import com.fsck.k9.ui.folders.FolderNameFormatter import com.fsck.k9.ui.helper.SizeFormatter import org.junit.Test @@ -44,6 +47,9 @@ class DependencyInjectionTest : AutoCloseKoinTest() { withParameter { RuntimeEnvironment.getApplication() } withParameter { ChangeLogMode.CHANGE_LOG } withParameter { mock() } + withParameter { + ContextThemeWrapper(RuntimeEnvironment.getApplication(), R.style.Theme_K9_DayNight).theme + } } } } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/KoinModule.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/KoinModule.kt index 5e3b83ef47..fa9746bff4 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/KoinModule.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/KoinModule.kt @@ -8,6 +8,7 @@ import com.fsck.k9.ui.helper.HtmlToSpanned import com.fsck.k9.ui.helper.SizeFormatter import com.fsck.k9.ui.messageview.LinkTextHandler import com.fsck.k9.ui.share.ShareIntentBuilder +import org.koin.core.qualifier.named import org.koin.dsl.module val uiModule = module { @@ -15,6 +16,7 @@ val uiModule = module { single { K9ThemeProvider() } single { HtmlSettingsProvider(get()) } single { DisplayHtmlUiFactory(get()) } + factory(named("MessageView")) { get().createForMessageView() } factory { (context: Context) -> SizeFormatter(context.resources) } factory { ShareIntentBuilder(resourceProvider = get(), textPartFinder = get(), quoteDateFormatter = get()) } factory { LinkTextHandler(context = get(), clipboardManager = get()) } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderActivity.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderActivity.kt index 5ec07b4ac4..713dfca9fa 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderActivity.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderActivity.kt @@ -31,7 +31,7 @@ class ChooseFolderActivity : K9Activity() { private val preferences: Preferences by inject() private val messagingController: MessagingController by inject() private val folderNameFormatter: FolderNameFormatter by inject { parametersOf(this) } - private val folderIconProvider by lazy { FolderIconProvider(theme) } + private val folderIconProvider: FolderIconProvider by inject { parametersOf(theme) } private lateinit var recyclerView: RecyclerView private lateinit var itemAdapter: ItemAdapter diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/folders/KoinModule.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/folders/KoinModule.kt index 083b6c8274..d493ca8aba 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/folders/KoinModule.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/folders/KoinModule.kt @@ -1,6 +1,7 @@ package com.fsck.k9.ui.folders import android.content.Context +import android.content.res.Resources.Theme import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module @@ -8,4 +9,5 @@ val foldersUiModule = module { single { FolderNameFormatterFactory() } factory { (context: Context) -> FolderNameFormatter(context.resources) } viewModel { FoldersViewModel(folderRepository = get(), messageCountsProvider = get()) } + factory { (theme: Theme) -> FolderIconProvider(theme) } } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/managefolders/ManageFoldersFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/managefolders/ManageFoldersFragment.kt index 2607a868df..6f8f0dc15a 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/managefolders/ManageFoldersFragment.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/managefolders/ManageFoldersFragment.kt @@ -32,7 +32,7 @@ class ManageFoldersFragment : Fragment() { private val folderNameFormatter: FolderNameFormatter by inject { parametersOf(requireActivity()) } private val messagingController: MessagingController by inject() private val preferences: Preferences by inject() - private val folderIconProvider by lazy { FolderIconProvider(requireActivity().theme) } + private val folderIconProvider: FolderIconProvider by inject { parametersOf(requireActivity().theme) } private lateinit var account: Account private lateinit var itemAdapter: ItemAdapter diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt index 4b6b914e91..bc6c8a7849 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messagelist/MessageListFragment.kt @@ -53,7 +53,6 @@ import com.fsck.k9.ui.changelog.RecentChangesViewModel import com.fsck.k9.ui.choosefolder.ChooseFolderActivity import com.fsck.k9.ui.fab.ShrinkFabOnScrollListener import com.fsck.k9.ui.folders.FolderNameFormatter -import com.fsck.k9.ui.folders.FolderNameFormatterFactory import com.fsck.k9.ui.helper.RelativeDateTimeFormatter import com.fsck.k9.ui.messagelist.MessageListFragment.MessageListFragmentListener.Companion.MAX_PROGRESS import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton @@ -63,6 +62,7 @@ import java.util.concurrent.Future import net.jcip.annotations.GuardedBy import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf import timber.log.Timber private const val MAXIMUM_MESSAGE_SORT_OVERRIDES = 3 @@ -77,8 +77,7 @@ class MessageListFragment : private val recentChangesViewModel: RecentChangesViewModel by viewModel() private val sortTypeToastProvider: SortTypeToastProvider by inject() - private val folderNameFormatterFactory: FolderNameFormatterFactory by inject() - private val folderNameFormatter: FolderNameFormatter by lazy { folderNameFormatterFactory.create(requireContext()) } + private val folderNameFormatter: FolderNameFormatter by inject { parametersOf(requireContext()) } private val messagingController: MessagingController by inject() private val preferences: Preferences by inject() private val clock: Clock by inject() diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageContainerView.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageContainerView.kt index 0d3534f269..0915160e4d 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageContainerView.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageContainerView.kt @@ -31,23 +31,21 @@ import com.fsck.k9.mail.Address import com.fsck.k9.mailstore.AttachmentResolver import com.fsck.k9.mailstore.AttachmentViewInfo import com.fsck.k9.mailstore.MessageViewInfo +import com.fsck.k9.message.html.DisplayHtml import com.fsck.k9.ui.R -import com.fsck.k9.ui.helper.DisplayHtmlUiFactory import com.fsck.k9.view.MessageWebView import com.fsck.k9.view.MessageWebView.OnPageFinishedListener import com.fsck.k9.view.WebViewConfigProvider import org.koin.core.component.KoinComponent -import org.koin.core.component.get import org.koin.core.component.inject +import org.koin.core.qualifier.named class MessageContainerView(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs), OnCreateContextMenuListener, KoinComponent { - private val displayHtml by lazy(mode = LazyThreadSafetyMode.NONE) { - get().createForMessageView() - } + private val displayHtml: DisplayHtml by inject(named("MessageView")) private val webViewConfigProvider: WebViewConfigProvider by inject() private val clipboardManager: ClipboardManager by inject() private val linkTextHandler: LinkTextHandler by inject() -- GitLab From cea4a514942d5dd3ca168f82ccaeec64705604f9 Mon Sep 17 00:00:00 2001 From: cketti Date: Tue, 7 Feb 2023 12:24:21 +0100 Subject: [PATCH 014/317] Tweak appearance of "Download complete message" button --- app/ui/legacy/src/main/res/layout/message.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/ui/legacy/src/main/res/layout/message.xml b/app/ui/legacy/src/main/res/layout/message.xml index 1ac80286db..b3b9d049e9 100644 --- a/app/ui/legacy/src/main/res/layout/message.xml +++ b/app/ui/legacy/src/main/res/layout/message.xml @@ -103,6 +103,8 @@