Make StrictMode more lenient for network on main thread violations (#7830)

* Make `StrictMode` more lenient for network on main thread violations

`rustls-platform-verifier-android:0.2.0` performs the certification revocation checks in whatever thread called the Rust code that triggered the network request. In our codebase, sometimes this is the main thread through `MainScope`.

This would usually be fine if we were using suspend APIs, since it would just wait for a result and not block the main thread. However, the cert verification logic uses some `HttpUrlConnection` calls under the hood that are fully blocking and this triggers `NetworkOnMainThreadException`, which in turn make the revocation fail.

With these changes, we log those issues but don't make them break the certificate verification. That said, we should revert this logic once a fix lands in the verifier.

* Make the `StrictMode` weaker only for release and nightly builds

This way we can fix the issues when we detect them in debug builds.

* Fix `org.matrix.rustsdk.Android.init` not being called immediately in `PlatformInitializer`

This must be called before `platformService.init(tracingConfiguration)`

* Add `penaltyDialog`, to check if it's useful or just annoying
This commit is contained in:
Jorge Martin Espinosa
2026-10-01 18:55:23 +02:00
committed by GitHub
parent 6e012ec7ed
commit a3ff7e1486
2 changed files with 27 additions and 7 deletions
@@ -9,6 +9,7 @@
package io.element.android.x
import android.app.Application
import android.os.StrictMode
import androidx.compose.material3.ComposeMaterial3Flags.isAnchoredDraggableComponentsStrictOffsetCheckEnabled
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.startup.AppInitializer
@@ -38,6 +39,21 @@ class ElementXApplication : Application(), DependencyInjectionGraphOwner, Config
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate() {
super.onCreate()
// Workaround to avoid NetworkOnMainThreadException when using the network on the main thread.
// This is a temporary solution to rustls doing the certificate verification using blocking network requests.
// It should be removed once the underlying issue is fixed.
// Also, we only want to enable it on nightly and release builds so we can debug the issue on debug builds.
if (!BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectNetwork()
.penaltyLog()
.penaltyDialog()
.build()
)
}
AppInitializer.getInstance(this).apply {
initializeComponent(CrashInitializer::class.java)
initializeComponent(PlatformInitializer::class.java)
@@ -8,8 +8,10 @@
package io.element.android.x.initializer
import android.annotation.SuppressLint
import android.content.Context
import android.system.Os
import android.util.Log
import androidx.startup.Initializer
import io.element.android.features.rageshake.api.logs.createWriteToFilesConfiguration
import io.element.android.libraries.architecture.bindings
@@ -25,6 +27,15 @@ private const val ELEMENT_X_TARGET = "elementx"
class PlatformInitializer : Initializer<Unit> {
override fun create(context: Context) {
// Init the SDK with the Android Context, so it can be used with rustls and other Android specific features
runCatchingExceptions {
org.matrix.rustsdk.Android.init(context)
}.onFailure {
// We can't log this to Timber since the logs aren't initialized yet, so we log it to Logcat instead
@SuppressLint("LogNotTimber")
Log.e("PlatformInitializer", "Failed to init the SDK with an Android Context. The app probably won't work properly.", it)
}
val appBindings = context.bindings<AppBindings>()
val tracingService = appBindings.tracingService()
val platformService = appBindings.platformService()
@@ -47,13 +58,6 @@ class PlatformInitializer : Initializer<Unit> {
platformService.init(tracingConfiguration)
// Also set env variable for rust back trace
Os.setenv("RUST_BACKTRACE", "1", true)
// Init the SDK with the Android Context, so it can be used with rustls and other Android specific features
runCatchingExceptions {
org.matrix.rustsdk.Android.init(context)
}.onFailure {
Timber.e(it, "Failed to init the SDK with an Android Context. The app probably won't work properly.")
}
}
override fun dependencies(): List<Class<out Initializer<*>>> = mutableListOf()