diff --git a/composeApp/src/commonMain/debug/kotlin/org/ooni/probe/config/OrganizationConfigInterface.kt b/composeApp/src/commonMain/debug/kotlin/org/ooni/probe/config/OrganizationConfigInterface.kt index 1d38bf95..3ec9094d 100644 --- a/composeApp/src/commonMain/debug/kotlin/org/ooni/probe/config/OrganizationConfigInterface.kt +++ b/composeApp/src/commonMain/debug/kotlin/org/ooni/probe/config/OrganizationConfigInterface.kt @@ -5,13 +5,13 @@ interface OrganizationConfigInterface { val baseSoftwareName: String val ooniApiBaseUrl: String - get() = "https://api.ooni.org" + get() = "https://api.dev.ooni.io" val ooniRunDomain: String - get() = "run.ooni.org" + get() = "run.test.ooni.org" val ooniRunDashboardUrl: String - get() = "https://run.ooni.org" + get() = "https://run.test.ooni.org" val explorerUrl: String get() = "https://explorer.test.ooni.org" diff --git a/composeApp/src/commonMain/kotlin/org/ooni/engine/Engine.kt b/composeApp/src/commonMain/kotlin/org/ooni/engine/Engine.kt index f06299af..3e0a1638 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/engine/Engine.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/engine/Engine.kt @@ -52,15 +52,19 @@ class Engine( val settingsSerialized = json.encodeToString(taskSettings) var task: OonimkallBridge.Task? = null + var isCancelled = false try { task = bridge.startTask(settingsSerialized) - addRunCancelListener { task.interrupt() } + addRunCancelListener { + isCancelled = true + task.interrupt() + } while (!task.isDone() && isActive) { val eventJson = task.waitForNextEvent() val taskEventResult = json.decodeFromString(eventJson) - taskEventMapper(taskEventResult)?.let { send(it) } + taskEventMapper(taskEventResult, isCancelled)?.let { send(it) } } } catch (e: Exception) { Logger.d("Error while running task", e) diff --git a/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskEventMapper.kt b/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskEventMapper.kt index 09a4ba99..71d2fd02 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskEventMapper.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/engine/TaskEventMapper.kt @@ -9,7 +9,10 @@ class TaskEventMapper( private val networkTypeFinder: NetworkTypeFinder, private val json: Json, ) { - operator fun invoke(result: TaskEventResult): TaskEvent? { + operator fun invoke( + result: TaskEventResult, + isCancelled: Boolean = false, + ): TaskEvent? { val key = result.key val value = result.value @@ -33,6 +36,7 @@ class TaskEventMapper( TaskEvent.ResolverLookupFailure( message = value.failure, value = value, + isCancelled = isCancelled, ) } ?: run { Logger.d("Task Event $key missing 'value'") @@ -44,6 +48,7 @@ class TaskEventMapper( TaskEvent.StartupFailure( message = value.failure, value = value, + isCancelled = isCancelled, ) } ?: run { Logger.d("Task Event $key missing 'value'") diff --git a/composeApp/src/commonMain/kotlin/org/ooni/engine/models/TaskEvent.kt b/composeApp/src/commonMain/kotlin/org/ooni/engine/models/TaskEvent.kt index 3b35dfa0..12d62280 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/engine/models/TaskEvent.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/engine/models/TaskEvent.kt @@ -59,6 +59,7 @@ sealed interface TaskEvent { data class ResolverLookupFailure( val message: String?, val value: TaskEventResult.Value, + val isCancelled: Boolean, ) : TaskEvent data object Started : TaskEvent @@ -66,9 +67,17 @@ sealed interface TaskEvent { data class StartupFailure( val message: String?, val value: TaskEventResult.Value, + val isCancelled: Boolean, ) : TaskEvent data class TaskTerminated( val index: Int, ) : TaskEvent + + fun isCancelled() = + when (this) { + is StartupFailure -> isCancelled + is ResolverLookupFailure -> isCancelled + else -> null + } } diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/RunNetTest.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/RunNetTest.kt index c79eb421..562b9594 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/RunNetTest.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/RunNetTest.kt @@ -221,7 +221,7 @@ class RunNetTest( is TaskEvent.StartupFailure, is TaskEvent.ResolverLookupFailure, - -> { + -> { val message = when (event) { is TaskEvent.StartupFailure -> event.message is TaskEvent.ResolverLookupFailure -> event.message @@ -232,28 +232,33 @@ class RunNetTest( updateResult { it.copy( failureMessage = - if (it.failureMessage != null) { - "${it.failureMessage}\n$message" - } else { - message - }, + if (it.failureMessage != null) { + "${it.failureMessage}\n$message" + } else { + message + }, ) } } + if (event.isCancelled() == true) return + when (event) { is TaskEvent.StartupFailure -> - Logger.w(message ?: "StartupFailure", Failure(event.value)) + Logger.w("StartupFailure", StartupFailure(message, event.value)) is TaskEvent.ResolverLookupFailure -> - Logger.i(message ?: "ResolverLookupFailure", Failure(event.value)) + Logger.i( + "ResolverLookupFailure", + ResolverLookupFailure(message, event.value), + ) else -> Unit } } is TaskEvent.BugJsonDump -> { - Logger.w("BugJsonDump", Failure(event.value)) + Logger.w("BugJsonDump", BugJsonDump(event.value)) } is TaskEvent.TaskTerminated -> Unit @@ -293,5 +298,21 @@ class RunNetTest( ) } - inner class Failure(value: TaskEventResult.Value) : Exception(json.encodeToString(value)) + open inner class Failure(message: String?, value: TaskEventResult.Value?) : Exception( + if (message != null && value != null) { + message + "\n" + json.encodeToString(value) + } else if (value != null) { + json.encodeToString(value) + } else { + message ?: "" + }, + ) + + inner class StartupFailure(message: String?, value: TaskEventResult.Value?) : + Failure(message, value) + + inner class ResolverLookupFailure(message: String?, value: TaskEventResult.Value?) : + Failure(message, value) + + inner class BugJsonDump(value: TaskEventResult.Value?) : Failure(null, value) }