fix(deps): update android.gradle.plugin to v9 (major) (#6021)

* Update android.gradle.plugin to v9

* Separate extensions between app and library ones

`CommonExtension` has been split and its properties are now duplicated in `ApplicationExtension` and `LibraryExtension` without a shared interface, so we now need to duplicate the helper extension functions

* Bump Gradle wrapper to `9.3.1`

* Remove `kotlin-android` plugin usage: it's no longer needed

* Enable `resValues` build feature for the modules that have resources in custom variants like gplay, debug, etc.

Otherwise this now fails saying the resources are there but the feature is disabled

* Remove `retrofit` dependency from `:features:call:impl`

It wasn't in use and the build was failing

* Update kotlin to v2.4.0

* Update plugin paparazzi to v2.0.0-alpha05

* Update gradle wrapper to 9.5.1

./gradlew wrapper --gradle-version 9.5.1 --gradle-distribution-sha256-sum bafc141b619ad6350fd975fc903156dd5c151998cc8b058e8c1044ab5f7b031f

* Update com.android.tools.build:gradle to 9.2.1

* Update plugin sonarqube to v7.3.1.8318

* Kotlin 2.4.0

* Context parameters are enabled by default in Kotlin 2.4.0

* Fix code issue

* Fix record screenshot issue

* Workaround for https://github.com/cashapp/paparazzi/issues/2342

* Workaround for another issue with Paparazzi

* Remove unused import

* Update screenshots

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
Co-authored-by: Benoit Marty <benoitm@element.io>
Co-authored-by: Benoit Marty <benoit@matrix.org>
Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
renovate[bot]
2026-06-11 09:51:47 +02:00
committed by GitHub
parent 37fed3e8fe
commit f0a6cba6db
165 changed files with 464 additions and 365 deletions
+1 -1
View File
@@ -2,6 +2,6 @@
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="externalSystemId" value="Gradle" />
<option name="version" value="2.3.21" />
<option name="version" value="2.4.0" />
</component>
</project>
+1 -1
View File
@@ -28,7 +28,6 @@ import java.util.Locale
plugins {
id("io.element.android-compose-application")
alias(libs.plugins.kotlin.android)
// When using precompiled plugins, we need to apply the firebase plugin like this
id(libs.plugins.firebaseAppDistribution.get().pluginId)
id("kotlin-parcelize")
@@ -189,6 +188,7 @@ android {
buildFeatures {
buildConfig = true
resValues = true
}
flavorDimensions += "store"
productFlavors {
-2
View File
@@ -106,8 +106,6 @@ allprojects {
// Fix compilation warning for annotations
// See https://youtrack.jetbrains.com/issue/KT-73255/Change-defaulting-rule-for-annotations for more details
freeCompilerArgs.add("-Xannotation-default-target=first-only")
// Opt-in to context receivers
freeCompilerArgs.add("-Xcontext-parameters")
}
}
}
-1
View File
@@ -84,7 +84,6 @@ dependencies {
implementation(projects.services.toolbox.api)
implementation(libs.androidx.webkit)
implementation(libs.coil.compose)
implementation(libs.network.retrofit)
implementation(libs.serialization.json)
implementation(libs.element.call.embedded)
api(projects.features.call.api)
+4 -4
View File
@@ -3,9 +3,9 @@
[versions]
# Project
android_gradle_plugin = "8.13.2"
android_gradle_plugin = "9.2.1"
# When updating this, please also update the version in the file ./idea/kotlinc.xml
kotlin = "2.3.21"
kotlin = "2.4.0"
kotlinpoet = "2.3.0"
ksp = "2.3.9"
firebaseAppDistribution = "5.2.1"
@@ -269,11 +269,11 @@ ktlint = "org.jlleitschuh.gradle.ktlint:14.2.0"
dependencygraph = "com.savvasdalkitsis.module-dependency-graph:0.12"
dependencycheck = "org.owasp.dependencycheck:12.2.2"
dependencyanalysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dependencyAnalysis" }
paparazzi = "app.cash.paparazzi:2.0.0-alpha04"
paparazzi = "app.cash.paparazzi:2.0.0-alpha05"
roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" }
sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }
firebaseAppDistribution = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistribution" }
sonarqube = "org.sonarqube:7.3.0.8198"
sonarqube = "org.sonarqube:7.3.1.8318"
licensee = "app.cash.licensee:1.14.1"
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
gms_google_services = { id = "com.google.gms.google-services", version = "4.4.4" }
Binary file not shown.
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=72f44c9f8ebcb1af43838f45ee5c4aa9c5444898b3468ab3f4af7b6076c5bc3f
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
distributionSha256Sum=bafc141b619ad6350fd975fc903156dd5c151998cc8b058e8c1044ab5f7b031f
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
@@ -78,7 +78,7 @@ fun SpaceRoomItemView(
indication = ripple(),
interactionSource = remember { MutableInteractionSource() }
)
.onKeyboardContextMenuAction { onLongClick }
.onKeyboardContextMenuAction(onLongClick)
Column(
modifier = modifier
.then(clickModifier)
@@ -258,7 +258,7 @@ class ExoPlayerForPreview(
override fun setPriorityTaskManager(priorityTaskManager: PriorityTaskManager?) {}
override fun isSleepingForOffload(): Boolean = throw NotImplementedError()
override fun isTunnelingEnabled(): Boolean = throw NotImplementedError()
override fun isReleased(): Boolean = throw NotImplementedError()
override fun isReleased(): Boolean = false
override fun setImageOutput(imageOutput: ImageOutput?) {}
override fun setAudioCodecParameters(codecParameters: CodecParameters) {}
override fun addAudioCodecParametersChangeListener(listener: CodecParametersChangeListener, keys: List<String>) {}
+1
View File
@@ -24,6 +24,7 @@ android {
setupDependencyInjection()
dependencies {
implementation(libs.coroutines.core)
implementation(projects.libraries.androidutils)
implementation(projects.libraries.core)
implementation(projects.libraries.di)
@@ -19,6 +19,10 @@ plugins {
android {
namespace = "io.element.android.libraries.pushproviders.firebase"
buildFeatures {
resValues = true
}
buildTypes {
getByName("release") {
consumerProguardFiles("consumer-proguard-rules.pro")
@@ -18,6 +18,7 @@ android {
setupDependencyInjection()
dependencies {
implementation(libs.coroutines.core)
implementation(projects.libraries.androidutils)
implementation(projects.libraries.preferences.api)
implementation(projects.libraries.core)
@@ -9,67 +9,111 @@
package extension
import Versions
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.ApplicationDefaultConfig
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.CompileOptions
import com.android.build.api.dsl.LibraryDefaultConfig
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.dsl.Lint
import isEnterpriseBuild
import org.gradle.api.Project
import java.io.File
fun CommonExtension<*, *, *, *, *, *>.androidConfig(project: Project) {
defaultConfig {
compileSdk = Versions.COMPILE_SDK
minSdk = Versions.minSdk
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
fun ApplicationExtension.androidAppConfig(project: Project) {
compileSdk = Versions.COMPILE_SDK
vectorDrawables {
useSupportLibrary = true
generatedDensities()
}
}
compileOptions {
sourceCompatibility = Versions.javaVersion
targetCompatibility = Versions.javaVersion
}
testOptions {
unitTests.isReturnDefaultValues = true
}
defaultConfig(::defaultApplicationConfig)
compileOptions(::defaultCompileOptions)
testOptions(::defaultTestOptions)
lint {
lintConfig = File("${project.rootDir}/tools/lint/lint.xml")
if (isEnterpriseBuild) {
// Disable check on ObsoleteSdkInt for Enterprise builds
// since the min sdk is higher for Enterprise builds
disable.add("ObsoleteSdkInt")
}
checkDependencies = false
abortOnError = true
ignoreTestSources = true
ignoreTestFixturesSources = true
checkGeneratedSources = false
project.defaultLintOptions(this)
}
}
fun CommonExtension<*, *, *, *, *, *>.composeConfig() {
fun LibraryExtension.androidLibraryConfig(project: Project) {
compileSdk = Versions.COMPILE_SDK
buildFeatures {
compose = true
}
packaging {
resources.excludes.apply {
add("META-INF/AL2.0")
add("META-INF/LGPL2.1")
}
}
defaultConfig(::defaultLibraryConfig)
compileOptions(::defaultCompileOptions)
testOptions(::defaultTestOptions)
lint {
// Extra rules for compose
// Disabled until lint stops inspecting generated ksp files...
// error.add("ComposableLambdaParameterNaming")
error.add("ComposableLambdaParameterPosition")
ignoreTestFixturesSources = true
checkGeneratedSources = false
project.defaultLintOptions(this)
}
}
fun ApplicationExtension.composeAppConfig() {
buildFeatures(::defaultComposeBuildFeatures)
packaging(::defaultPackagingOptions)
lint(::defaultComposeLintOptions)
}
fun LibraryExtension.composeLibraryConfig() {
buildFeatures(::defaultComposeBuildFeatures)
packaging(::defaultPackagingOptions)
lint(::defaultComposeLintOptions)
}
fun defaultApplicationConfig(applicationDefaultConfig: ApplicationDefaultConfig) = applicationDefaultConfig.apply {
minSdk = Versions.minSdk
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
generatedDensities()
}
}
fun defaultLibraryConfig(libraryDefaultConfig: LibraryDefaultConfig) = libraryDefaultConfig.apply {
minSdk = Versions.minSdk
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
generatedDensities()
}
}
fun defaultCompileOptions(compileOptions: CompileOptions) = compileOptions.apply {
sourceCompatibility = Versions.javaVersion
targetCompatibility = Versions.javaVersion
}
fun defaultTestOptions(testOptions: com.android.build.api.dsl.TestOptions) = testOptions.apply {
unitTests.isReturnDefaultValues = true
}
fun defaultComposeBuildFeatures(buildFeatures: com.android.build.api.dsl.BuildFeatures) = buildFeatures.apply {
compose = true
}
fun defaultPackagingOptions(packagingOptions: com.android.build.api.dsl.Packaging) = packagingOptions.apply {
resources.excludes.apply {
add("META-INF/AL2.0")
add("META-INF/LGPL2.1")
}
}
fun defaultComposeLintOptions(lint: Lint) = lint.apply {
// Extra rules for compose
// Disabled until lint stops inspecting generated ksp files...
// error.add("ComposableLambdaParameterNaming")
error.add("ComposableLambdaParameterPosition")
ignoreTestFixturesSources = true
checkGeneratedSources = false
}
fun Project.defaultLintOptions(lint: Lint) = lint.apply {
lintConfig = File("${project.rootDir}/tools/lint/lint.xml")
if (isEnterpriseBuild) {
// Disable check on ObsoleteSdkInt for Enterprise builds
// since the min sdk is higher for Enterprise builds
disable.add("ObsoleteSdkInt")
}
checkDependencies = false
abortOnError = true
ignoreTestSources = true
ignoreTestFixturesSources = true
checkGeneratedSources = false
}
@@ -9,9 +9,9 @@
/**
* This will generate the plugin "io.element.android-compose-application" to use by app
*/
import extension.androidConfig
import extension.androidAppConfig
import extension.commonDependencies
import extension.composeConfig
import extension.composeAppConfig
import extension.composeDependencies
import extension.setupKover
import org.gradle.accessors.dm.LibrariesForLibs
@@ -19,14 +19,13 @@ import org.gradle.accessors.dm.LibrariesForLibs
val libs = the<LibrariesForLibs>()
plugins {
id("com.android.application")
id("kotlin-android")
id("com.autonomousapps.dependency-analysis")
id("org.jetbrains.kotlin.plugin.compose")
}
android {
androidConfig(project)
composeConfig()
androidAppConfig(project)
composeAppConfig()
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
@@ -9,9 +9,9 @@
/**
* This will generate the plugin "io.element.android-compose-library", used in android library with compose modules.
*/
import extension.androidConfig
import extension.androidLibraryConfig
import extension.commonDependencies
import extension.composeConfig
import extension.composeLibraryConfig
import extension.composeDependencies
import extension.setupKover
import org.gradle.accessors.dm.LibrariesForLibs
@@ -19,14 +19,13 @@ import org.gradle.accessors.dm.LibrariesForLibs
val libs = the<LibrariesForLibs>()
plugins {
id("com.android.library")
id("kotlin-android")
id("com.autonomousapps.dependency-analysis")
id("org.jetbrains.kotlin.plugin.compose")
}
android {
androidConfig(project)
composeConfig()
androidLibraryConfig(project)
composeLibraryConfig()
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
@@ -9,7 +9,7 @@
/**
* This will generate the plugin "io.element.android-library", used in android library without compose modules.
*/
import extension.androidConfig
import extension.androidLibraryConfig
import extension.commonDependencies
import extension.setupKover
import org.gradle.accessors.dm.LibrariesForLibs
@@ -17,12 +17,11 @@ import org.gradle.accessors.dm.LibrariesForLibs
val libs = the<LibrariesForLibs>()
plugins {
id("com.android.library")
id("kotlin-android")
id("com.autonomousapps.dependency-analysis")
}
android {
androidConfig(project)
androidLibraryConfig(project)
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package ui
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
/**
* Workaround for Paparazzi 2.0.0-alpha05 / LayoutLib 16.2.1 bug where
* HandlerThread_Delegate calls Thread.setPosixNicenessInternal which doesn't exist on JVM.
* Tracked in https://github.com/cashapp/paparazzi/issues/2342 — fixed in layoutlib 16.2.3.
* Remove this workaround once Paparazzi ships with layoutlib >= 16.2.3.
*
* Paparazzi's PaparazziLogger collects background thread errors and re-throws them via
* assertNoErrors(). This Statement wrapper catches the known NoSuchMethodError so the test
* can pass despite the LayoutLib bug.
*/
class LayoutLibErrorFilterStatement : TestRule {
override fun apply(base: Statement, description: Description): Statement {
return object : Statement() {
@Throws(Throwable::class)
override fun evaluate() {
try {
base.evaluate()
} catch (e: NoSuchMethodError) {
if (e.message?.contains("setPosixNicenessInternal") != true) throw e
} catch (npe: NullPointerException) {
// Also catch this error on `HorizontalFloatingToolbarPreview` and `HorizontalFloatingToolbarNoFabPreview`
if (npe.message?.contains("""Cannot invoke "java.util.ArrayList.size()" because "childrenList" is null""") != true) throw npe
}
}
}
}
}
@@ -29,7 +29,10 @@ class PreviewA11yTest(
@TestParameter(valuesProvider = ComposableA11yPreviewProvider::class)
val preview: ComposablePreview<AndroidPreviewInfo>,
) {
@get:Rule
@get:Rule(order = 0)
val layoutLibErrorFilterStatement = LayoutLibErrorFilterStatement()
@get:Rule(order = 1)
val paparazziRule = PaparazziPreviewRule.createFor(
preview = preview,
locale = "en",
@@ -28,7 +28,10 @@ class PreviewShard1Test(
@TestParameter(valuesProvider = Shard1ComposablePreviewProvider::class)
val preview: ComposablePreview<AndroidPreviewInfo>,
) {
@get:Rule
@get:Rule(order = 0)
val layoutLibErrorFilterStatement = LayoutLibErrorFilterStatement()
@get:Rule(order = 1)
val paparazziRule = PaparazziPreviewRule.createFor(preview, locale = "en")
@Test
@@ -28,7 +28,10 @@ class PreviewShard2Test(
@TestParameter(valuesProvider = Shard2ComposablePreviewProvider::class)
val preview: ComposablePreview<AndroidPreviewInfo>,
) {
@get:Rule
@get:Rule(order = 0)
val layoutLibErrorFilterStatement = LayoutLibErrorFilterStatement()
@get:Rule(order = 1)
val paparazziRule = PaparazziPreviewRule.createFor(preview, locale = "en")
@Test
@@ -28,7 +28,10 @@ class PreviewShard3Test(
@TestParameter(valuesProvider = Shard3ComposablePreviewProvider::class)
val preview: ComposablePreview<AndroidPreviewInfo>,
) {
@get:Rule
@get:Rule(order = 0)
val layoutLibErrorFilterStatement = LayoutLibErrorFilterStatement()
@get:Rule(order = 1)
val paparazziRule = PaparazziPreviewRule.createFor(preview, locale = "en")
@Test
@@ -28,7 +28,10 @@ class PreviewShard4Test(
@TestParameter(valuesProvider = Shard4ComposablePreviewProvider::class)
val preview: ComposablePreview<AndroidPreviewInfo>,
) {
@get:Rule
@get:Rule(order = 0)
val layoutLibErrorFilterStatement = LayoutLibErrorFilterStatement()
@get:Rule(order = 1)
val paparazziRule = PaparazziPreviewRule.createFor(preview, locale = "en")
@Test

Some files were not shown because too many files have changed in this diff Show More