Simplify WifiDoubleLock invocations

This commit is contained in:
Mygod
2019-02-05 17:27:33 +08:00
parent 89559103bf
commit 89a4e9f071
6 changed files with 20 additions and 43 deletions

View File

@@ -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)

View File

@@ -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()

View File

@@ -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()
} }
} }

View File

@@ -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) {

View File

@@ -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
} }

View File

@@ -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)