diff --git a/mobile/src/main/java/be/mygod/librootkotlinx/RootServer.kt b/mobile/src/main/java/be/mygod/librootkotlinx/RootServer.kt index 396c2c55..8113e71c 100644 --- a/mobile/src/main/java/be/mygod/librootkotlinx/RootServer.kt +++ b/mobile/src/main/java/be/mygod/librootkotlinx/RootServer.kt @@ -11,10 +11,7 @@ import androidx.collection.LongSparseArray import androidx.collection.set import androidx.collection.valueIterator import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.channels.SendChannel -import kotlinx.coroutines.channels.consumeEach -import kotlinx.coroutines.channels.produce +import kotlinx.coroutines.channels.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import java.io.* @@ -77,15 +74,13 @@ class RootServer { override fun shouldRemove(result: Byte) = result.toInt() != SUCCESS override fun invoke(input: DataInputStream, result: Byte) { when (result.toInt()) { - // the channel we are supporting should never block - SUCCESS -> check(try { - channel.offer(input.readParcelable(classLoader)) - } catch (closed: Throwable) { + SUCCESS -> channel.trySend(input.readParcelable(classLoader)).onClosed { active = false GlobalScope.launch(Dispatchers.Unconfined) { sendClosed() } - finish.completeExceptionally(closed) + finish.completeExceptionally(it + ?: ClosedSendChannelException("Channel was closed normally")) return - }) + }.onFailure { throw it!! } // the channel we are supporting should never block CHANNEL_CONSUMED -> finish.complete(Unit) else -> finish.completeExceptionally(input.readException(result)) } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/ServiceNotification.kt b/mobile/src/main/java/be/mygod/vpnhotspot/ServiceNotification.kt index 3581e577..fd7c8853 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/ServiceNotification.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/ServiceNotification.kt @@ -38,7 +38,7 @@ object ServiceNotification { lines += context.getString(R.string.notification_interfaces_inactive, inactive.joinToString()) } return if (lines.size <= 1) builder.setContentText(lines.singleOrNull()).build() else { - val deviceCount = deviceCounts.sumBy { it.value } + val deviceCount = deviceCounts.sumOf { it.value } val interfaceCount = deviceCounts.size + inactive.size NotificationCompat.BigTextStyle(builder .setContentText(context.resources.getQuantityString(R.plurals.notification_connected_devices, diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/MacAddressCompat.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/MacAddressCompat.kt index 73397bdc..cc31a92e 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/MacAddressCompat.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/MacAddressCompat.kt @@ -8,7 +8,8 @@ import java.nio.ByteOrder /** * Compat support class for [MacAddress]. */ -inline class MacAddressCompat(val addr: Long) { +@JvmInline +value class MacAddressCompat(val addr: Long) { companion object { private const val ETHER_ADDR_LEN = 6 /** diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/IpNeighbourMonitor.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/IpNeighbourMonitor.kt index 87239548..df0bb130 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/IpNeighbourMonitor.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/IpNeighbourMonitor.kt @@ -5,9 +5,7 @@ import be.mygod.vpnhotspot.net.IpNeighbour import kotlinx.collections.immutable.PersistentMap import kotlinx.collections.immutable.persistentMapOf import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.channels.actor -import kotlinx.coroutines.channels.sendBlocking +import kotlinx.coroutines.channels.* class IpNeighbourMonitor private constructor() : IpMonitor() { companion object { @@ -69,7 +67,7 @@ class IpNeighbourMonitor private constructor() : IpMonitor() { IpNeighbour.State.DELETING -> neighbours.remove(IpDev(neighbour)) else -> neighbours.put(IpDev(neighbour), neighbour) } - if (neighbours != old) aggregator.sendBlocking(neighbours) + if (neighbours != old) aggregator.trySendBlocking(neighbours).onFailure { throw it!! } } override fun processLines(lines: Sequence) { @@ -78,6 +76,6 @@ class IpNeighbourMonitor private constructor() : IpMonitor() { .filter { it.state != IpNeighbour.State.DELETING } // skip entries without lladdr .associateByTo(persistentMapOf().builder()) { IpDev(it) } .build() - aggregator.sendBlocking(neighbours) + aggregator.trySendBlocking(neighbours).onFailure { throw it!! } } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/root/MiscCommands.kt b/mobile/src/main/java/be/mygod/vpnhotspot/root/MiscCommands.kt index e0b85712..f089bc8b 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/root/MiscCommands.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/root/MiscCommands.kt @@ -13,6 +13,8 @@ import be.mygod.vpnhotspot.net.Routing.Companion.IPTABLES import be.mygod.vpnhotspot.net.TetheringManager import be.mygod.vpnhotspot.util.Services import kotlinx.coroutines.* +import kotlinx.coroutines.channels.onClosed +import kotlinx.coroutines.channels.onFailure import kotlinx.coroutines.channels.produce import kotlinx.parcelize.Parcelize import java.io.File @@ -101,7 +103,7 @@ class ProcessListener(private val terminateRegex: Regex, launch(parent) { try { process.inputStream.bufferedReader().forEachLine { - check(offer(ProcessData.StdoutLine(it))) + trySend(ProcessData.StdoutLine(it)).onClosed { return@forEachLine }.onFailure { throw it!! } if (terminateRegex.containsMatchIn(it)) process.destroy() } } catch (_: InterruptedIOException) { } @@ -111,7 +113,9 @@ class ProcessListener(private val terminateRegex: Regex, process.errorStream.bufferedReader().forEachLine { check(offer(ProcessData.StderrLine(it))) } } catch (_: InterruptedIOException) { } } - launch(parent) { check(offer(ProcessData.Exit(process.waitFor()))) } + launch(parent) { + trySend(ProcessData.Exit(process.waitFor())).onClosed { return@launch }.onFailure { throw it!! } + } parent.join() } finally { parent.cancel() diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/root/WifiApCommands.kt b/mobile/src/main/java/be/mygod/vpnhotspot/root/WifiApCommands.kt index 42bb2f32..29cb1e24 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/root/WifiApCommands.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/root/WifiApCommands.kt @@ -10,9 +10,7 @@ import be.mygod.vpnhotspot.net.wifi.SoftApConfigurationCompat import be.mygod.vpnhotspot.net.wifi.WifiApManager import be.mygod.vpnhotspot.widget.SmartSnackbar import kotlinx.coroutines.* -import kotlinx.coroutines.channels.ReceiveChannel -import kotlinx.coroutines.channels.consumeEach -import kotlinx.coroutines.channels.produce +import kotlinx.coroutines.channels.* import kotlinx.parcelize.Parcelize import timber.log.Timber @@ -65,12 +63,11 @@ object WifiApCommands { override fun create(scope: CoroutineScope) = scope.produce(capacity = capacity) { val finish = CompletableDeferred() val key = WifiApManager.registerSoftApCallback(object : WifiApManager.SoftApCallbackCompat { - private fun push(parcel: SoftApCallbackParcel) = check(try { - offer(parcel) - } catch (closed: Throwable) { - finish.completeExceptionally(closed) - true - }) + private fun push(parcel: SoftApCallbackParcel) { + trySend(parcel).onClosed { + finish.completeExceptionally(it ?: ClosedSendChannelException("Channel was closed normally")) + }.onFailure { throw it!! } + } override fun onStateChanged(state: Int, failureReason: Int) = push(SoftApCallbackParcel.OnStateChanged(state, failureReason))