Skip to content

Commit

Permalink
NetworkTypeFinder for Android
Browse files Browse the repository at this point in the history
  • Loading branch information
sdsantos committed Aug 7, 2024
1 parent aac5677 commit 810ce59
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 41 deletions.
4 changes: 3 additions & 1 deletion composeApp/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
android:name=".AndroidApplication"
Expand All @@ -22,4 +24,4 @@
</activity>
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.ooni.engine

import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import org.ooni.engine.models.NetworkType

class AndroidNetworkTypeFinder(
private val connectivityManager: ConnectivityManager?,
) : NetworkTypeFinder {
override fun invoke(): NetworkType {
if (connectivityManager == null) return NetworkType.NoInternet

val capabilities =
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
?: return NetworkType.NoInternet

return when {
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> NetworkType.VPN
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> NetworkType.Wifi
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> NetworkType.Mobile
else -> NetworkType.NoInternet
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.ooni.probe

import android.app.Application
import android.net.ConnectivityManager
import android.os.Build
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
import org.ooni.engine.AndroidNetworkTypeFinder
import org.ooni.engine.AndroidOonimkallBridge
import org.ooni.probe.di.Dependencies
import org.ooni.probe.shared.Platform
Expand All @@ -21,6 +23,8 @@ class AndroidApplication : Application() {
baseFileDir = filesDir.absolutePath,
cacheDir = cacheDir.absolutePath,
databaseDriverFactory = ::buildDatabaseDriver,
networkTypeFinder =
AndroidNetworkTypeFinder(getSystemService(ConnectivityManager::class.java)),
)
}

Expand Down
73 changes: 47 additions & 26 deletions composeApp/src/commonMain/kotlin/org/ooni/engine/Engine.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,19 @@ class Engine(
channelFlow {
val taskSettings = buildTaskSettings(name, inputs, taskOrigin)
val settingsSerialized = json.encodeToString(taskSettings)
val task = bridge.startTask(settingsSerialized)

while (!task.isDone()) {
val eventJson = task.waitForNextEvent()
val taskEventResult = json.decodeFromString<TaskEventResult>(eventJson)
taskEventMapper(taskEventResult)?.let { send(it) }
var task: OonimkallBridge.Task? = null
try {
task = bridge.startTask(settingsSerialized)

while (!task.isDone()) {
val eventJson = task.waitForNextEvent()
val taskEventResult = json.decodeFromString<TaskEventResult>(eventJson)
taskEventMapper(taskEventResult)?.let { send(it) }
}
} catch (e: Exception) {
task?.interrupt()
throw MkException(e)
}

invokeOnClose {
Expand All @@ -57,27 +64,35 @@ class Engine(
taskOrigin: TaskOrigin = TaskOrigin.OoniRun,
): SubmitMeasurementResults =
withContext(backgroundDispatcher) {
val sessionConfig = buildSessionConfig(taskOrigin)
session(sessionConfig).submitMeasurement(measurement)
try {
val sessionConfig = buildSessionConfig(taskOrigin)
session(sessionConfig).submitMeasurement(measurement)
} catch (e: Exception) {
throw MkException(e)
}
}

suspend fun checkIn(
categories: List<String>,
taskOrigin: TaskOrigin,
): OonimkallBridge.CheckInResults =
withContext(backgroundDispatcher) {
val sessionConfig = buildSessionConfig(taskOrigin)
session(sessionConfig).checkIn(
OonimkallBridge.CheckInConfig(
charging = true,
onWiFi = true,
platform = platformInfo.platform.value,
runType = taskOrigin.value,
softwareName = sessionConfig.softwareName,
softwareVersion = sessionConfig.softwareVersion,
webConnectivityCategories = categories,
),
)
try {
val sessionConfig = buildSessionConfig(taskOrigin)
session(sessionConfig).checkIn(
OonimkallBridge.CheckInConfig(
charging = true,
onWiFi = true,
platform = platformInfo.platform.value,
runType = taskOrigin.value,
softwareName = sessionConfig.softwareName,
softwareVersion = sessionConfig.softwareVersion,
webConnectivityCategories = categories,
),
)
} catch (e: Exception) {
throw MkException(e)
}
}

suspend fun httpDo(
Expand All @@ -86,13 +101,17 @@ class Engine(
taskOrigin: TaskOrigin = TaskOrigin.OoniRun,
): String? =
withContext(backgroundDispatcher) {
session(buildSessionConfig(taskOrigin))
.httpDo(
OonimkallBridge.HTTPRequest(
method = method,
url = url,
),
).body
try {
session(buildSessionConfig(taskOrigin))
.httpDo(
OonimkallBridge.HTTPRequest(
method = method,
url = url,
),
).body
} catch (e: Exception) {
throw MkException(e)
}
}

private fun session(sessionConfig: OonimkallBridge.SessionConfig): OonimkallBridge.Session = bridge.newSession(sessionConfig)
Expand Down Expand Up @@ -179,4 +198,6 @@ class Engine(
}
}
}

class MkException(e: Exception) : Exception(e)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import org.ooni.engine.Engine
import org.ooni.engine.NetworkTypeFinder
import org.ooni.engine.OonimkallBridge
import org.ooni.engine.TaskEventMapper
import org.ooni.engine.models.NetworkType
import org.ooni.probe.Database
import org.ooni.probe.data.models.TestResult
import org.ooni.probe.shared.PlatformInfo
Expand All @@ -23,8 +22,9 @@ class Dependencies(
private val baseFileDir: String,
private val cacheDir: String,
private val databaseDriverFactory: () -> SqlDriver,
private val networkTypeFinder: NetworkTypeFinder,
) {
// Commong
// Common

private val backgroundDispatcher = Dispatchers.IO

Expand All @@ -35,8 +35,6 @@ class Dependencies(

// Engine

private val networkTypeFinder by lazy { NetworkTypeFinder { NetworkType.Unknown("") } } // TODO

private val taskEventMapper by lazy { TaskEventMapper(networkTypeFinder, json) }

private val engine by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import co.touchlab.kermit.Logger
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.launchIn
Expand Down Expand Up @@ -33,18 +34,27 @@ class DashboardViewModel(

_state.value = _state.value.copy(isRunning = true)

val response =
engine.httpDo(
method = "GET",
url = "https://api.dev.ooni.io/api/v2/oonirun/links/10426",
)
response?.let { Logger.d(it) }
try {
val response =
engine.httpDo(
method = "GET",
url = "https://api.dev.ooni.io/api/v2/oonirun/links/10426",
)
response?.let { Logger.d(it) }
} catch (e: Engine.MkException) {
Logger.e("httpDo failed", e)
}

val checkInResults =
engine.checkIn(
categories = listOf("NEWS"),
taskOrigin = TaskOrigin.OoniRun,
)
try {
engine.checkIn(
categories = listOf("NEWS"),
taskOrigin = TaskOrigin.OoniRun,
)
} catch (e: Engine.MkException) {
Logger.e("checkIn failed", e)
return@flatMapLatest emptyFlow()
}

engine
.startTask(
Expand All @@ -62,6 +72,9 @@ class DashboardViewModel(
}.onCompletion {
_state.update { it.copy(isRunning = false) }
}
.catch {
Logger.e("startTask failed", it)
}
}
}
}.launchIn(viewModelScope)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.ooni.probe

import app.cash.sqldelight.driver.native.NativeSqliteDriver
import org.ooni.engine.OonimkallBridge
import org.ooni.engine.models.NetworkType
import org.ooni.probe.di.Dependencies
import org.ooni.probe.shared.Platform
import org.ooni.probe.shared.PlatformInfo
Expand All @@ -23,6 +24,8 @@ fun setupDependencies(bridge: OonimkallBridge) =
baseFileDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).first().toString(),
cacheDir = NSTemporaryDirectory(),
databaseDriverFactory = ::buildDatabaseDriver,
// TODO
networkTypeFinder = { NetworkType.Unknown("") },
)

private val platformInfo get() =
Expand Down

0 comments on commit 810ce59

Please sign in to comment.