refactor(coroutines): migrate to kotlinx-coroutines 1.11.0-rc02 (#5312)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
James Rich
2026-04-30 22:11:22 -05:00
committed by GitHub
parent 2822290908
commit e198f52de5
21 changed files with 64 additions and 49 deletions
@@ -20,6 +20,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import co.touchlab.kermit.Logger
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Job
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.delay
@@ -32,6 +33,7 @@ import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull
import org.jetbrains.compose.resources.StringResource
import org.koin.core.annotation.KoinViewModel
@@ -127,10 +129,10 @@ class FirmwareUpdateViewModel(
override fun onCleared() {
super.onCleared()
// viewModelScope is already cancelled when onCleared() runs, so launch cleanup on the
// application-wide scope (SupervisorJob + ioDispatcher). NonCancellable keeps cleanup
// running even if something tries to cancel it mid-flight.
applicationScope.launch(NonCancellable) {
tempFirmwareFile = cleanupTemporaryFiles(fileHandler, tempFirmwareFile)
// application-wide scope (SupervisorJob + ioDispatcher). ATOMIC start + NonCancellable
// context keeps cleanup running even if something tries to cancel it mid-flight.
applicationScope.launch(start = CoroutineStart.ATOMIC) {
withContext(NonCancellable) { tempFirmwareFile = cleanupTemporaryFiles(fileHandler, tempFirmwareFile) }
}
}
@@ -142,7 +142,7 @@ class LegacyDfuTransport(
// Best-effort DFU Version read — gate out unsupported old bootloaders (SDK ≤ 6).
val versionChar = service.characteristic(LEGACY_DFU_VERSION_UUID)
val version =
runCatching { service.read(versionChar) }
safeCatching { service.read(versionChar) }
.map { bytes ->
if (bytes.size >= 2) (bytes[0].toInt() and 0xFF) or ((bytes[1].toInt() and 0xFF) shl 8) else -1
}
@@ -35,6 +35,7 @@ import org.jetbrains.compose.resources.StringResource
import org.koin.core.annotation.InjectedParam
import org.koin.core.annotation.KoinViewModel
import org.meshtastic.core.common.util.CommonUri
import org.meshtastic.core.common.util.safeCatching
import org.meshtastic.core.domain.usecase.settings.AdminActionsUseCase
import org.meshtastic.core.domain.usecase.settings.ExportProfileUseCase
import org.meshtastic.core.domain.usecase.settings.ExportSecurityConfigUseCase
@@ -165,7 +166,7 @@ open class RadioConfigViewModel(
probeJob =
viewModelScope.launch {
val result =
runCatching { mqttManager.probe(address, tlsEnabled, username, password) }
safeCatching { mqttManager.probe(address, tlsEnabled, username, password) }
.getOrElse { e ->
Logger.w(e) { "MQTT probe threw" }
MqttProbeStatus.Other(message = e.message)