Listen for persistent group changes

This commit is contained in:
Mygod
2018-12-21 15:58:52 +08:00
parent 7b8c3f5b73
commit 5281f14e0f
5 changed files with 47 additions and 42 deletions

View File

@@ -2,7 +2,6 @@ package be.mygod.vpnhotspot
import android.app.Service
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.net.NetworkInfo
import android.net.wifi.WpsInfo
@@ -58,6 +57,11 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
val service get() = this@RepeaterService
val active get() = status == Status.ACTIVE
val statusChanged = StickyEvent0()
var group: WifiP2pGroup? = null
set(value) {
field = value
groupChanged(value)
}
val groupChanged = StickyEvent1 { group }
fun startWps(pin: String? = null) {
@@ -92,38 +96,10 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
formatReason(R.string.repeater_reset_credentials_failure, reason)).show()
})
}
fun requestGroupUpdate() {
group = null
val channel = channel ?: return
val device = thisDevice ?: return
try {
p2pManager.requestPersistentGroupInfo(channel) {
val ownedGroups = it.filter { it.isGroupOwner && it.owner.deviceAddress == device.deviceAddress }
val main = ownedGroups.minBy { it.netId }
group = main
if (main != null) ownedGroups.filter { it.netId != main.netId }.forEach {
p2pManager.deletePersistentGroup(channel, it.netId, object : WifiP2pManager.ActionListener {
override fun onSuccess() = Timber.i("Removed redundant owned group: $it")
override fun onFailure(reason: Int) = SmartSnackbar.make(
formatReason(R.string.repeater_clean_pog_failure, reason)).show()
})
}
}
} catch (e: ReflectiveOperationException) {
Timber.w(e)
SmartSnackbar.make(e).show()
}
}
}
private val p2pManager get() = RepeaterService.p2pManager!!
private var channel: WifiP2pManager.Channel? = null
var group: WifiP2pGroup? = null
private set(value) {
field = value
binder.groupChanged(value)
}
private val binder = Binder()
private var receiverRegistered = false
private val receiver = broadcastReceiver { _, intent ->
@@ -140,8 +116,13 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
private var routingManager: LocalOnlyInterfaceManager? = null
private var thisDevice: WifiP2pDevice? = null
private val thisDeviceListener = broadcastReceiver { _, intent ->
thisDevice = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)
private val deviceListener = broadcastReceiver { _, intent ->
when (intent.action) {
WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION -> {
thisDevice = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)
}
WifiP2pManagerHelper.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION -> onPersistentGroupsChanged()
}
}
var status = Status.IDLE
@@ -164,8 +145,9 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
override fun onCreate() {
super.onCreate()
registerReceiver(thisDeviceListener, IntentFilter(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION))
onChannelDisconnected()
registerReceiver(deviceListener, intentFilter(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION,
WifiP2pManagerHelper.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION))
app.pref.registerOnSharedPreferenceChangeListener(this)
}
@@ -194,7 +176,6 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
if (status != Status.DESTROYED) try {
channel = p2pManager.initialize(this, Looper.getMainLooper(), this)
setOperatingChannel()
binder.requestGroupUpdate()
} catch (e: RuntimeException) {
Timber.w(e)
app.handler.postDelayed(1000, this, this::onChannelDisconnected)
@@ -205,6 +186,29 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
if (key == App.KEY_OPERATING_CHANNEL) setOperatingChannel()
}
private fun onPersistentGroupsChanged() {
val channel = channel ?: return
val device = thisDevice ?: return
try {
p2pManager.requestPersistentGroupInfo(channel) {
val ownedGroups = it.filter { it.isGroupOwner && it.owner.deviceAddress == device.deviceAddress }
val main = ownedGroups.minBy { it.netId }
// do not replace current group if it's better
if (binder.group?.passphrase == null) binder.group = main
if (main != null) ownedGroups.filter { it.netId != main.netId }.forEach {
p2pManager.deletePersistentGroup(channel, it.netId, object : WifiP2pManager.ActionListener {
override fun onSuccess() = Timber.i("Removed redundant owned group: $it")
override fun onFailure(reason: Int) = SmartSnackbar.make(
formatReason(R.string.repeater_clean_pog_failure, reason)).show()
})
}
}
} catch (e: ReflectiveOperationException) {
Timber.w(e)
SmartSnackbar.make(e).show()
}
}
/**
* startService Step 1
*/
@@ -248,7 +252,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
if (routingManager != null) clean() // P2P shutdown, else other groups changing before start, ignore
}
routingManager != null -> {
this.group = group
binder.group = group
showNotification(group)
}
else -> doStart(group)
@@ -258,7 +262,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
* startService Step 3
*/
private fun doStart(group: WifiP2pGroup) {
this.group = group
binder.group = group
check(routingManager == null)
routingManager = LocalOnlyInterfaceManager(group.`interface`!!)
status = Status.ACTIVE
@@ -304,9 +308,9 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
if (status != Status.IDLE) binder.shutdown()
clean() // force clean to prevent leakage
app.pref.unregisterOnSharedPreferenceChangeListener(this)
unregisterReceiver(deviceListener)
status = Status.DESTROYED
if (Build.VERSION.SDK_INT >= 27) channel?.close()
unregisterReceiver(thisDeviceListener)
super.onDestroy()
}
}

