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:
Mygod
2018-12-13 15:04:19 +08:00
parent 6002794905
commit ca1fc946ca
6 changed files with 43 additions and 21 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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