Ensure receiver unregistered synchronously in onDestroy

This commit is contained in:
Mygod
2019-07-31 10:03:27 +08:00
parent 1f2ccf83b0
commit e55aa17399
3 changed files with 17 additions and 20 deletions

View File

@@ -126,7 +126,6 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
private val handler = Handler() private val handler = Handler()
@RequiresApi(28) @RequiresApi(28)
private var timeoutMonitor: TetherTimeoutMonitor? = null private var timeoutMonitor: TetherTimeoutMonitor? = null
private var receiverRegistered = false
private val receiver = broadcastReceiver { _, intent -> private val receiver = broadcastReceiver { _, intent ->
when (intent.action) { when (intent.action) {
WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION -> WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION ->
@@ -257,10 +256,9 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
if (Build.VERSION.SDK_INT >= 26 && app.uiMode.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION) { if (Build.VERSION.SDK_INT >= 26 && app.uiMode.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION) {
showNotification() showNotification()
} }
registerReceiver(receiver, intentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION,
WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION))
launch { launch {
registerReceiver(receiver, intentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION,
WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION))
receiverRegistered = true
try { try {
p2pManager.requestGroupInfo(channel) { p2pManager.requestGroupInfo(channel) {
when { when {
@@ -399,10 +397,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
}) })
} }
private fun cleanLocked() { private fun cleanLocked() {
if (receiverRegistered) { ensureReceiverUnregistered(receiver)
unregisterReceiver(receiver)
receiverRegistered = false
}
if (Build.VERSION.SDK_INT >= 28) { if (Build.VERSION.SDK_INT >= 28) {
timeoutMonitor?.close() timeoutMonitor?.close()
timeoutMonitor = null timeoutMonitor = null
@@ -417,6 +412,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
override fun onDestroy() { override fun onDestroy() {
handler.removeCallbacksAndMessages(null) handler.removeCallbacksAndMessages(null)
if (status != Status.IDLE) binder.shutdown() if (status != Status.IDLE) binder.shutdown()
ensureReceiverUnregistered(receiver)
launch { // force clean to prevent leakage launch { // force clean to prevent leakage
cleanLocked() cleanLocked()
cancel() cancel()

View File

@@ -10,6 +10,7 @@ import be.mygod.vpnhotspot.net.TetheringManager.tetheredIfaces
import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor
import be.mygod.vpnhotspot.util.Event0 import be.mygod.vpnhotspot.util.Event0
import be.mygod.vpnhotspot.util.broadcastReceiver import be.mygod.vpnhotspot.util.broadcastReceiver
import be.mygod.vpnhotspot.util.ensureReceiverUnregistered
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -46,7 +47,6 @@ class TetheringService : IpNeighbourMonitoringService(), CoroutineScope {
override val coroutineContext = dispatcher + Job() override val coroutineContext = dispatcher + Job()
private val binder = Binder() private val binder = Binder()
private val downstreams = ConcurrentHashMap<String, Downstream>() private val downstreams = ConcurrentHashMap<String, Downstream>()
private var receiverRegistered = false
private val receiver = broadcastReceiver { _, intent -> private val receiver = broadcastReceiver { _, intent ->
launch { launch {
val toRemove = downstreams.toMutableMap() // make a copy val toRemove = downstreams.toMutableMap() // make a copy
@@ -69,11 +69,8 @@ class TetheringService : IpNeighbourMonitoringService(), CoroutineScope {
ServiceNotification.stopForeground(this) ServiceNotification.stopForeground(this)
stopSelf() stopSelf()
} else { } else {
if (!receiverRegistered) { registerReceiver(receiver, IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED))
receiverRegistered = true IpNeighbourMonitor.registerCallback(this)
registerReceiver(receiver, IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED))
IpNeighbourMonitor.registerCallback(this)
}
updateNotification() updateNotification()
} }
launch(Dispatchers.Main) { binder.routingsChanged() } launch(Dispatchers.Main) { binder.routingsChanged() }
@@ -106,9 +103,9 @@ class TetheringService : IpNeighbourMonitoringService(), CoroutineScope {
} }
override fun onDestroy() { override fun onDestroy() {
unregisterReceiver()
launch { launch {
downstreams.values.forEach { it.destroy() } // force clean to prevent leakage downstreams.values.forEach { it.destroy() } // force clean to prevent leakage
unregisterReceiver()
cancel() cancel()
dispatcher.close() dispatcher.close()
} }
@@ -116,10 +113,7 @@ class TetheringService : IpNeighbourMonitoringService(), CoroutineScope {
} }
private fun unregisterReceiver() { private fun unregisterReceiver() {
if (receiverRegistered) { ensureReceiverUnregistered(receiver)
unregisterReceiver(receiver) IpNeighbourMonitor.unregisterCallback(this)
IpNeighbourMonitor.unregisterCallback(this)
receiverRegistered = false
}
} }
} }

View File

@@ -19,6 +19,7 @@ import androidx.databinding.BindingAdapter
import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.room.macToString import be.mygod.vpnhotspot.room.macToString
import be.mygod.vpnhotspot.widget.SmartSnackbar import be.mygod.vpnhotspot.widget.SmartSnackbar
import java.lang.IllegalArgumentException
import java.net.InetAddress import java.net.InetAddress
import java.net.NetworkInterface import java.net.NetworkInterface
import java.net.SocketException import java.net.SocketException
@@ -35,6 +36,12 @@ fun Long.toPluralInt(): Int {
return (this % 1000000000).toInt() + 1000000000 return (this % 1000000000).toInt() + 1000000000
} }
fun Context.ensureReceiverUnregistered(receiver: BroadcastReceiver) {
try {
unregisterReceiver(receiver)
} catch (_: IllegalArgumentException) { }
}
@SuppressLint("Recycle") @SuppressLint("Recycle")
fun <T> useParcel(block: (Parcel) -> T) = Parcel.obtain().run { fun <T> useParcel(block: (Parcel) -> T) = Parcel.obtain().run {
try { try {