Remove repeater from UI if it's not supported
This could happen on devices like Chrome OS and Android emulators.
This commit is contained in:
@@ -27,6 +27,8 @@ class BootReceiver : BroadcastReceiver() {
|
||||
Intent.ACTION_BOOT_COMPLETED, Intent.ACTION_LOCKED_BOOT_COMPLETED -> started = true
|
||||
else -> return
|
||||
}
|
||||
ContextCompat.startForegroundService(context, Intent(context, RepeaterService::class.java))
|
||||
if (RepeaterService.supported) {
|
||||
ContextCompat.startForegroundService(context, Intent(context, RepeaterService::class.java))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,28 @@ import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||
import timber.log.Timber
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
|
||||
/**
|
||||
* Service for handling Wi-Fi P2P. `supported` must be checked before this service is started otherwise it would crash.
|
||||
*/
|
||||
class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
companion object {
|
||||
private const val TAG = "RepeaterService"
|
||||
/**
|
||||
* This is only a "ServiceConnection" to system service and its impact on system is minimal.
|
||||
*/
|
||||
private val p2pManager: WifiP2pManager? by lazy {
|
||||
try {
|
||||
app.getSystemService<WifiP2pManager>()
|
||||
} catch (e: RuntimeException) {
|
||||
Timber.w(e)
|
||||
null
|
||||
}
|
||||
}
|
||||
val supported get() = p2pManager != null
|
||||
}
|
||||
|
||||
enum class Status {
|
||||
IDLE, STARTING, ACTIVE
|
||||
IDLE, STARTING, ACTIVE, DESTROYED
|
||||
}
|
||||
|
||||
inner class Binder : android.os.Binder() {
|
||||
@@ -92,7 +107,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var p2pManager: WifiP2pManager
|
||||
private val p2pManager get() = RepeaterService.p2pManager!!
|
||||
private var channel: WifiP2pManager.Channel? = null
|
||||
var group: WifiP2pGroup? = null
|
||||
private set(value) {
|
||||
@@ -138,12 +153,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
try {
|
||||
p2pManager = getSystemService()!!
|
||||
onChannelDisconnected()
|
||||
} catch (e: RuntimeException) {
|
||||
Timber.w(e)
|
||||
}
|
||||
onChannelDisconnected()
|
||||
app.pref.registerOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
||||
@@ -169,7 +179,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
|
||||
|
||||
override fun onChannelDisconnected() {
|
||||
channel = null
|
||||
try {
|
||||
if (status != Status.DESTROYED) try {
|
||||
channel = p2pManager.initialize(this, Looper.getMainLooper(), this)
|
||||
setOperatingChannel()
|
||||
binder.requestGroupUpdate()
|
||||
@@ -282,6 +292,8 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, SharedPrefere
|
||||
if (status != Status.IDLE) binder.shutdown()
|
||||
clean() // force clean to prevent leakage
|
||||
app.pref.unregisterOnSharedPreferenceChangeListener(this)
|
||||
status = Status.DESTROYED
|
||||
channel?.close()
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,12 +22,14 @@ class RepeaterTileService : TileService(), ServiceConnection {
|
||||
|
||||
override fun onStartListening() {
|
||||
super.onStartListening()
|
||||
bindService(Intent(this, RepeaterService::class.java), this, Context.BIND_AUTO_CREATE)
|
||||
if (RepeaterService.supported) {
|
||||
bindService(Intent(this, RepeaterService::class.java), this, Context.BIND_AUTO_CREATE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStopListening() {
|
||||
super.onStopListening()
|
||||
stopAndUnbind(this)
|
||||
if (RepeaterService.supported) stopAndUnbind(this)
|
||||
}
|
||||
|
||||
override fun onClick() {
|
||||
@@ -72,7 +74,7 @@ class RepeaterTileService : TileService(), ServiceConnection {
|
||||
qsTile.icon = tileOn
|
||||
qsTile.label = group?.networkName
|
||||
}
|
||||
null -> {
|
||||
else -> { // null or DESTROYED, which should never occur
|
||||
qsTile.state = Tile.STATE_UNAVAILABLE
|
||||
qsTile.icon = tileOff
|
||||
qsTile.label = getString(R.string.title_repeater)
|
||||
|
||||
@@ -32,11 +32,13 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
|
||||
preferenceManager.preferenceDataStore = SharedPreferenceDataStore(app.pref)
|
||||
addPreferencesFromResource(R.xml.pref_settings)
|
||||
val boot = findPreference("service.repeater.startOnBoot") as SwitchPreference
|
||||
boot.setOnPreferenceChangeListener { _, value ->
|
||||
BootReceiver.enabled = value as Boolean
|
||||
true
|
||||
}
|
||||
boot.isChecked = BootReceiver.enabled
|
||||
if (RepeaterService.supported) {
|
||||
boot.setOnPreferenceChangeListener { _, value ->
|
||||
BootReceiver.enabled = value as Boolean
|
||||
true
|
||||
}
|
||||
boot.isChecked = BootReceiver.enabled
|
||||
} else boot.parent!!.removePreference(boot)
|
||||
findPreference("service.clean").setOnPreferenceClickListener {
|
||||
val cleaned = try {
|
||||
Routing.clean()
|
||||
|
||||
@@ -64,7 +64,9 @@ class ClientMonitorService : Service(), ServiceConnection, IpNeighbourMonitor.Ca
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
bindService(Intent(this, RepeaterService::class.java), this, Context.BIND_AUTO_CREATE)
|
||||
if (RepeaterService.supported) {
|
||||
bindService(Intent(this, RepeaterService::class.java), this, Context.BIND_AUTO_CREATE)
|
||||
}
|
||||
IpNeighbourMonitor.registerCallback(this)
|
||||
registerReceiver(receiver, IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED))
|
||||
}
|
||||
@@ -72,7 +74,7 @@ class ClientMonitorService : Service(), ServiceConnection, IpNeighbourMonitor.Ca
|
||||
override fun onDestroy() {
|
||||
unregisterReceiver(receiver)
|
||||
IpNeighbourMonitor.unregisterCallback(this)
|
||||
stopAndUnbind(this)
|
||||
if (RepeaterService.supported) stopAndUnbind(this)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import be.mygod.vpnhotspot.LocalOnlyHotspotService
|
||||
import be.mygod.vpnhotspot.R
|
||||
import be.mygod.vpnhotspot.RepeaterService
|
||||
import be.mygod.vpnhotspot.TetheringService
|
||||
import be.mygod.vpnhotspot.databinding.FragmentTetheringBinding
|
||||
import be.mygod.vpnhotspot.net.TetherType
|
||||
@@ -59,7 +60,8 @@ class TetheringFragment : Fragment(), ServiceConnection {
|
||||
this@TetheringFragment.enabledTypes =
|
||||
(activeIfaces + localOnlyIfaces).map { TetherType.ofInterface(it) }.toSet()
|
||||
|
||||
val list = arrayListOf<Manager>(repeaterManager)
|
||||
val list = ArrayList<Manager>()
|
||||
if (RepeaterService.supported) list.add(repeaterManager)
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
list.add(localOnlyHotspotManager)
|
||||
localOnlyHotspotManager.update()
|
||||
|
||||
Reference in New Issue
Block a user