diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotTileService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotTileService.kt index 0b0c3bb9..4a25d31b 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotTileService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotTileService.kt @@ -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?) { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterTileService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterTileService.kt index 48dbf05c..e00e3f41 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterTileService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterTileService.kt @@ -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?) { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetherListeningTileService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetherListeningTileService.kt index 1e29589f..a4f5b2d3 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetherListeningTileService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetherListeningTileService.kt @@ -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 = emptyList() private val receiver = broadcastReceiver { _, intent -> diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringTileService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringTileService.kt index d8c452a9..9106bb86 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringTileService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringTileService.kt @@ -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() } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/util/KillableTileService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/util/KillableTileService.kt new file mode 100644 index 00000000..507f1c2c --- /dev/null +++ b/mobile/src/main/java/be/mygod/vpnhotspot/util/KillableTileService.kt @@ -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() + } + } +}