Refactor using ViewModel

This commit is contained in:
Mygod
2018-12-21 14:53:12 +08:00
parent e9421fd24f
commit f1db0f2c8f
6 changed files with 34 additions and 65 deletions

View File

@@ -0,0 +1,85 @@
package be.mygod.vpnhotspot.client
import android.content.ComponentName
import android.content.IntentFilter
import android.content.ServiceConnection
import android.net.wifi.p2p.WifiP2pDevice
import android.os.IBinder
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.RepeaterService
import be.mygod.vpnhotspot.net.IpNeighbour
import be.mygod.vpnhotspot.net.TetheringManager
import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor
import be.mygod.vpnhotspot.util.broadcastReceiver
class ClientViewModel : ViewModel(), ServiceConnection, IpNeighbourMonitor.Callback {
private var tetheredInterfaces = emptySet<String>()
private val receiver = broadcastReceiver { _, intent ->
val extras = intent.extras ?: return@broadcastReceiver
tetheredInterfaces = TetheringManager.getTetheredIfaces(extras).toSet() +
TetheringManager.getLocalOnlyTetheredIfaces(extras)
populateClients()
}
private var repeater: RepeaterService.Binder? = null
private var p2p: Collection<WifiP2pDevice> = emptyList()
private var neighbours = emptyList<IpNeighbour>()
val clients = MutableLiveData<List<Client>>()
private fun populateClients() {
val clients = HashMap<Pair<String, String>, Client>()
val group = repeater?.service?.group
val p2pInterface = group?.`interface`
if (p2pInterface != null) {
for (client in p2p) clients[Pair(p2pInterface, client.deviceAddress)] = WifiP2pClient(p2pInterface, client)
}
for (neighbour in neighbours) {
val key = Pair(neighbour.dev, neighbour.lladdr)
var client = clients[key]
if (client == null) {
if (!tetheredInterfaces.contains(neighbour.dev)) continue
client = TetheringClient(neighbour)
clients[key] = client
}
client.ip += Pair(neighbour.ip, neighbour.state)
}
this.clients.postValue(clients.values.sortedWith(compareBy<Client> { it.iface }.thenBy { it.mac }))
}
private fun refreshP2p() {
val repeater = repeater
p2p = (if (repeater?.active != true) null else repeater.service.group?.clientList) ?: emptyList()
populateClients()
}
init {
app.registerReceiver(receiver, IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED))
IpNeighbourMonitor.registerCallback(this)
}
override fun onCleared() {
IpNeighbourMonitor.unregisterCallback(this)
app.unregisterReceiver(receiver)
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val binder = service as RepeaterService.Binder
repeater = binder
binder.statusChanged[this] = this::refreshP2p
binder.groupChanged[this] = { refreshP2p() }
}
override fun onServiceDisconnected(name: ComponentName?) {
val binder = repeater ?: return
repeater = null
binder.statusChanged -= this
binder.groupChanged -= this
}
override fun onIpNeighbourAvailable(neighbours: List<IpNeighbour>) {
this.neighbours = neighbours
populateClients()
}
}