View File

@@ -56,7 +56,7 @@ class RepeaterTileService : TileService(), ServiceConnection {
binder.groupChanged -= this
}
private fun updateTile(group: WifiP2pGroup? = binder?.service?.group) {
private fun updateTile(group: WifiP2pGroup? = binder?.group) {
val qsTile = qsTile ?: return
when (binder?.service?.status) {
RepeaterService.Status.IDLE -> {

View File

@@ -30,7 +30,7 @@ class ClientViewModel : ViewModel(), ServiceConnection, IpNeighbourMonitor.Callb
private fun populateClients() {
val clients = HashMap<Pair<String, String>, Client>()
val group = repeater?.service?.group
val group = repeater?.group
val p2pInterface = group?.`interface`
if (p2pInterface != null) {
for (client in p2p) clients[Pair(p2pInterface, client.deviceAddress)] = WifiP2pClient(p2pInterface, client)
@@ -50,7 +50,7 @@ class ClientViewModel : ViewModel(), ServiceConnection, IpNeighbourMonitor.Callb
private fun refreshP2p() {
val repeater = repeater
p2p = (if (repeater?.active != true) null else repeater.service.group?.clientList) ?: emptyList()
p2p = (if (repeater?.active != true) null else repeater.group?.clientList) ?: emptyList()
populateClients()
}

View File

@@ -42,7 +42,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
else -> false
}
val ssid @Bindable get() = binder?.service?.group?.networkName ?: ""
val ssid @Bindable get() = binder?.group?.networkName ?: ""
val addresses: CharSequence @Bindable get() {
return try {
NetworkInterface.getByName(p2pInterface ?: return "")?.formatAddresses() ?: ""
@@ -90,7 +90,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
fun editConfigurations() {
val binder = binder
val group = binder?.service?.group
val group = binder?.group
val ssid = group?.networkName
if (ssid != null) {
val wifi = WifiConfiguration()
@@ -171,7 +171,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
DialogInterface.BUTTON_POSITIVE -> try {
data.getParcelableExtra<P2pSupplicantConfiguration>(WifiP2pDialogFragment.KEY_CONFIGURER)
.update(data.getParcelableExtra(WifiP2pDialogFragment.KEY_CONFIGURATION))
app.handler.postDelayed(binder!!::requestGroupUpdate, 1000)
binder!!.group = null
} catch (e: Exception) {
Timber.w(e)
SmartSnackbar.make(e).show()

View File

@@ -10,6 +10,7 @@ import java.lang.reflect.Proxy
object WifiP2pManagerHelper {
const val UNSUPPORTED = -2
const val WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION = "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED"
/**
* Available since Android 4.4.