Skip to content

Instantly share code, notes, and snippets.

@vladimirpetrovski
Last active July 22, 2020 10:05
Show Gist options
  • Select an option

  • Save vladimirpetrovski/d7435d8ffea8780dc8d76c33007fa5a6 to your computer and use it in GitHub Desktop.

Select an option

Save vladimirpetrovski/d7435d8ffea8780dc8d76c33007fa5a6 to your computer and use it in GitHub Desktop.
class WifiConnectionViewModel(
private val context: Context,
wifiScanUseCase: WiFiScanUseCase,
private val wifiConnectUseCase: WiFiConnectDockUseCase,
private val wifiConnectLegacyUseCase: WiFiConnectDockLegacyUseCase,
private val wifiDisconnectUseCase: WiFiDisconnectDockUseCase
) : ViewModel() {
private val disposables = CompositeDisposable();
private var networkCallback: ConnectivityManager.NetworkCallback? = null
init {
disposables.add(
findDockUseCase()
.andThen(connect())
.doOnSuccess { lockNetwork(it) }
// here, once connected, we usually communicate with the device
.doOnSuccess { unlockNetwork() }
.doOnTerminate { disconnectDockUseCase(networkCallback) }
.doOnTerminate { networkCallback = null }
.subscribe({
Timber.v("Successfully finished test.")
}, {
Timber.v("Test failed: ${it.message}")
})
)
}
private fun connect(): Single<Network> {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
connectDockUseCase()
.doOnSuccess { networkCallback = it.second }
.map { it.first }
} else {
connectDockLegacyUseCase()
}
}
private fun lockNetwork(it: Network) {
Timber.v("Binding process to network")
context.bindProcessToNetwork(it)
}
private fun unlockNetwork() {
Timber.v("Unbinding process to network")
context.unbindProcessToNetwork()
}
override fun onCleared() {
super.onCleared()
disposables.clear()
}
}
/**
* If the network doesn't have internet connectivity network, requests will not be routed to it.
* To direct all the network requests from your app to an external Wi-Fi device bind a network using
* this function and all traffic will be routed to this network even if it has not internet connection.
*
* Call Context#unbindProcessToNetwork an extension function in order to unbind.
*/
fun Context.bindProcessToNetwork(network: Network) {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManager.bindProcessToNetwork(network)
} else {
ConnectivityManager.setProcessDefaultNetwork(network)
}
}
/**
* To unbind direction of all network requests and let the system decide which the traffic channel
* will use if there is no internet connection.
*/
fun Context.unbindProcessToNetwork() {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManager.bindProcessToNetwork(null)
} else {
ConnectivityManager.setProcessDefaultNetwork(null)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment