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 6, 2024
1 parent 951882a commit 1d3e983
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 40 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,7 +1,9 @@
package org.ooni.probe

import android.app.Application
import android.net.ConnectivityManager
import android.os.Build
import org.ooni.engine.AndroidNetworkTypeFinder
import org.ooni.engine.AndroidOonimkallBridge
import org.ooni.probe.di.Dependencies
import org.ooni.probe.shared.Platform
Expand All @@ -18,6 +20,8 @@ class AndroidApplication : Application() {
oonimkallBridge = AndroidOonimkallBridge(),
baseFileDir = filesDir.absolutePath,
cacheDir = cacheDir.absolutePath,
networkTypeFinder =
AndroidNetworkTypeFinder(getSystemService(ConnectivityManager::class.java)),
)
}

Expand Down
71 changes: 46 additions & 25 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,12 +101,16 @@ 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 {
Expand Down Expand Up @@ -180,4 +199,6 @@ class Engine(
}
}
}

class MkException(e: Exception) : Exception(e)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,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.data.models.TestResult
import org.ooni.probe.shared.PlatformInfo
import org.ooni.probe.ui.dashboard.DashboardViewModel
Expand All @@ -20,8 +19,9 @@ class Dependencies(
private val oonimkallBridge: OonimkallBridge,
private val baseFileDir: String,
private val cacheDir: String,
private val networkTypeFinder: NetworkTypeFinder,
) {
// Commong
// Common

private val backgroundDispatcher = Dispatchers.IO

Expand All @@ -31,8 +31,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(
name = "web_connectivity",
Expand All @@ -63,6 +73,9 @@ class DashboardViewModel(
.onCompletion {
_state.update { it.copy(isRunning = false) }
}
.catch {
Logger.e("startTask failed", it)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.ooni.probe

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 @@ -21,6 +22,8 @@ fun setupDependencies(bridge: OonimkallBridge) =
oonimkallBridge = bridge,
baseFileDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).first().toString(),
cacheDir = NSTemporaryDirectory(),
// TODO
networkTypeFinder = { NetworkType.Unknown("") },
)

private val platformInfo get() =
Expand Down

0 comments on commit 1d3e983

Please sign in to comment.