From 89a4e9f07190e09e3803823fca91f612e1580101 Mon Sep 17 00:00:00 2001 From: Mygod Date: Tue, 5 Feb 2019 17:27:33 +0800 Subject: [PATCH] Simplify WifiDoubleLock invocations --- .../mygod/vpnhotspot/LocalOnlyHotspotService.kt | 9 --------- .../java/be/mygod/vpnhotspot/RepeaterService.kt | 9 --------- .../java/be/mygod/vpnhotspot/RoutingManager.kt | 12 +++++++++--- .../vpnhotspot/SettingsPreferenceFragment.kt | 2 +- .../be/mygod/vpnhotspot/TetheringService.kt | 17 +++-------------- .../mygod/vpnhotspot/net/wifi/WifiDoubleLock.kt | 14 +++++++------- 6 files changed, 20 insertions(+), 43 deletions(-) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/LocalOnlyHotspotService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/LocalOnlyHotspotService.kt index f4551ac9..d3d84833 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/LocalOnlyHotspotService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/LocalOnlyHotspotService.kt @@ -8,7 +8,6 @@ import androidx.annotation.RequiresApi import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.net.TetheringManager import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor -import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock import be.mygod.vpnhotspot.util.StickyEvent1 import be.mygod.vpnhotspot.util.broadcastReceiver import be.mygod.vpnhotspot.widget.SmartSnackbar @@ -39,7 +38,6 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() { private val binder = Binder() private var reservation: WifiManager.LocalOnlyHotspotReservation? = null private var routingManager: RoutingManager? = null - private var locked = false private var receiverRegistered = false private val receiver = broadcastReceiver { _, intent -> val ifaces = TetheringManager.getLocalOnlyTetheredIfaces(intent.extras ?: return@broadcastReceiver) @@ -76,9 +74,6 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() { override fun onStarted(reservation: WifiManager.LocalOnlyHotspotReservation?) { if (reservation == null) onFailed(-2) else { this@LocalOnlyHotspotService.reservation = reservation - check(!locked) - WifiDoubleLock.acquire() - locked = true if (!receiverRegistered) { registerReceiver(receiver, IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED)) receiverRegistered = true @@ -135,10 +130,6 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() { private fun unregisterReceiver() { routingManager?.stop() routingManager = null - if (locked) { - WifiDoubleLock.release() - locked = false - } if (receiverRegistered) { unregisterReceiver(receiver) IpNeighbourMonitor.unregisterCallback(this) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt index 02648dc3..f5aaccd4 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt @@ -15,7 +15,6 @@ import android.os.Looper import androidx.annotation.StringRes import androidx.core.content.getSystemService import be.mygod.vpnhotspot.App.Companion.app -import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.deletePersistentGroup import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.netId @@ -133,7 +132,6 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere } } private var routingManager: RoutingManager? = null - private var locked = false var status = Status.IDLE private set(value) { @@ -277,9 +275,6 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere * startService Step 3 */ private fun doStart(group: WifiP2pGroup) { - check(!locked) - WifiDoubleLock.acquire() - locked = true binder.group = group check(routingManager == null) routingManager = RoutingManager.LocalOnly(this, group.`interface`!!).apply { initRouting() } @@ -316,10 +311,6 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere unregisterReceiver() routingManager?.stop() routingManager = null - if (locked) { - WifiDoubleLock.release() - locked = false - } status = Status.IDLE ServiceNotification.stopForeground(this) stopSelf() diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/RoutingManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/RoutingManager.kt index 42969b27..43ea6de3 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/RoutingManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/RoutingManager.kt @@ -2,10 +2,11 @@ package be.mygod.vpnhotspot import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.net.Routing +import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock import be.mygod.vpnhotspot.widget.SmartSnackbar import timber.log.Timber -abstract class RoutingManager(private val caller: Any, val downstream: String) { +abstract class RoutingManager(private val caller: Any, val downstream: String, private val isWifi: Boolean) { companion object { private const val KEY_MASQUERADE_MODE = "service.masqueradeMode" var masqueradeMode: Routing.MasqueradeMode @@ -17,7 +18,10 @@ abstract class RoutingManager(private val caller: Any, val downstream: String) { set(value) = app.pref.edit().putString(KEY_MASQUERADE_MODE, value.name).apply() } - class LocalOnly(caller: Any, downstream: String) : RoutingManager(caller, downstream) { + /** + * Both repeater and local-only hotspot are Wi-Fi based. + */ + class LocalOnly(caller: Any, downstream: String) : RoutingManager(caller, downstream, true) { override fun Routing.configure() { ipForward() // local only interfaces need to enable ip_forward forward() @@ -31,6 +35,7 @@ abstract class RoutingManager(private val caller: Any, val downstream: String) { init { app.onPreCleanRoutings[this] = { routing?.stop() } app.onRoutingsCleaned[this] = { initRouting() } + if (isWifi) WifiDoubleLock.acquire(this) } fun initRouting() = try { @@ -53,8 +58,9 @@ abstract class RoutingManager(private val caller: Any, val downstream: String) { protected abstract fun Routing.configure() fun stop() { + routing?.revert() + if (isWifi) WifiDoubleLock.release(this) app.onPreCleanRoutings -= this app.onRoutingsCleaned -= this - routing?.revert() } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt index da367a0e..7a1fb97b 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt @@ -28,7 +28,7 @@ import java.net.SocketException class SettingsPreferenceFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { preferenceManager.preferenceDataStore = SharedPreferenceDataStore(app.pref) - RoutingManager.masquerade = RoutingManager.masquerade // flush default value + RoutingManager.masqueradeMode = RoutingManager.masqueradeMode // flush default value addPreferencesFromResource(R.xml.pref_settings) val boot = findPreference("service.repeater.startOnBoot") as SwitchPreference if (RepeaterService.supported) { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/TetheringService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/TetheringService.kt index 39b2ff70..f79c7a8d 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/TetheringService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/TetheringService.kt @@ -7,7 +7,6 @@ import be.mygod.vpnhotspot.net.Routing import be.mygod.vpnhotspot.net.TetherType import be.mygod.vpnhotspot.net.TetheringManager import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor -import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock import be.mygod.vpnhotspot.util.Event0 import be.mygod.vpnhotspot.util.broadcastReceiver import kotlinx.coroutines.Dispatchers @@ -26,7 +25,8 @@ class TetheringService : IpNeighbourMonitoringService() { fun isActive(iface: String): Boolean = synchronized(downstreams) { downstreams.containsKey(iface) } } - inner class Downstream(caller: Any, downstream: String) : RoutingManager(caller, downstream) { + inner class Downstream(caller: Any, downstream: String) : + RoutingManager(caller, downstream, TetherType.ofInterface(downstream).isWifi) { override fun Routing.configure() { forward() masquerade(RoutingManager.masqueradeMode) @@ -37,7 +37,6 @@ class TetheringService : IpNeighbourMonitoringService() { private val binder = Binder() private val downstreams = mutableMapOf() - private var locked = false private var receiverRegistered = false private val receiver = broadcastReceiver { _, intent -> val extras = intent.extras ?: return@broadcastReceiver @@ -50,10 +49,6 @@ class TetheringService : IpNeighbourMonitoringService() { override val activeIfaces get() = synchronized(downstreams) { downstreams.keys.toList() } private fun updateRoutingsLocked() { - if (locked && downstreams.keys.all { !TetherType.ofInterface(it).isWifi }) { - WifiDoubleLock.release() - locked = false - } if (downstreams.isEmpty()) { unregisterReceiver() ServiceNotification.stopForeground(this) @@ -85,14 +80,10 @@ class TetheringService : IpNeighbourMonitoringService() { val ifaces = intent.getStringArrayExtra(EXTRA_ADD_INTERFACES) ?: emptyArray() synchronized(downstreams) { for (iface in ifaces) { - Downstream(this, iface).apply { + Downstream(this, iface).run { downstreams[iface] = this initRouting() } - if (TetherType.ofInterface(iface).isWifi && !locked) { - WifiDoubleLock.acquire() - locked = true - } } downstreams.remove(intent.getStringExtra(EXTRA_REMOVE_INTERFACE))?.stop() updateRoutingsLocked() @@ -110,8 +101,6 @@ class TetheringService : IpNeighbourMonitoringService() { private fun unregisterReceiver() { if (receiverRegistered) { unregisterReceiver(receiver) - app.onPreCleanRoutings -= this - app.onRoutingsCleaned -= this IpNeighbourMonitor.unregisterCallback(this) receiverRegistered = false } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiDoubleLock.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiDoubleLock.kt index b1831503..90c53a1e 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiDoubleLock.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiDoubleLock.kt @@ -17,20 +17,20 @@ class WifiDoubleLock(lockType: Int) : AutoCloseable { WifiDoubleLock.Mode.valueOf(app.pref.getString(KEY, WifiDoubleLock.Mode.Full.toString()) ?: "").lockType private val service by lazy { app.getSystemService()!! } - private var referenceCount = 0 + private var holders = mutableSetOf() private var lock: WifiDoubleLock? = null - fun acquire() = synchronized(this) { - if (referenceCount == 0) { + fun acquire(holder: Any) = synchronized(this) { + if (holders.isEmpty()) { app.pref.registerOnSharedPreferenceChangeListener(this) val lockType = lockType if (lockType != null) lock = WifiDoubleLock(lockType) } - referenceCount += 1 + check(holders.add(holder)) } - fun release() = synchronized(this) { - referenceCount -= 1 - if (referenceCount == 0) { + fun release(holder: Any) = synchronized(this) { + check(holders.remove(holder)) + if (holders.isEmpty()) { lock?.close() lock = null app.pref.unregisterOnSharedPreferenceChangeListener(this)