diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index 166b54907f..148a1eab61 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -37,7 +37,7 @@ kotlin { } dependencies { - compileOnly(libs.android.gradleApiPlugin) + compileOnly(libs.android.gradlePlugin) compileOnly(libs.android.tools.common) compileOnly(libs.compose.gradlePlugin) compileOnly(libs.firebase.crashlytics.gradlePlugin) diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt index f45d664b7a..e952a8f5c7 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -15,6 +15,7 @@ */ import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.dsl.CommonExtension import com.android.build.api.variant.ApplicationAndroidComponentsExtension import com.google.samples.apps.nowinandroid.configureBadgingTasks import com.google.samples.apps.nowinandroid.configureGradleManagedDevices @@ -30,7 +31,6 @@ class AndroidApplicationConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { apply(plugin = "com.android.application") - apply(plugin = "org.jetbrains.kotlin.android") apply(plugin = "nowinandroid.android.lint") apply(plugin = "com.dropbox.dependency-guard") @@ -43,7 +43,7 @@ class AndroidApplicationConventionPlugin : Plugin { } extensions.configure { configurePrintApksTask(this) - configureBadgingTasks(extensions.getByType(), this) + configureBadgingTasks(extensions.getByType(), this) } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt index b0eece41da..326d03f4f1 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt @@ -21,20 +21,16 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.getByType +import org.gradle.testing.jacoco.plugins.JacocoPlugin class AndroidApplicationJacocoConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - apply(plugin = "jacoco") - - val androidExtension = extensions.getByType() - - androidExtension.buildTypes.configureEach { - enableAndroidTestCoverage = true - enableUnitTestCoverage = true - } - - configureJacoco(extensions.getByType()) + apply() + configureJacoco( + commonExtension = extensions.getByType(), + androidComponentsExtension = extensions.getByType(), + ) } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index 0f6fde8848..17c4379e7b 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -32,12 +32,10 @@ class AndroidLibraryConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { apply(plugin = "com.android.library") - apply(plugin = "org.jetbrains.kotlin.android") apply(plugin = "nowinandroid.android.lint") extensions.configure { configureKotlinAndroid(this) - testOptions.targetSdk = 35 lint.targetSdk = 35 defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testOptions.animationsDisabled = true @@ -56,6 +54,7 @@ class AndroidLibraryConventionPlugin : Plugin { dependencies { "androidTestImplementation"(libs.findLibrary("kotlin.test").get()) "testImplementation"(libs.findLibrary("kotlin.test").get()) + "testImplementation"(libs.findLibrary("junit").get()) "implementation"(libs.findLibrary("androidx.tracing.ktx").get()) } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt index d249e4cbf1..2fd97d4566 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt @@ -21,20 +21,16 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.getByType +import org.gradle.testing.jacoco.plugins.JacocoPlugin class AndroidLibraryJacocoConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - apply(plugin = "jacoco") - - val androidExtension = extensions.getByType() - - androidExtension.buildTypes.configureEach { - enableAndroidTestCoverage = true - enableUnitTestCoverage = true - } - - configureJacoco(extensions.getByType()) + apply() + configureJacoco( + commonExtension = extensions.getByType(), + androidComponentsExtension = extensions.getByType(), + ) } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt index 49c2eececa..ddfd03e241 100644 --- a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt @@ -26,7 +26,6 @@ class AndroidTestConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { apply(plugin = "com.android.test") - apply(plugin = "org.jetbrains.kotlin.android") extensions.configure { configureKotlinAndroid(this) diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt index 3d050d86b6..f018cbfc52 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt @@ -28,10 +28,10 @@ import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginE * Configure Compose-specific options */ internal fun Project.configureAndroidCompose( - commonExtension: CommonExtension<*, *, *, *, *, *>, + commonExtension: CommonExtension, ) { commonExtension.apply { - buildFeatures { + buildFeatures.apply { compose = true } diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Badging.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Badging.kt index 2293880013..ea6f83a833 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Badging.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Badging.kt @@ -18,7 +18,7 @@ package com.google.samples.apps.nowinandroid import com.android.SdkConstants import com.android.build.api.artifact.SingleArtifact -import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.dsl.CommonExtension import com.android.build.api.variant.ApplicationAndroidComponentsExtension import com.google.common.truth.Truth.assertWithMessage import org.gradle.api.DefaultTask @@ -110,7 +110,7 @@ private fun String.capitalized() = replaceFirstChar { } fun Project.configureBadgingTasks( - baseExtension: ApplicationExtension, + baseExtension: CommonExtension, componentsExtension: ApplicationAndroidComponentsExtension, ) { // Registers a callback to be called, when a new variant is configured diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/GradleManagedDevices.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/GradleManagedDevices.kt index f67e9093dc..310d90d81b 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/GradleManagedDevices.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/GradleManagedDevices.kt @@ -25,7 +25,7 @@ import org.gradle.kotlin.dsl.invoke * Configure project for Gradle managed devices */ internal fun configureGradleManagedDevices( - commonExtension: CommonExtension<*, *, *, *, *, *>, + commonExtension: CommonExtension, ) { val pixel4 = DeviceConfig("Pixel 4", 30, "aosp-atd") val pixel6 = DeviceConfig("Pixel 6", 31, "aosp") @@ -34,9 +34,10 @@ internal fun configureGradleManagedDevices( val allDevices = listOf(pixel4, pixel6, pixelC) val ciDevices = listOf(pixel4, pixelC) - commonExtension.testOptions { + + commonExtension.testOptions.apply { managedDevices { - devices { + allDevices { allDevices.forEach { deviceConfig -> maybeCreate(deviceConfig.taskName, ManagedVirtualDevice::class.java).apply { device = deviceConfig.device @@ -48,7 +49,7 @@ internal fun configureGradleManagedDevices( groups { maybeCreate("ci").apply { ciDevices.forEach { deviceConfig -> - targetDevices.add(devices[deviceConfig.taskName]) + targetDevices.add(localDevices[deviceConfig.taskName]) } } } diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt index ed1ea42541..8d16c428ed 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt @@ -17,9 +17,12 @@ package com.google.samples.apps.nowinandroid import com.android.build.api.artifact.ScopedArtifact +import com.android.build.api.dsl.BuildType +import com.android.build.api.dsl.CommonExtension import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.ScopedArtifacts import com.android.build.api.variant.SourceDirectories +import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.file.Directory import org.gradle.api.file.RegularFile @@ -59,8 +62,15 @@ private fun String.capitalize() = replaceFirstChar { * tests on CI using a different Github Action or an external device farm. */ internal fun Project.configureJacoco( + commonExtension: CommonExtension, androidComponentsExtension: AndroidComponentsExtension<*, *, *>, ) { + // Configure only the debug build, otherwise it will force the debuggable flag on release buildTypes as well + commonExtension.buildTypes.named("debug") { + enableAndroidTestCoverage = true + enableUnitTestCoverage = true + } + configure { toolVersion = libs.findVersion("jacoco").get().toString() } diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt index 2ac96e556b..a923ce24eb 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt @@ -32,16 +32,16 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension * Configure base Kotlin with Android options */ internal fun Project.configureKotlinAndroid( - commonExtension: CommonExtension<*, *, *, *, *, *>, + commonExtension: CommonExtension, ) { commonExtension.apply { compileSdk = 35 - defaultConfig { + defaultConfig.apply { minSdk = 23 } - compileOptions { + compileOptions.apply { // Up to Java 11 APIs are available through desugaring // https://developer.android.com/studio/write/java11-minimal-support-table sourceCompatibility = JavaVersion.VERSION_11 diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/NiaFlavor.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/NiaFlavor.kt index f57e634ccb..9fbf0625ce 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/NiaFlavor.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/NiaFlavor.kt @@ -20,7 +20,7 @@ enum class NiaFlavor(val dimension: FlavorDimension, val applicationIdSuffix: St } fun configureFlavors( - commonExtension: CommonExtension<*, *, *, *, *, *>, + commonExtension: CommonExtension, flavorConfigurationBlock: ProductFlavor.(flavor: NiaFlavor) -> Unit = {}, ) { commonExtension.apply { @@ -28,7 +28,7 @@ fun configureFlavors( flavorDimensions += flavorDimension.name } - productFlavors { + productFlavors.apply { NiaFlavor.values().forEach { niaFlavor -> register(niaFlavor.name) { dimension = niaFlavor.dimension.name diff --git a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt index 8e0d7d4d89..ac9eaf7672 100644 --- a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt +++ b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt @@ -41,7 +41,7 @@ object DataStoreModule { @Provides @Singleton - internal fun providesUserPreferencesDataStore( + fun providesUserPreferencesDataStore( @ApplicationContext context: Context, @Dispatcher(IO) ioDispatcher: CoroutineDispatcher, @ApplicationScope scope: CoroutineScope, diff --git a/gradle.properties b/gradle.properties index 2e9d9fc306..b941705081 100644 --- a/gradle.properties +++ b/gradle.properties @@ -63,3 +63,5 @@ roborazzi.test.verify=true # Prevent uninstall app after instrumented tests # https://issuetracker.google.com/issues/295039976 android.injected.androidTest.leaveApksInstalledAfterRun=true + +android.newDsl=false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0a6132d7d9..4a11407a3e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,8 +2,8 @@ accompanist = "0.37.0" androidDesugarJdkLibs = "2.1.4" # AGP and tools should be updated together -androidGradlePlugin = "8.13.1" -androidTools = "31.13.1" +androidGradlePlugin = "9.0.0-beta02" +androidTools = "32.0.0-beta02" androidxActivity = "1.9.3" androidxAppCompat = "1.7.0" androidxBrowser = "1.8.0" @@ -124,6 +124,7 @@ hilt-core = { group = "com.google.dagger", name = "hilt-core", version.ref = "hi hilt-ext-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "hiltExt" } hilt-ext-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "hiltExt" } javax-inject = { module = "javax.inject:javax.inject", version = "1" } +junit = { module = "junit:junit", version.ref = "junit4" } kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" } kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test", version.ref = "kotlin" } kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" } @@ -150,7 +151,7 @@ truth = { group = "com.google.truth", name = "truth", version.ref = "truth" } turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine" } # Dependencies of the included build-logic -android-gradleApiPlugin = { group = "com.android.tools.build", name = "gradle-api", version.ref = "androidGradlePlugin" } +android-gradlePlugin = { group = "com.android.tools.build", name = "gradle-api", version.ref = "androidGradlePlugin" } android-tools-common = { group = "com.android.tools", name = "common", version.ref = "androidTools" } compose-gradlePlugin = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" } firebase-crashlytics-gradlePlugin = { group = "com.google.firebase", name = "firebase-crashlytics-gradle", version.ref = "firebaseCrashlyticsPlugin" } diff --git a/sync/work/src/prod/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt b/sync/work/src/prod/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt index ceeb395486..97de27867a 100644 --- a/sync/work/src/prod/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt +++ b/sync/work/src/prod/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt @@ -43,9 +43,9 @@ abstract class SyncModule { syncSubscriber: FirebaseSyncSubscriber, ): SyncSubscriber - companion object { + internal companion object { @Provides @Singleton - internal fun provideFirebaseMessaging(): FirebaseMessaging = Firebase.messaging + fun provideFirebaseMessaging(): FirebaseMessaging = Firebase.messaging } }