diff --git a/client/android/src/org/amnezia/vpn/AmneziaVpnService.kt b/client/android/src/org/amnezia/vpn/AmneziaVpnService.kt index cbf20123..23ed8204 100644 --- a/client/android/src/org/amnezia/vpn/AmneziaVpnService.kt +++ b/client/android/src/org/amnezia/vpn/AmneziaVpnService.kt @@ -23,6 +23,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import org.amnezia.vpn.protocol.BadConfigException @@ -54,6 +55,7 @@ const val ERROR_MSG = "ERROR_MSG" const val AFTER_PERMISSION_CHECK = "AFTER_PERMISSION_CHECK" private const val PREFS_CONFIG_KEY = "LAST_CONF" private const val NOTIFICATION_ID = 1337 +private const val STATISTICS_SENDING_TIMEOUT = 1000L class AmneziaVpnService : VpnService() { @@ -75,6 +77,7 @@ class AmneziaVpnService : VpnService() { private var connectionJob: Job? = null private var disconnectionJob: Job? = null + private var statisticsSendingJob: Job? = null private lateinit var clientMessenger: IpcMessenger private val connectionExceptionHandler = CoroutineExceptionHandler { _, e -> @@ -123,14 +126,6 @@ class AmneziaVpnService : VpnService() { } } } - - Action.REQUEST_STATISTICS -> { - clientMessenger.send { - ServiceEvent.STATISTICS_UPDATE.packToMessage { - putStatistics(protocol?.statistics ?: Statistics.EMPTY_STATISTICS) - } - } - } } } } @@ -207,6 +202,7 @@ class AmneziaVpnService : VpnService() { Log.d(TAG, "onBind by $intent") if (intent?.action == "android.net.VpnService") return super.onBind(intent) isServiceBound = true + if (isConnected) launchSendingStatistics() return vpnServiceMessenger.binder } @@ -214,6 +210,7 @@ class AmneziaVpnService : VpnService() { Log.d(TAG, "onUnbind by $intent") if (intent?.action != "android.net.VpnService") { isServiceBound = false + stopSendingStatistics() clientMessenger.reset() if (isUnknown || isDisconnected) stopSelf() } @@ -247,19 +244,46 @@ class AmneziaVpnService : VpnService() { when (protocolState) { CONNECTED -> { clientMessenger.send(ServiceEvent.CONNECTED) + if (isServiceBound) launchSendingStatistics() } DISCONNECTED -> { clientMessenger.send(ServiceEvent.DISCONNECTED) + stopSendingStatistics() if (!isServiceBound) stopSelf() } - CONNECTING, DISCONNECTING, UNKNOWN -> {} + DISCONNECTING -> { + stopSendingStatistics() + } + + CONNECTING, UNKNOWN -> {} } } } } + @MainThread + private fun launchSendingStatistics() { + if (isServiceBound && isConnected) { + statisticsSendingJob = mainScope.launch { + while (true) { + clientMessenger.send { + ServiceEvent.STATISTICS_UPDATE.packToMessage { + putStatistics(protocol?.statistics ?: Statistics.EMPTY_STATISTICS) + } + } + delay(STATISTICS_SENDING_TIMEOUT) + } + } + } + } + + @MainThread + private fun stopSendingStatistics() { + statisticsSendingJob?.cancel() + } + @MainThread private fun connect(vpnConfig: String?) { Log.v(TAG, "Start VPN connection") diff --git a/client/android/src/org/amnezia/vpn/IpcMessage.kt b/client/android/src/org/amnezia/vpn/IpcMessage.kt index 206b47ad..c0183b45 100644 --- a/client/android/src/org/amnezia/vpn/IpcMessage.kt +++ b/client/android/src/org/amnezia/vpn/IpcMessage.kt @@ -31,8 +31,7 @@ enum class Action : IpcMessage { REGISTER_CLIENT, CONNECT, DISCONNECT, - REQUEST_STATUS, - REQUEST_STATISTICS + REQUEST_STATUS } fun T.packToMessage(): Message