From b88f23a18e5e7af878649e5467d0defc93986e74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolf-Martell=20Montw=C3=A9?= Date: Wed, 10 Jan 2024 18:14:40 +0100 Subject: [PATCH] Add `app-k9mail` module to host the app project --- app-k9mail/build.gradle.kts | 147 +++++++++++++ .../dependencies/releaseRuntimeClasspath.txt | 0 {app/k9mail => app-k9mail}/proguard-rules.pro | 0 .../debug/java/app/k9mail/dev/DebugConfig.kt | 12 ++ .../java/app/k9mail/dev/DemoBackendFactory.kt | 0 .../src/debug/res/values/app_logo_colors.xml | 0 app-k9mail/src/main/AndroidManifest.xml | 9 + .../src/main/kotlin/com/fsck/k9/K9App.kt | 7 + .../main/kotlin/com/fsck/k9/K9KoinModule.kt | 29 +++ .../k9/auth/AppOAuthConfigurationFactory.kt | 0 .../src/main/res/drawable/ic_app_logo.xml | 150 +++++++++++++ app-k9mail/src/main/res/values/drawables.xml | 4 + app-k9mail/src/main/res/values/strings.xml | 5 + .../java/app/k9mail/dev/ReleaseConfig.kt | 8 +- app/k9mail/build.gradle.kts | 130 +----------- .../debug/java/app/k9mail/dev/DebugConfig.kt | 12 -- app/k9mail/src/main/AndroidManifest.xml | 197 +++++++++--------- .../java/com/fsck/k9/{App.kt => CommonApp.kt} | 22 +- .../{Dependencies.kt => CommonKoinModule.kt} | 10 +- .../java/com/fsck/k9/backends/KoinModule.kt | 11 +- .../k9/backends/RealOAuth2TokenProvider.kt | 7 +- .../fsck/k9/provider/UnreadWidgetProvider.kt | 2 +- .../UnreadWidgetConfigurationActivity.kt | 2 +- .../UnreadWidgetConfigurationFragment.kt | 4 +- .../java/com/fsck/k9/AppRobolectricTest.kt | 14 -- .../com/fsck/k9/DependencyInjectionTest.kt | 2 +- .../src/test/java/com/fsck/k9/TestApp.kt | 25 +++ .../unread/UnreadWidgetDataProviderTest.kt | 10 +- settings.gradle.kts | 1 + 29 files changed, 522 insertions(+), 298 deletions(-) create mode 100644 app-k9mail/build.gradle.kts rename {app/k9mail => app-k9mail}/dependencies/releaseRuntimeClasspath.txt (100%) rename {app/k9mail => app-k9mail}/proguard-rules.pro (100%) create mode 100644 app-k9mail/src/debug/java/app/k9mail/dev/DebugConfig.kt rename {app/k9mail => app-k9mail}/src/debug/java/app/k9mail/dev/DemoBackendFactory.kt (100%) rename {app/k9mail => app-k9mail}/src/debug/res/values/app_logo_colors.xml (100%) create mode 100644 app-k9mail/src/main/AndroidManifest.xml create mode 100644 app-k9mail/src/main/kotlin/com/fsck/k9/K9App.kt create mode 100644 app-k9mail/src/main/kotlin/com/fsck/k9/K9KoinModule.kt rename {app/k9mail/src/main/java => app-k9mail/src/main/kotlin}/com/fsck/k9/auth/AppOAuthConfigurationFactory.kt (100%) create mode 100644 app-k9mail/src/main/res/drawable/ic_app_logo.xml create mode 100644 app-k9mail/src/main/res/values/drawables.xml create mode 100644 app-k9mail/src/main/res/values/strings.xml rename {app/k9mail => app-k9mail}/src/release/java/app/k9mail/dev/ReleaseConfig.kt (52%) delete mode 100644 app/k9mail/src/debug/java/app/k9mail/dev/DebugConfig.kt rename app/k9mail/src/main/java/com/fsck/k9/{App.kt => CommonApp.kt} (88%) rename app/k9mail/src/main/java/com/fsck/k9/{Dependencies.kt => CommonKoinModule.kt} (86%) delete mode 100644 app/k9mail/src/test/java/com/fsck/k9/AppRobolectricTest.kt create mode 100644 app/k9mail/src/test/java/com/fsck/k9/TestApp.kt diff --git a/app-k9mail/build.gradle.kts b/app-k9mail/build.gradle.kts new file mode 100644 index 000000000..4719be17b --- /dev/null +++ b/app-k9mail/build.gradle.kts @@ -0,0 +1,147 @@ +plugins { + id(ThunderbirdPlugins.App.android) + alias(libs.plugins.dependency.guard) +} + +val testCoverageEnabled: Boolean by extra +if (testCoverageEnabled) { + apply(plugin = "jacoco") +} + +dependencies { + implementation(projects.app.k9mail) + + implementation(projects.app.core) + implementation(projects.app.ui.legacy) + implementation(projects.app.ui.messageListWidget) + + debugImplementation(projects.backend.demo) + + implementation(libs.androidx.work.runtime) +} + +android { + namespace = "com.fsck.k9" + + defaultConfig { + applicationId = "com.fsck.k9" + testApplicationId = "com.fsck.k9.tests" + + versionCode = 37014 + versionName = "6.715-SNAPSHOT" + + // Keep in sync with the resource string array "supported_languages" + resourceConfigurations.addAll( + listOf( + "in", "br", "ca", "cs", "cy", "da", "de", "et", "en", "en_GB", "es", "eo", "eu", "fr", "gd", "gl", + "hr", "is", "it", "lv", "lt", "hu", "nl", "nb", "pl", "pt_PT", "pt_BR", "ru", "ro", "sq", "sk", "sl", + "fi", "sv", "tr", "el", "be", "bg", "sr", "uk", "iw", "ar", "fa", "ml", "ko", "zh_CN", "zh_TW", "ja", + "fy", + ), + ) + + buildConfigField("String", "CLIENT_ID_APP_NAME", "\"K-9 Mail\"") + } + + signingConfigs { + if (project.hasProperty("k9mail.keyAlias") && + project.hasProperty("k9mail.keyPassword") && + project.hasProperty("k9mail.storeFile") && + project.hasProperty("k9mail.storePassword") + ) { + create("release") { + keyAlias = project.property("k9mail.keyAlias") as String + keyPassword = project.property("k9mail.keyPassword") as String + storeFile = file(project.property("k9mail.storeFile") as String) + storePassword = project.property("k9mail.storePassword") as String + } + } + } + + buildTypes { + release { + signingConfig = signingConfigs.findByName("release") + + isMinifyEnabled = true + proguardFiles( + getDefaultProguardFile("proguard-android.txt"), + "proguard-rules.pro", + ) + + buildConfigField( + "String", + "OAUTH_GMAIL_CLIENT_ID", + "\"262622259280-hhmh92rhklkg2k1tjil69epo0o9a12jm.apps.googleusercontent.com\"", + ) + buildConfigField( + "String", + "OAUTH_YAHOO_CLIENT_ID", + "\"dj0yJmk9aHNUb3d2MW5TQnpRJmQ9WVdrOWVYbHpaRWM0YkdnbWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PWIz\"", + ) + buildConfigField( + "String", + "OAUTH_AOL_CLIENT_ID", + "\"dj0yJmk9dUNqYXZhYWxOYkdRJmQ9WVdrOU1YQnZVRFZoY1ZrbWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PWIw\"", + ) + buildConfigField("String", "OAUTH_MICROSOFT_CLIENT_ID", "\"e647013a-ada4-4114-b419-e43d250f99c5\"") + buildConfigField( + "String", + "OAUTH_MICROSOFT_REDIRECT_URI", + "\"msauth://com.fsck.k9/Dx8yUsuhyU3dYYba1aA16Wxu5eM%3D\"", + ) + + manifestPlaceholders["appAuthRedirectScheme"] = "com.fsck.k9" + } + + debug { + applicationIdSuffix = ".debug" + enableUnitTestCoverage = testCoverageEnabled + enableAndroidTestCoverage = testCoverageEnabled + + isMinifyEnabled = false + + buildConfigField( + "String", + "OAUTH_GMAIL_CLIENT_ID", + "\"262622259280-5qb3vtj68d5dtudmaif4g9vd3cpar8r3.apps.googleusercontent.com\"", + ) + buildConfigField( + "String", + "OAUTH_YAHOO_CLIENT_ID", + "\"dj0yJmk9ejRCRU1ybmZjQlVBJmQ9WVdrOVVrZEViak4xYmxZbWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PTZj\"", + ) + buildConfigField( + "String", + "OAUTH_AOL_CLIENT_ID", + "\"dj0yJmk9cHYydkJkTUxHcXlYJmQ9WVdrOWVHZHhVVXN4VVV3bWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PTdm\"", + ) + buildConfigField("String", "OAUTH_MICROSOFT_CLIENT_ID", "\"e647013a-ada4-4114-b419-e43d250f99c5\"") + buildConfigField( + "String", + "OAUTH_MICROSOFT_REDIRECT_URI", + "\"msauth://com.fsck.k9.debug/VZF2DYuLYAu4TurFd6usQB2JPts%3D\"", + ) + + manifestPlaceholders["appAuthRedirectScheme"] = "com.fsck.k9.debug" + } + } + + packaging { + jniLibs { + excludes += listOf("kotlin/**") + } + + resources { + excludes += listOf( + "META-INF/*.kotlin_module", + "META-INF/*.version", + "kotlin/**", + "DebugProbesKt.bin", + ) + } + } +} + +dependencyGuard { + configuration("releaseRuntimeClasspath") +} diff --git a/app/k9mail/dependencies/releaseRuntimeClasspath.txt b/app-k9mail/dependencies/releaseRuntimeClasspath.txt similarity index 100% rename from app/k9mail/dependencies/releaseRuntimeClasspath.txt rename to app-k9mail/dependencies/releaseRuntimeClasspath.txt diff --git a/app/k9mail/proguard-rules.pro b/app-k9mail/proguard-rules.pro similarity index 100% rename from app/k9mail/proguard-rules.pro rename to app-k9mail/proguard-rules.pro diff --git a/app-k9mail/src/debug/java/app/k9mail/dev/DebugConfig.kt b/app-k9mail/src/debug/java/app/k9mail/dev/DebugConfig.kt new file mode 100644 index 000000000..90ffc4ed8 --- /dev/null +++ b/app-k9mail/src/debug/java/app/k9mail/dev/DebugConfig.kt @@ -0,0 +1,12 @@ +package app.k9mail.dev + +import com.fsck.k9.backend.BackendFactory +import org.koin.core.module.Module +import org.koin.core.qualifier.named + +fun Module.developmentModuleAdditions() { + single { DemoBackendFactory(backendStorageFactory = get()) } + single>(named("developmentBackends")) { + mapOf("demo" to get()) + } +} diff --git a/app/k9mail/src/debug/java/app/k9mail/dev/DemoBackendFactory.kt b/app-k9mail/src/debug/java/app/k9mail/dev/DemoBackendFactory.kt similarity index 100% rename from app/k9mail/src/debug/java/app/k9mail/dev/DemoBackendFactory.kt rename to app-k9mail/src/debug/java/app/k9mail/dev/DemoBackendFactory.kt diff --git a/app/k9mail/src/debug/res/values/app_logo_colors.xml b/app-k9mail/src/debug/res/values/app_logo_colors.xml similarity index 100% rename from app/k9mail/src/debug/res/values/app_logo_colors.xml rename to app-k9mail/src/debug/res/values/app_logo_colors.xml diff --git a/app-k9mail/src/main/AndroidManifest.xml b/app-k9mail/src/main/AndroidManifest.xml new file mode 100644 index 000000000..29a34f8ca --- /dev/null +++ b/app-k9mail/src/main/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/app-k9mail/src/main/kotlin/com/fsck/k9/K9App.kt b/app-k9mail/src/main/kotlin/com/fsck/k9/K9App.kt new file mode 100644 index 000000000..ee9e03e91 --- /dev/null +++ b/app-k9mail/src/main/kotlin/com/fsck/k9/K9App.kt @@ -0,0 +1,7 @@ +package com.fsck.k9 + +import org.koin.core.module.Module + +class K9App : CommonApp() { + override fun provideAppModule(): Module = appModule +} diff --git a/app-k9mail/src/main/kotlin/com/fsck/k9/K9KoinModule.kt b/app-k9mail/src/main/kotlin/com/fsck/k9/K9KoinModule.kt new file mode 100644 index 000000000..c81c5be40 --- /dev/null +++ b/app-k9mail/src/main/kotlin/com/fsck/k9/K9KoinModule.kt @@ -0,0 +1,29 @@ +package com.fsck.k9 + +import app.k9mail.core.common.oauth.OAuthConfigurationFactory +import app.k9mail.dev.developmentModuleAdditions +import com.fsck.k9.activity.LauncherShortcuts +import com.fsck.k9.activity.MessageCompose +import com.fsck.k9.auth.AppOAuthConfigurationFactory +import com.fsck.k9.provider.UnreadWidgetProvider +import com.fsck.k9.widget.list.MessageListWidgetProvider +import org.koin.core.qualifier.named +import org.koin.dsl.module + +val appModule = module { + single(named("ClientIdAppName")) { BuildConfig.CLIENT_ID_APP_NAME } + single(named("ClientIdAppVersion")) { BuildConfig.VERSION_NAME } + single { appConfig } + single { AppOAuthConfigurationFactory() } + + developmentModuleAdditions() +} + +val appConfig = AppConfig( + componentsToDisable = listOf( + MessageCompose::class.java, + LauncherShortcuts::class.java, + UnreadWidgetProvider::class.java, + MessageListWidgetProvider::class.java, + ), +) diff --git a/app/k9mail/src/main/java/com/fsck/k9/auth/AppOAuthConfigurationFactory.kt b/app-k9mail/src/main/kotlin/com/fsck/k9/auth/AppOAuthConfigurationFactory.kt similarity index 100% rename from app/k9mail/src/main/java/com/fsck/k9/auth/AppOAuthConfigurationFactory.kt rename to app-k9mail/src/main/kotlin/com/fsck/k9/auth/AppOAuthConfigurationFactory.kt diff --git a/app-k9mail/src/main/res/drawable/ic_app_logo.xml b/app-k9mail/src/main/res/drawable/ic_app_logo.xml new file mode 100644 index 000000000..2977664bf --- /dev/null +++ b/app-k9mail/src/main/res/drawable/ic_app_logo.xml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app-k9mail/src/main/res/values/drawables.xml b/app-k9mail/src/main/res/values/drawables.xml new file mode 100644 index 000000000..f5a91e6d5 --- /dev/null +++ b/app-k9mail/src/main/res/values/drawables.xml @@ -0,0 +1,4 @@ + + + @drawable/ic_app_logo + diff --git a/app-k9mail/src/main/res/values/strings.xml b/app-k9mail/src/main/res/values/strings.xml new file mode 100644 index 000000000..b142c3250 --- /dev/null +++ b/app-k9mail/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + + + K-9 Mail + diff --git a/app/k9mail/src/release/java/app/k9mail/dev/ReleaseConfig.kt b/app-k9mail/src/release/java/app/k9mail/dev/ReleaseConfig.kt similarity index 52% rename from app/k9mail/src/release/java/app/k9mail/dev/ReleaseConfig.kt rename to app-k9mail/src/release/java/app/k9mail/dev/ReleaseConfig.kt index 054e735a8..d368a418f 100644 --- a/app/k9mail/src/release/java/app/k9mail/dev/ReleaseConfig.kt +++ b/app-k9mail/src/release/java/app/k9mail/dev/ReleaseConfig.kt @@ -2,10 +2,10 @@ package app.k9mail.dev import com.fsck.k9.backend.BackendFactory import org.koin.core.module.Module -import org.koin.core.scope.Scope - -fun Scope.developmentBackends() = emptyMap() +import org.koin.core.qualifier.named fun Module.developmentModuleAdditions() { - // No-op + single>(named("developmentBackends")) { + emptyMap() + } } diff --git a/app/k9mail/build.gradle.kts b/app/k9mail/build.gradle.kts index 1e3a3f1a8..cc0ff03ec 100644 --- a/app/k9mail/build.gradle.kts +++ b/app/k9mail/build.gradle.kts @@ -1,11 +1,5 @@ plugins { - id(ThunderbirdPlugins.App.android) - alias(libs.plugins.dependency.guard) -} - -val testCoverageEnabled: Boolean by extra -if (testCoverageEnabled) { - apply(plugin = "jacoco") + id(ThunderbirdPlugins.Library.android) } dependencies { @@ -16,7 +10,6 @@ dependencies { implementation(projects.app.cryptoOpenpgp) implementation(projects.backend.imap) implementation(projects.backend.pop3) - debugImplementation(projects.backend.demo) implementation(projects.core.featureflags) implementation(projects.feature.launcher) @@ -45,127 +38,14 @@ dependencies { } android { - namespace = "com.fsck.k9" - - defaultConfig { - applicationId = "com.fsck.k9" - testApplicationId = "com.fsck.k9.tests" - - versionCode = 37014 - versionName = "6.715-SNAPSHOT" - - // Keep in sync with the resource string array "supported_languages" - resourceConfigurations.addAll( - listOf( - "in", "br", "ca", "cs", "cy", "da", "de", "et", "en", "en_GB", "es", "eo", "eu", "fr", "gd", "gl", - "hr", "is", "it", "lv", "lt", "hu", "nl", "nb", "pl", "pt_PT", "pt_BR", "ru", "ro", "sq", "sk", "sl", - "fi", "sv", "tr", "el", "be", "bg", "sr", "uk", "iw", "ar", "fa", "ml", "ko", "zh_CN", "zh_TW", "ja", - "fy", - ), - ) - - buildConfigField("String", "CLIENT_ID_APP_NAME", "\"K-9 Mail\"") - } - - signingConfigs { - if (project.hasProperty("k9mail.keyAlias") && - project.hasProperty("k9mail.keyPassword") && - project.hasProperty("k9mail.storeFile") && - project.hasProperty("k9mail.storePassword") - ) { - create("release") { - keyAlias = project.property("k9mail.keyAlias") as String - keyPassword = project.property("k9mail.keyPassword") as String - storeFile = file(project.property("k9mail.storeFile") as String) - storePassword = project.property("k9mail.storePassword") as String - } - } - } + namespace = "com.fsck.k9.common" buildTypes { - release { - signingConfig = signingConfigs.findByName("release") - - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android.txt"), - "proguard-rules.pro", - ) - - buildConfigField( - "String", - "OAUTH_GMAIL_CLIENT_ID", - "\"262622259280-hhmh92rhklkg2k1tjil69epo0o9a12jm.apps.googleusercontent.com\"", - ) - buildConfigField( - "String", - "OAUTH_YAHOO_CLIENT_ID", - "\"dj0yJmk9aHNUb3d2MW5TQnpRJmQ9WVdrOWVYbHpaRWM0YkdnbWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PWIz\"", - ) - buildConfigField( - "String", - "OAUTH_AOL_CLIENT_ID", - "\"dj0yJmk9dUNqYXZhYWxOYkdRJmQ9WVdrOU1YQnZVRFZoY1ZrbWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PWIw\"", - ) - buildConfigField("String", "OAUTH_MICROSOFT_CLIENT_ID", "\"e647013a-ada4-4114-b419-e43d250f99c5\"") - buildConfigField( - "String", - "OAUTH_MICROSOFT_REDIRECT_URI", - "\"msauth://com.fsck.k9/Dx8yUsuhyU3dYYba1aA16Wxu5eM%3D\"", - ) - - manifestPlaceholders["appAuthRedirectScheme"] = "com.fsck.k9" - } - debug { - applicationIdSuffix = ".debug" - enableUnitTestCoverage = testCoverageEnabled - enableAndroidTestCoverage = testCoverageEnabled - - isMinifyEnabled = false - - buildConfigField( - "String", - "OAUTH_GMAIL_CLIENT_ID", - "\"262622259280-5qb3vtj68d5dtudmaif4g9vd3cpar8r3.apps.googleusercontent.com\"", - ) - buildConfigField( - "String", - "OAUTH_YAHOO_CLIENT_ID", - "\"dj0yJmk9ejRCRU1ybmZjQlVBJmQ9WVdrOVVrZEViak4xYmxZbWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PTZj\"", - ) - buildConfigField( - "String", - "OAUTH_AOL_CLIENT_ID", - "\"dj0yJmk9cHYydkJkTUxHcXlYJmQ9WVdrOWVHZHhVVXN4VVV3bWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PTdm\"", - ) - buildConfigField("String", "OAUTH_MICROSOFT_CLIENT_ID", "\"e647013a-ada4-4114-b419-e43d250f99c5\"") - buildConfigField( - "String", - "OAUTH_MICROSOFT_REDIRECT_URI", - "\"msauth://com.fsck.k9.debug/VZF2DYuLYAu4TurFd6usQB2JPts%3D\"", - ) - - manifestPlaceholders["appAuthRedirectScheme"] = "com.fsck.k9.debug" + manifestPlaceholders["appAuthRedirectScheme"] = "FIXME: override this in your app project" } - } - - packaging { - jniLibs { - excludes += listOf("kotlin/**") - } - - resources { - excludes += listOf( - "META-INF/*.kotlin_module", - "META-INF/*.version", - "kotlin/**", - "DebugProbesKt.bin", - ) + release { + manifestPlaceholders["appAuthRedirectScheme"] = "FIXME: override this in your app project" } } } - -dependencyGuard { - configuration("releaseRuntimeClasspath") -} diff --git a/app/k9mail/src/debug/java/app/k9mail/dev/DebugConfig.kt b/app/k9mail/src/debug/java/app/k9mail/dev/DebugConfig.kt deleted file mode 100644 index c8380082c..000000000 --- a/app/k9mail/src/debug/java/app/k9mail/dev/DebugConfig.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.k9mail.dev - -import org.koin.core.module.Module -import org.koin.core.scope.Scope - -fun Scope.developmentBackends() = mapOf( - "demo" to get(), -) - -fun Module.developmentModuleAdditions() { - single { DemoBackendFactory(backendStorageFactory = get()) } -} diff --git a/app/k9mail/src/main/AndroidManifest.xml b/app/k9mail/src/main/AndroidManifest.xml index d7ee7ccb8..8170338db 100644 --- a/app/k9mail/src/main/AndroidManifest.xml +++ b/app/k9mail/src/main/AndroidManifest.xml @@ -1,33 +1,31 @@ - + android:required="false" /> + android:smallScreens="true" /> - - + + - - - - - - - - + + + + + + + + + android:value="com.fsck.k9.activity.Search" /> + android:value="true" /> + android:required="false" /> + + android:value="true" /> - + + android:theme="@style/Theme.K9.Dialog.Translucent.DayNight" /> + android:label="@string/account_settings_composition_title" /> + android:label="@string/manage_identities_title" /> + android:label="@string/edit_identity_title" /> + android:theme="@style/Theme.K9.Dialog.Translucent.DayNight" /> + android:label="@string/ac_transfer_title" /> - + - - - + + + - - + + - + - + android:scheme="k9mail" /> + @@ -140,107 +138,107 @@ This component is disabled by default. It will be enabled programmatically after an account has been set up. --> - - - + + + - - - + + + - - - + + + - - + + - - + + - - + + - - + + + android:resource="@xml/searchable" /> - - + + - + + android:name="com.fsck.k9.activity.UpgradeDatabases" + android:label="@string/upgrade_databases_title" /> - + + android:resource="@xml/unread_widget_info" /> - + - + + android:name="com.fsck.k9.service.DatabaseUpgradeService" + android:exported="false" /> @@ -320,7 +317,7 @@ @@ -331,7 +328,7 @@ @@ -342,7 +339,7 @@ @@ -363,7 +360,9 @@ - + diff --git a/app/k9mail/src/main/java/com/fsck/k9/App.kt b/app/k9mail/src/main/java/com/fsck/k9/CommonApp.kt similarity index 88% rename from app/k9mail/src/main/java/com/fsck/k9/App.kt rename to app/k9mail/src/main/java/com/fsck/k9/CommonApp.kt index 516d7ebdc..e721dc1fa 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/App.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/CommonApp.kt @@ -4,16 +4,12 @@ import android.app.Application import android.content.res.Configuration import android.content.res.Resources import app.k9mail.ui.widget.list.MessageListWidgetManager -import com.fsck.k9.activity.LauncherShortcuts -import com.fsck.k9.activity.MessageCompose import com.fsck.k9.controller.MessagingController import com.fsck.k9.job.WorkManagerConfigurationProvider import com.fsck.k9.notification.NotificationChannelManager -import com.fsck.k9.provider.UnreadWidgetProvider import com.fsck.k9.ui.base.AppLanguageManager import com.fsck.k9.ui.base.ThemeManager import com.fsck.k9.ui.base.extensions.currentLocale -import com.fsck.k9.widget.list.MessageListWidgetProvider import java.util.Locale import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -24,10 +20,11 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.plus import org.koin.android.ext.android.inject +import org.koin.core.module.Module import timber.log.Timber import androidx.work.Configuration as WorkManagerConfiguration -class App : Application(), WorkManagerConfiguration.Provider { +abstract class CommonApp : Application(), WorkManagerConfiguration.Provider { private val messagingController: MessagingController by inject() private val messagingListenerProvider: MessagingListenerProvider by inject() private val themeManager: ThemeManager by inject() @@ -44,7 +41,7 @@ class App : Application(), WorkManagerConfiguration.Provider { super.onCreate() - DI.start(this, coreModules + uiModules + appModules) + DI.start(this, listOf(provideAppModule()) + coreModules + uiModules + commonAppModules) K9.init(this) Core.init(this) @@ -58,6 +55,8 @@ class App : Application(), WorkManagerConfiguration.Provider { } } + abstract fun provideAppModule(): Module + private fun initializeAppLanguage() { appLanguageManager.init() applyOverrideLocaleToConfiguration() @@ -130,15 +129,4 @@ class App : Application(), WorkManagerConfiguration.Provider { override val workManagerConfiguration: WorkManagerConfiguration get() = workManagerConfigurationProvider.getConfiguration() - - companion object { - val appConfig = AppConfig( - componentsToDisable = listOf( - MessageCompose::class.java, - LauncherShortcuts::class.java, - UnreadWidgetProvider::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/CommonKoinModule.kt similarity index 86% rename from app/k9mail/src/main/java/com/fsck/k9/Dependencies.kt rename to app/k9mail/src/main/java/com/fsck/k9/CommonKoinModule.kt index f2af6f00f..03c797d96 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/Dependencies.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/CommonKoinModule.kt @@ -1,12 +1,10 @@ package com.fsck.k9 -import app.k9mail.core.common.oauth.OAuthConfigurationFactory import app.k9mail.core.featureflag.FeatureFlagFactory import app.k9mail.core.featureflag.FeatureFlagProvider import app.k9mail.core.featureflag.InMemoryFeatureFlagProvider import app.k9mail.ui.widget.list.messageListWidgetModule import com.fsck.k9.account.newAccountModule -import com.fsck.k9.auth.AppOAuthConfigurationFactory import com.fsck.k9.backends.backendsModule import com.fsck.k9.controller.ControllerExtension import com.fsck.k9.crypto.EncryptionExtractor @@ -24,8 +22,7 @@ import com.fsck.k9.widget.unread.unreadWidgetModule import org.koin.core.qualifier.named import org.koin.dsl.module -private val mainAppModule = module { - single { App.appConfig } +val commonAppModule = module { single { MessagingListenerProvider( listOf( @@ -36,7 +33,6 @@ private val mainAppModule = module { single(named("controllerExtensions")) { emptyList() } single { OpenPgpEncryptionExtractor.newInstance() } single { K9StoragePersister(get()) } - single { AppOAuthConfigurationFactory() } single { InMemoryFeatureFlagFactory() } single { InMemoryFeatureFlagProvider( @@ -45,8 +41,8 @@ private val mainAppModule = module { } } -val appModules = listOf( - mainAppModule, +val commonAppModules = listOf( + commonAppModule, messageListWidgetConfigModule, messageListWidgetModule, unreadWidgetModule, diff --git a/app/k9mail/src/main/java/com/fsck/k9/backends/KoinModule.kt b/app/k9mail/src/main/java/com/fsck/k9/backends/KoinModule.kt index aff40d036..652db05a0 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/backends/KoinModule.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/backends/KoinModule.kt @@ -1,8 +1,6 @@ package com.fsck.k9.backends -import app.k9mail.dev.developmentBackends -import app.k9mail.dev.developmentModuleAdditions -import com.fsck.k9.BuildConfig +import com.fsck.k9.backend.BackendFactory import com.fsck.k9.backend.BackendManager import com.fsck.k9.backend.imap.BackendIdleRefreshManager import com.fsck.k9.backend.imap.SystemAlarmManager @@ -13,11 +11,12 @@ import org.koin.dsl.module val backendsModule = module { single { + val developmentBackends = get>(named("developmentBackends")) BackendManager( mapOf( "imap" to get(), "pop3" to get(), - ) + developmentBackends(), + ) + developmentBackends, ) } single { @@ -35,9 +34,5 @@ val backendsModule = module { single { AndroidAlarmManager(context = get(), alarmManager = get()) } single { BackendIdleRefreshManager(alarmManager = get()) } single { Pop3BackendFactory(get(), get()) } - single(named("ClientIdAppName")) { BuildConfig.CLIENT_ID_APP_NAME } - single(named("ClientIdAppVersion")) { BuildConfig.VERSION_NAME } single { RealOAuth2TokenProviderFactory(context = get()) } - - developmentModuleAdditions() } diff --git a/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt b/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt index da65f22c7..67884db7f 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt @@ -1,7 +1,6 @@ package com.fsck.k9.backends import android.content.Context -import com.fsck.k9.BuildConfig import com.fsck.k9.mail.AuthenticationFailedException import com.fsck.k9.mail.oauth.AuthStateStorage import com.fsck.k9.mail.oauth.OAuth2TokenProvider @@ -18,6 +17,7 @@ import timber.log.Timber class RealOAuth2TokenProvider( context: Context, private val authStateStorage: AuthStateStorage, + ) : OAuth2TokenProvider { private val authService = AuthorizationService(context) private var requestFreshToken = false @@ -49,11 +49,6 @@ class RealOAuth2TokenProvider( latch.await(timeoutMillis, TimeUnit.MILLISECONDS) } catch (e: Exception) { - // OAuth errors are communicated via the callback. If we end up here, it's probably a programming error. - if (BuildConfig.DEBUG) { - throw AssertionError("Wrong usage of AuthState.performActionWithFreshTokens()?", e) - } - Timber.w(e, "Failed to fetch an access token. Clearing authorization state.") authStateStorage.updateAuthorizationState(authorizationState = null) diff --git a/app/k9mail/src/main/java/com/fsck/k9/provider/UnreadWidgetProvider.kt b/app/k9mail/src/main/java/com/fsck/k9/provider/UnreadWidgetProvider.kt index c2b4b404a..1affe7e9d 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/provider/UnreadWidgetProvider.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/provider/UnreadWidgetProvider.kt @@ -9,7 +9,7 @@ import android.content.Intent import android.view.View import android.widget.RemoteViews import com.fsck.k9.EarlyInit -import com.fsck.k9.R +import com.fsck.k9.common.R import com.fsck.k9.helper.PendingIntentCompat.FLAG_MUTABLE import com.fsck.k9.inject import com.fsck.k9.widget.unread.UnreadWidgetConfigurationActivity diff --git a/app/k9mail/src/main/java/com/fsck/k9/widget/unread/UnreadWidgetConfigurationActivity.kt b/app/k9mail/src/main/java/com/fsck/k9/widget/unread/UnreadWidgetConfigurationActivity.kt index fa1662b0d..a8d65cffa 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/widget/unread/UnreadWidgetConfigurationActivity.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/widget/unread/UnreadWidgetConfigurationActivity.kt @@ -2,7 +2,7 @@ package com.fsck.k9.widget.unread import android.appwidget.AppWidgetManager import android.os.Bundle -import com.fsck.k9.R +import com.fsck.k9.common.R import com.fsck.k9.ui.base.K9Activity import com.fsck.k9.ui.fragmentTransaction import timber.log.Timber diff --git a/app/k9mail/src/main/java/com/fsck/k9/widget/unread/UnreadWidgetConfigurationFragment.kt b/app/k9mail/src/main/java/com/fsck/k9/widget/unread/UnreadWidgetConfigurationFragment.kt index 738783587..fd4015ba9 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/widget/unread/UnreadWidgetConfigurationFragment.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/widget/unread/UnreadWidgetConfigurationFragment.kt @@ -12,8 +12,8 @@ import androidx.core.os.bundleOf import androidx.preference.CheckBoxPreference import androidx.preference.Preference import com.fsck.k9.Preferences -import com.fsck.k9.R import com.fsck.k9.activity.ChooseAccount +import com.fsck.k9.common.R import com.fsck.k9.search.SearchAccount import com.fsck.k9.ui.choosefolder.ChooseFolderActivity import com.takisoft.preferencex.PreferenceFragmentCompat @@ -98,6 +98,7 @@ class UnreadWidgetConfigurationFragment : PreferenceFragmentCompat() { val accountUuid = data.getStringExtra(ChooseAccount.EXTRA_ACCOUNT_UUID)!! handleChooseAccount(accountUuid) } + REQUEST_CHOOSE_FOLDER -> { val folderId = data.getLongExtra(ChooseFolderActivity.RESULT_SELECTED_FOLDER_ID, -1L) val folderDisplayName = data.getStringExtra(ChooseFolderActivity.RESULT_FOLDER_DISPLAY_NAME)!! @@ -163,6 +164,7 @@ class UnreadWidgetConfigurationFragment : PreferenceFragmentCompat() { } true } + else -> super.onOptionsItemSelected(item) } } diff --git a/app/k9mail/src/test/java/com/fsck/k9/AppRobolectricTest.kt b/app/k9mail/src/test/java/com/fsck/k9/AppRobolectricTest.kt deleted file mode 100644 index 1739d41d8..000000000 --- a/app/k9mail/src/test/java/com/fsck/k9/AppRobolectricTest.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.fsck.k9 - -import android.app.Application -import org.junit.runner.RunWith -import org.koin.test.AutoCloseKoinTest -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config - -/** - * A Robolectric test that creates an instance of our [Application] class [App]. - */ -@RunWith(RobolectricTestRunner::class) -@Config(application = App::class) -abstract class AppRobolectricTest : AutoCloseKoinTest() 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 005a826be..a96e0badb 100644 --- a/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt +++ b/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt @@ -32,7 +32,7 @@ import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) -@Config(application = App::class) +@Config(application = TestApp::class) class DependencyInjectionTest : AutoCloseKoinTest() { private val lifecycleOwner = mock { on { lifecycle } doReturn mock() diff --git a/app/k9mail/src/test/java/com/fsck/k9/TestApp.kt b/app/k9mail/src/test/java/com/fsck/k9/TestApp.kt new file mode 100644 index 000000000..c428952d7 --- /dev/null +++ b/app/k9mail/src/test/java/com/fsck/k9/TestApp.kt @@ -0,0 +1,25 @@ +package com.fsck.k9 + +import app.k9mail.core.common.oauth.OAuthConfigurationFactory +import com.fsck.k9.backend.BackendFactory +import org.koin.core.module.Module +import org.koin.core.qualifier.named +import org.koin.dsl.module + +class TestApp : CommonApp() { + override fun provideAppModule(): Module = module { + single(named("ClientIdAppName")) { "ClientIdAppName" } + single(named("ClientIdAppVersion")) { "ClientIdAppVersion" } + single { + AppConfig( + componentsToDisable = emptyList(), + ) + } + single>(named("developmentBackends")) { + emptyMap() + } + single { + OAuthConfigurationFactory { emptyMap() } + } + } +} 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 e7a463567..12a022849 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 @@ -5,8 +5,8 @@ import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.isNull import com.fsck.k9.Account -import com.fsck.k9.AppRobolectricTest import com.fsck.k9.Preferences +import com.fsck.k9.TestApp import com.fsck.k9.controller.MessageCounts import com.fsck.k9.controller.MessageCountsProvider import com.fsck.k9.mailstore.Folder @@ -16,11 +16,17 @@ import com.fsck.k9.search.SearchAccount import com.fsck.k9.ui.folders.FolderNameFormatter import com.fsck.k9.ui.messagelist.DefaultFolderProvider import org.junit.Test +import org.junit.runner.RunWith +import org.koin.test.AutoCloseKoinTest import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock +import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.Config -class UnreadWidgetDataProviderTest : AppRobolectricTest() { +@RunWith(RobolectricTestRunner::class) +@Config(application = TestApp::class) +class UnreadWidgetDataProviderTest : AutoCloseKoinTest() { private val context: Context = RuntimeEnvironment.getApplication() private val account = createAccount() private val preferences = createPreferences() diff --git a/settings.gradle.kts b/settings.gradle.kts index fd2f962db..518823938 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,6 +21,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") rootProject.name = "k-9" include( + ":app-k9mail", ":app-feature-preview", ":app-ui-catalog", )