Simplify WifiDoubleLock invocations
This commit is contained in:
@@ -8,7 +8,6 @@ import androidx.annotation.RequiresApi
|
|||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.net.TetheringManager
|
import be.mygod.vpnhotspot.net.TetheringManager
|
||||||
import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor
|
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.StickyEvent1
|
||||||
import be.mygod.vpnhotspot.util.broadcastReceiver
|
import be.mygod.vpnhotspot.util.broadcastReceiver
|
||||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||||
@@ -39,7 +38,6 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() {
|
|||||||
private val binder = Binder()
|
private val binder = Binder()
|
||||||
private var reservation: WifiManager.LocalOnlyHotspotReservation? = null
|
private var reservation: WifiManager.LocalOnlyHotspotReservation? = null
|
||||||
private var routingManager: RoutingManager? = null
|
private var routingManager: RoutingManager? = null
|
||||||
private var locked = false
|
|
||||||
private var receiverRegistered = false
|
private var receiverRegistered = false
|
||||||
private val receiver = broadcastReceiver { _, intent ->
|
private val receiver = broadcastReceiver { _, intent ->
|
||||||
val ifaces = TetheringManager.getLocalOnlyTetheredIfaces(intent.extras ?: return@broadcastReceiver)
|
val ifaces = TetheringManager.getLocalOnlyTetheredIfaces(intent.extras ?: return@broadcastReceiver)
|
||||||
@@ -76,9 +74,6 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() {
|
|||||||
override fun onStarted(reservation: WifiManager.LocalOnlyHotspotReservation?) {
|
override fun onStarted(reservation: WifiManager.LocalOnlyHotspotReservation?) {
|
||||||
if (reservation == null) onFailed(-2) else {
|
if (reservation == null) onFailed(-2) else {
|
||||||
this@LocalOnlyHotspotService.reservation = reservation
|
this@LocalOnlyHotspotService.reservation = reservation
|
||||||
check(!locked)
|
|
||||||
WifiDoubleLock.acquire()
|
|
||||||
locked = true
|
|
||||||
if (!receiverRegistered) {
|
if (!receiverRegistered) {
|
||||||
registerReceiver(receiver, IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED))
|
registerReceiver(receiver, IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED))
|
||||||
receiverRegistered = true
|
receiverRegistered = true
|
||||||
@@ -135,10 +130,6 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() {
|
|||||||
private fun unregisterReceiver() {
|
private fun unregisterReceiver() {
|
||||||
routingManager?.stop()
|
routingManager?.stop()
|
||||||
routingManager = null
|
routingManager = null
|
||||||
if (locked) {
|
|
||||||
WifiDoubleLock.release()
|
|
||||||
locked = false
|
|
||||||
}
|
|
||||||
if (receiverRegistered) {
|
if (receiverRegistered) {
|
||||||
unregisterReceiver(receiver)
|
unregisterReceiver(receiver)
|
||||||
IpNeighbourMonitor.unregisterCallback(this)
|
IpNeighbourMonitor.unregisterCallback(this)
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import android.os.Looper
|
|||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
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
|
||||||
import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.deletePersistentGroup
|
import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.deletePersistentGroup
|
||||||
import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.netId
|
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 routingManager: RoutingManager? = null
|
||||||
private var locked = false
|
|
||||||
|
|
||||||
var status = Status.IDLE
|
var status = Status.IDLE
|
||||||
private set(value) {
|
private set(value) {
|
||||||
@@ -277,9 +275,6 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
|
|||||||
* startService Step 3
|
* startService Step 3
|
||||||
*/
|
*/
|
||||||
private fun doStart(group: WifiP2pGroup) {
|
private fun doStart(group: WifiP2pGroup) {
|
||||||
check(!locked)
|
|
||||||
WifiDoubleLock.acquire()
|
|
||||||
locked = true
|
|
||||||
binder.group = group
|
binder.group = group
|
||||||
check(routingManager == null)
|
check(routingManager == null)
|
||||||
routingManager = RoutingManager.LocalOnly(this, group.`interface`!!).apply { initRouting() }
|
routingManager = RoutingManager.LocalOnly(this, group.`interface`!!).apply { initRouting() }
|
||||||
@@ -316,10 +311,6 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
|
|||||||
unregisterReceiver()
|
unregisterReceiver()
|
||||||
routingManager?.stop()
|
routingManager?.stop()
|
||||||
routingManager = null
|
routingManager = null
|
||||||
if (locked) {
|
|
||||||
WifiDoubleLock.release()
|
|
||||||
locked = false
|
|
||||||
}
|
|
||||||
status = Status.IDLE
|
status = Status.IDLE
|
||||||
ServiceNotification.stopForeground(this)
|
ServiceNotification.stopForeground(this)
|
||||||
stopSelf()
|
stopSelf()
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ package be.mygod.vpnhotspot
|
|||||||
|
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.net.Routing
|
import be.mygod.vpnhotspot.net.Routing
|
||||||
|
import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock
|
||||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||||
import timber.log.Timber
|
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 {
|
companion object {
|
||||||
private const val KEY_MASQUERADE_MODE = "service.masqueradeMode"
|
private const val KEY_MASQUERADE_MODE = "service.masqueradeMode"
|
||||||
var masqueradeMode: Routing.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()
|
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() {
|
override fun Routing.configure() {
|
||||||
ipForward() // local only interfaces need to enable ip_forward
|
ipForward() // local only interfaces need to enable ip_forward
|
||||||
forward()
|
forward()
|
||||||
@@ -31,6 +35,7 @@ abstract class RoutingManager(private val caller: Any, val downstream: String) {
|
|||||||
init {
|
init {
|
||||||
app.onPreCleanRoutings[this] = { routing?.stop() }
|
app.onPreCleanRoutings[this] = { routing?.stop() }
|
||||||
app.onRoutingsCleaned[this] = { initRouting() }
|
app.onRoutingsCleaned[this] = { initRouting() }
|
||||||
|
if (isWifi) WifiDoubleLock.acquire(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun initRouting() = try {
|
fun initRouting() = try {
|
||||||
@@ -53,8 +58,9 @@ abstract class RoutingManager(private val caller: Any, val downstream: String) {
|
|||||||
protected abstract fun Routing.configure()
|
protected abstract fun Routing.configure()
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
|
routing?.revert()
|
||||||
|
if (isWifi) WifiDoubleLock.release(this)
|
||||||
app.onPreCleanRoutings -= this
|
app.onPreCleanRoutings -= this
|
||||||
app.onRoutingsCleaned -= this
|
app.onRoutingsCleaned -= this
|
||||||
routing?.revert()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import java.net.SocketException
|
|||||||
class SettingsPreferenceFragment : PreferenceFragmentCompat() {
|
class SettingsPreferenceFragment : PreferenceFragmentCompat() {
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
preferenceManager.preferenceDataStore = SharedPreferenceDataStore(app.pref)
|
preferenceManager.preferenceDataStore = SharedPreferenceDataStore(app.pref)
|
||||||
RoutingManager.masquerade = RoutingManager.masquerade // flush default value
|
RoutingManager.masqueradeMode = RoutingManager.masqueradeMode // flush default value
|
||||||
addPreferencesFromResource(R.xml.pref_settings)
|
addPreferencesFromResource(R.xml.pref_settings)
|
||||||
val boot = findPreference("service.repeater.startOnBoot") as SwitchPreference
|
val boot = findPreference("service.repeater.startOnBoot") as SwitchPreference
|
||||||
if (RepeaterService.supported) {
|
if (RepeaterService.supported) {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import be.mygod.vpnhotspot.net.Routing
|
|||||||
import be.mygod.vpnhotspot.net.TetherType
|
import be.mygod.vpnhotspot.net.TetherType
|
||||||
import be.mygod.vpnhotspot.net.TetheringManager
|
import be.mygod.vpnhotspot.net.TetheringManager
|
||||||
import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor
|
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.Event0
|
||||||
import be.mygod.vpnhotspot.util.broadcastReceiver
|
import be.mygod.vpnhotspot.util.broadcastReceiver
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -26,7 +25,8 @@ class TetheringService : IpNeighbourMonitoringService() {
|
|||||||
fun isActive(iface: String): Boolean = synchronized(downstreams) { downstreams.containsKey(iface) }
|
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() {
|
override fun Routing.configure() {
|
||||||
forward()
|
forward()
|
||||||
masquerade(RoutingManager.masqueradeMode)
|
masquerade(RoutingManager.masqueradeMode)
|
||||||
@@ -37,7 +37,6 @@ class TetheringService : IpNeighbourMonitoringService() {
|
|||||||
|
|
||||||
private val binder = Binder()
|
private val binder = Binder()
|
||||||
private val downstreams = mutableMapOf<String, Downstream>()
|
private val downstreams = mutableMapOf<String, Downstream>()
|
||||||
private var locked = false
|
|
||||||
private var receiverRegistered = false
|
private var receiverRegistered = false
|
||||||
private val receiver = broadcastReceiver { _, intent ->
|
private val receiver = broadcastReceiver { _, intent ->
|
||||||
val extras = intent.extras ?: return@broadcastReceiver
|
val extras = intent.extras ?: return@broadcastReceiver
|
||||||
@@ -50,10 +49,6 @@ class TetheringService : IpNeighbourMonitoringService() {
|
|||||||
override val activeIfaces get() = synchronized(downstreams) { downstreams.keys.toList() }
|
override val activeIfaces get() = synchronized(downstreams) { downstreams.keys.toList() }
|
||||||
|
|
||||||
private fun updateRoutingsLocked() {
|
private fun updateRoutingsLocked() {
|
||||||
if (locked && downstreams.keys.all { !TetherType.ofInterface(it).isWifi }) {
|
|
||||||
WifiDoubleLock.release()
|
|
||||||
locked = false
|
|
||||||
}
|
|
||||||
if (downstreams.isEmpty()) {
|
if (downstreams.isEmpty()) {
|
||||||
unregisterReceiver()
|
unregisterReceiver()
|
||||||
ServiceNotification.stopForeground(this)
|
ServiceNotification.stopForeground(this)
|
||||||
@@ -85,14 +80,10 @@ class TetheringService : IpNeighbourMonitoringService() {
|
|||||||
val ifaces = intent.getStringArrayExtra(EXTRA_ADD_INTERFACES) ?: emptyArray()
|
val ifaces = intent.getStringArrayExtra(EXTRA_ADD_INTERFACES) ?: emptyArray()
|
||||||
synchronized(downstreams) {
|
synchronized(downstreams) {
|
||||||
for (iface in ifaces) {
|
for (iface in ifaces) {
|
||||||
Downstream(this, iface).apply {
|
Downstream(this, iface).run {
|
||||||
downstreams[iface] = this
|
downstreams[iface] = this
|
||||||
initRouting()
|
initRouting()
|
||||||
}
|
}
|
||||||
if (TetherType.ofInterface(iface).isWifi && !locked) {
|
|
||||||
WifiDoubleLock.acquire()
|
|
||||||
locked = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
downstreams.remove(intent.getStringExtra(EXTRA_REMOVE_INTERFACE))?.stop()
|
downstreams.remove(intent.getStringExtra(EXTRA_REMOVE_INTERFACE))?.stop()
|
||||||
updateRoutingsLocked()
|
updateRoutingsLocked()
|
||||||
@@ -110,8 +101,6 @@ class TetheringService : IpNeighbourMonitoringService() {
|
|||||||
private fun unregisterReceiver() {
|
private fun unregisterReceiver() {
|
||||||
if (receiverRegistered) {
|
if (receiverRegistered) {
|
||||||
unregisterReceiver(receiver)
|
unregisterReceiver(receiver)
|
||||||
app.onPreCleanRoutings -= this
|
|
||||||
app.onRoutingsCleaned -= this
|
|
||||||
IpNeighbourMonitor.unregisterCallback(this)
|
IpNeighbourMonitor.unregisterCallback(this)
|
||||||
receiverRegistered = false
|
receiverRegistered = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,20 +17,20 @@ class WifiDoubleLock(lockType: Int) : AutoCloseable {
|
|||||||
WifiDoubleLock.Mode.valueOf(app.pref.getString(KEY, WifiDoubleLock.Mode.Full.toString()) ?: "").lockType
|
WifiDoubleLock.Mode.valueOf(app.pref.getString(KEY, WifiDoubleLock.Mode.Full.toString()) ?: "").lockType
|
||||||
private val service by lazy { app.getSystemService<PowerManager>()!! }
|
private val service by lazy { app.getSystemService<PowerManager>()!! }
|
||||||
|
|
||||||
private var referenceCount = 0
|
private var holders = mutableSetOf<Any>()
|
||||||
private var lock: WifiDoubleLock? = null
|
private var lock: WifiDoubleLock? = null
|
||||||
|
|
||||||
fun acquire() = synchronized(this) {
|
fun acquire(holder: Any) = synchronized(this) {
|
||||||
if (referenceCount == 0) {
|
if (holders.isEmpty()) {
|
||||||
app.pref.registerOnSharedPreferenceChangeListener(this)
|
app.pref.registerOnSharedPreferenceChangeListener(this)
|
||||||
val lockType = lockType
|
val lockType = lockType
|
||||||
if (lockType != null) lock = WifiDoubleLock(lockType)
|
if (lockType != null) lock = WifiDoubleLock(lockType)
|
||||||
}
|
}
|
||||||
referenceCount += 1
|
check(holders.add(holder))
|
||||||
}
|
}
|
||||||
fun release() = synchronized(this) {
|
fun release(holder: Any) = synchronized(this) {
|
||||||
referenceCount -= 1
|
check(holders.remove(holder))
|
||||||
if (referenceCount == 0) {
|
if (holders.isEmpty()) {
|
||||||
lock?.close()
|
lock?.close()
|
||||||
lock = null
|
lock = null
|
||||||
app.pref.unregisterOnSharedPreferenceChangeListener(this)
|
app.pref.unregisterOnSharedPreferenceChangeListener(this)
|
||||||
|
|||||||
Reference in New Issue
Block a user