Improve quick settings tiles reliability
Android apparently can decide to kill TileService when there are too many. Therefore, let's check if our service is connected before doing anything. Source: https://android.googlesource.com/platform/frameworks/base/+/e1d13c9/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java#52
This commit is contained in:
@@ -3,7 +3,6 @@ package be.mygod.vpnhotspot.manage
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.IBinder
|
||||
import android.service.quicksettings.Tile
|
||||
@@ -14,7 +13,7 @@ import be.mygod.vpnhotspot.R
|
||||
import be.mygod.vpnhotspot.util.stopAndUnbind
|
||||
|
||||
@RequiresApi(26)
|
||||
class LocalOnlyHotspotTileService : TetherListeningTileService(), ServiceConnection {
|
||||
class LocalOnlyHotspotTileService : TetherListeningTileService() {
|
||||
private val tile by lazy { Icon.createWithResource(application, R.drawable.ic_device_wifi_tethering) }
|
||||
private var binder: LocalOnlyHotspotService.Binder? = null
|
||||
|
||||
@@ -30,13 +29,17 @@ class LocalOnlyHotspotTileService : TetherListeningTileService(), ServiceConnect
|
||||
|
||||
override fun onClick() {
|
||||
val binder = binder
|
||||
if (binder?.iface != null) binder.stop()
|
||||
else ContextCompat.startForegroundService(this, Intent(this, LocalOnlyHotspotService::class.java))
|
||||
when {
|
||||
binder == null -> tapPending = true
|
||||
binder.iface != null -> binder.stop()
|
||||
else -> ContextCompat.startForegroundService(this, Intent(this, LocalOnlyHotspotService::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder) {
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
binder = service as LocalOnlyHotspotService.Binder
|
||||
updateTile()
|
||||
super.onServiceConnected(name, service)
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
|
||||
@@ -3,20 +3,19 @@ package be.mygod.vpnhotspot.manage
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.graphics.drawable.Icon
|
||||
import android.net.wifi.p2p.WifiP2pGroup
|
||||
import android.os.IBinder
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.ContextCompat
|
||||
import be.mygod.vpnhotspot.R
|
||||
import be.mygod.vpnhotspot.RepeaterService
|
||||
import be.mygod.vpnhotspot.util.KillableTileService
|
||||
import be.mygod.vpnhotspot.util.stopAndUnbind
|
||||
|
||||
@RequiresApi(24)
|
||||
class RepeaterTileService : TileService(), ServiceConnection {
|
||||
class RepeaterTileService : KillableTileService() {
|
||||
private val tile by lazy { Icon.createWithResource(application, R.drawable.ic_action_settings_input_antenna) }
|
||||
|
||||
private var binder: RepeaterService.Binder? = null
|
||||
@@ -34,7 +33,7 @@ class RepeaterTileService : TileService(), ServiceConnection {
|
||||
|
||||
override fun onClick() {
|
||||
val binder = binder
|
||||
when (binder?.service?.status) {
|
||||
if (binder == null) tapPending = true else when (binder.service.status) {
|
||||
RepeaterService.Status.ACTIVE -> binder.shutdown()
|
||||
RepeaterService.Status.IDLE ->
|
||||
ContextCompat.startForegroundService(this, Intent(this, RepeaterService::class.java))
|
||||
@@ -42,10 +41,11 @@ class RepeaterTileService : TileService(), ServiceConnection {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder) {
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
binder = service as RepeaterService.Binder
|
||||
service.statusChanged[this] = { updateTile() }
|
||||
service.groupChanged[this] = this::updateTile
|
||||
super.onServiceConnected(name, service)
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package be.mygod.vpnhotspot.manage
|
||||
|
||||
import android.content.IntentFilter
|
||||
import android.service.quicksettings.TileService
|
||||
import androidx.annotation.RequiresApi
|
||||
import be.mygod.vpnhotspot.net.TetheringManager
|
||||
import be.mygod.vpnhotspot.util.KillableTileService
|
||||
import be.mygod.vpnhotspot.util.broadcastReceiver
|
||||
|
||||
@RequiresApi(24)
|
||||
abstract class TetherListeningTileService : TileService() {
|
||||
abstract class TetherListeningTileService : KillableTileService() {
|
||||
protected var tethered: List<String> = emptyList()
|
||||
|
||||
private val receiver = broadcastReceiver { _, intent ->
|
||||
|
||||
@@ -3,7 +3,6 @@ package be.mygod.vpnhotspot.manage
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.IBinder
|
||||
import android.service.quicksettings.Tile
|
||||
@@ -22,8 +21,7 @@ import java.io.IOException
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
|
||||
@RequiresApi(24)
|
||||
sealed class TetheringTileService : TetherListeningTileService(), ServiceConnection,
|
||||
TetheringManager.OnStartTetheringCallback {
|
||||
sealed class TetheringTileService : TetherListeningTileService(), TetheringManager.OnStartTetheringCallback {
|
||||
protected val tileOff by lazy { Icon.createWithResource(application, icon) }
|
||||
protected val tileOn by lazy { Icon.createWithResource(application, R.drawable.ic_quick_settings_tile_on) }
|
||||
|
||||
@@ -49,6 +47,7 @@ sealed class TetheringTileService : TetherListeningTileService(), ServiceConnect
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
binder = service as TetheringService.Binder
|
||||
service.routingsChanged[this] = { updateTile() }
|
||||
super.onServiceConnected(name, service)
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
@@ -89,10 +88,13 @@ sealed class TetheringTileService : TetherListeningTileService(), ServiceConnect
|
||||
override fun onClick() {
|
||||
val interested = interested
|
||||
if (interested.isEmpty()) safeInvoker { start() } else {
|
||||
val inactive = interested.filter { binder?.isActive(it) != true }
|
||||
if (inactive.isEmpty()) safeInvoker { stop() }
|
||||
else ContextCompat.startForegroundService(this, Intent(this, TetheringService::class.java)
|
||||
.putExtra(TetheringService.EXTRA_ADD_INTERFACES, inactive.toTypedArray()))
|
||||
val binder = binder
|
||||
if (binder == null) tapPending = true else {
|
||||
val inactive = interested.filter { !binder.isActive(it) }
|
||||
if (inactive.isEmpty()) safeInvoker { stop() }
|
||||
else ContextCompat.startForegroundService(this, Intent(this, TetheringService::class.java)
|
||||
.putExtra(TetheringService.EXTRA_ADD_INTERFACES, inactive.toTypedArray()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,10 +156,13 @@ sealed class TetheringTileService : TetherListeningTileService(), ServiceConnect
|
||||
}
|
||||
|
||||
override fun onClick() = if (tethering?.active == true) {
|
||||
val inactive = interested.filter { binder?.isActive(it) != true }
|
||||
if (inactive.isEmpty()) safeInvoker { stop() }
|
||||
else ContextCompat.startForegroundService(this, Intent(this, TetheringService::class.java)
|
||||
.putExtra(TetheringService.EXTRA_ADD_INTERFACES, inactive.toTypedArray()))
|
||||
val binder = binder
|
||||
if (binder == null) tapPending = true else {
|
||||
val inactive = interested.filter { !binder.isActive(it) }
|
||||
if (inactive.isEmpty()) safeInvoker { stop() }
|
||||
else ContextCompat.startForegroundService(this, Intent(this, TetheringService::class.java)
|
||||
.putExtra(TetheringService.EXTRA_ADD_INTERFACES, inactive.toTypedArray()))
|
||||
}
|
||||
} else safeInvoker { start() }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package be.mygod.vpnhotspot.util
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.ServiceConnection
|
||||
import android.os.IBinder
|
||||
import android.service.quicksettings.TileService
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
@RequiresApi(24)
|
||||
abstract class KillableTileService : TileService(), ServiceConnection {
|
||||
protected var tapPending = false
|
||||
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
if (tapPending) {
|
||||
tapPending = false
|
||||
onClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user