Draft for supporting using system configuration for temporary hotspot

Attempt at addressing #166.
This commit is contained in:
Mygod
2021-05-31 01:21:40 -04:00
parent 229b190c22
commit bc25cdb0bb
11 changed files with 204 additions and 42 deletions

View File

@@ -0,0 +1,19 @@
package be.mygod.vpnhotspot.root
import android.net.wifi.SoftApConfiguration
import android.os.Parcelable
import androidx.annotation.RequiresApi
import kotlinx.parcelize.Parcelize
@RequiresApi(30)
sealed class LocalOnlyHotspotCallbacks : Parcelable {
@Parcelize
data class OnStarted(val config: SoftApConfiguration) : LocalOnlyHotspotCallbacks()
@Parcelize
class OnStopped : LocalOnlyHotspotCallbacks() {
override fun equals(other: Any?) = other is OnStopped
override fun hashCode() = 0x80acd3ca.toInt()
}
@Parcelize
data class OnFailed(val reason: Int) : LocalOnlyHotspotCallbacks()
}

View File

@@ -1,5 +1,6 @@
package be.mygod.vpnhotspot.root
import android.net.wifi.WifiManager
import android.os.Parcelable
import androidx.annotation.RequiresApi
import be.mygod.librootkotlinx.ParcelableBoolean
@@ -62,6 +63,7 @@ object WifiApCommands {
private fun push(parcel: SoftApCallbackParcel) {
trySend(parcel).onClosed {
finish.completeExceptionally(it ?: ClosedSendChannelException("Channel was closed normally"))
return
}.onFailure { throw it!! }
}
@@ -149,11 +151,60 @@ object WifiApCommands {
@Parcelize
class GetConfiguration : RootCommand<SoftApConfigurationCompat> {
override suspend fun execute() = WifiApManager.configuration
override suspend fun execute() = WifiApManager.configurationCompat
}
@Parcelize
data class SetConfiguration(val configuration: SoftApConfigurationCompat) : RootCommand<ParcelableBoolean> {
override suspend fun execute() = ParcelableBoolean(WifiApManager.setConfiguration(configuration))
override suspend fun execute() = ParcelableBoolean(WifiApManager.setConfigurationCompat(configuration))
}
@Parcelize
@RequiresApi(30)
class StartLocalOnlyHotspot : RootCommandChannel<LocalOnlyHotspotCallbacks> {
override fun create(scope: CoroutineScope) = scope.produce(capacity = capacity) {
val finish = CompletableDeferred<Unit>()
var lohr: WifiManager.LocalOnlyHotspotReservation? = null
WifiApManager.startLocalOnlyHotspot(WifiApManager.configuration, object :
WifiManager.LocalOnlyHotspotCallback() {
private fun push(parcel: LocalOnlyHotspotCallbacks) {
trySend(parcel).onClosed {
finish.completeExceptionally(it ?: ClosedSendChannelException("Channel was closed normally"))
return
}.onFailure { throw it!! }
}
override fun onStarted(reservation: WifiManager.LocalOnlyHotspotReservation?) {
if (reservation == null) onFailed(-3) else {
require(lohr == null)
lohr = reservation
push(LocalOnlyHotspotCallbacks.OnStarted(reservation.softApConfiguration))
}
}
override fun onStopped() {
push(LocalOnlyHotspotCallbacks.OnStopped())
finish.complete(Unit)
}
override fun onFailed(reason: Int) {
push(LocalOnlyHotspotCallbacks.OnFailed(reason))
finish.complete(Unit)
}
}) {
scope.launch {
try {
it.run()
} catch (e: Throwable) {
finish.completeExceptionally(e)
}
}
}
try {
finish.await()
} catch (e: Exception) {
WifiApManager.cancelLocalOnlyHotspotRequest()
throw e
} finally {
lohr?.close()
}
}
}
}