From e55aa173998d0a3cf68e5d3067a2808f1f3dbce0 Mon Sep 17 00:00:00 2001 From: Mygod Date: Wed, 31 Jul 2019 10:03:27 +0800 Subject: [PATCH] Ensure receiver unregistered synchronously in onDestroy --- .../be/mygod/vpnhotspot/RepeaterService.kt | 12 ++++-------- .../be/mygod/vpnhotspot/TetheringService.kt | 18 ++++++------------ .../java/be/mygod/vpnhotspot/util/Utils.kt | 7 +++++++ 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt index ce123249..7084f982 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt @@ -126,7 +126,6 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene private val handler = Handler() @RequiresApi(28) private var timeoutMonitor: TetherTimeoutMonitor? = null - private var receiverRegistered = false private val receiver = broadcastReceiver { _, intent -> when (intent.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) { showNotification() } + registerReceiver(receiver, intentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION, + WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) launch { - registerReceiver(receiver, intentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION, - WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) - receiverRegistered = true try { p2pManager.requestGroupInfo(channel) { when { @@ -399,10 +397,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene }) } private fun cleanLocked() { - if (receiverRegistered) { - unregisterReceiver(receiver) - receiverRegistered = false - } + ensureReceiverUnregistered(receiver) if (Build.VERSION.SDK_INT >= 28) { timeoutMonitor?.close() timeoutMonitor = null @@ -417,6 +412,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene override fun onDestroy() { handler.removeCallbacksAndMessages(null) if (status != Status.IDLE) binder.shutdown() + ensureReceiverUnregistered(receiver) launch { // force clean to prevent leakage cleanLocked() cancel() diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/TetheringService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/TetheringService.kt index 00004964..28367ff3 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/TetheringService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/TetheringService.kt @@ -10,6 +10,7 @@ import be.mygod.vpnhotspot.net.TetheringManager.tetheredIfaces import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor import be.mygod.vpnhotspot.util.Event0 import be.mygod.vpnhotspot.util.broadcastReceiver +import be.mygod.vpnhotspot.util.ensureReceiverUnregistered import kotlinx.coroutines.* import java.util.concurrent.ConcurrentHashMap @@ -46,7 +47,6 @@ class TetheringService : IpNeighbourMonitoringService(), CoroutineScope { override val coroutineContext = dispatcher + Job() private val binder = Binder() private val downstreams = ConcurrentHashMap() - private var receiverRegistered = false private val receiver = broadcastReceiver { _, intent -> launch { val toRemove = downstreams.toMutableMap() // make a copy @@ -69,11 +69,8 @@ class TetheringService : IpNeighbourMonitoringService(), CoroutineScope { ServiceNotification.stopForeground(this) stopSelf() } else { - if (!receiverRegistered) { - receiverRegistered = true - registerReceiver(receiver, IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED)) - IpNeighbourMonitor.registerCallback(this) - } + registerReceiver(receiver, IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED)) + IpNeighbourMonitor.registerCallback(this) updateNotification() } launch(Dispatchers.Main) { binder.routingsChanged() } @@ -106,9 +103,9 @@ class TetheringService : IpNeighbourMonitoringService(), CoroutineScope { } override fun onDestroy() { + unregisterReceiver() launch { downstreams.values.forEach { it.destroy() } // force clean to prevent leakage - unregisterReceiver() cancel() dispatcher.close() } @@ -116,10 +113,7 @@ class TetheringService : IpNeighbourMonitoringService(), CoroutineScope { } private fun unregisterReceiver() { - if (receiverRegistered) { - unregisterReceiver(receiver) - IpNeighbourMonitor.unregisterCallback(this) - receiverRegistered = false - } + ensureReceiverUnregistered(receiver) + IpNeighbourMonitor.unregisterCallback(this) } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt b/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt index 4d129b70..fa9df854 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt @@ -19,6 +19,7 @@ import androidx.databinding.BindingAdapter import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.room.macToString import be.mygod.vpnhotspot.widget.SmartSnackbar +import java.lang.IllegalArgumentException import java.net.InetAddress import java.net.NetworkInterface import java.net.SocketException @@ -35,6 +36,12 @@ fun Long.toPluralInt(): Int { return (this % 1000000000).toInt() + 1000000000 } +fun Context.ensureReceiverUnregistered(receiver: BroadcastReceiver) { + try { + unregisterReceiver(receiver) + } catch (_: IllegalArgumentException) { } +} + @SuppressLint("Recycle") fun useParcel(block: (Parcel) -> T) = Parcel.obtain().run { try {