Skip to content

Commit

Permalink
Add device count to other tiles too
Browse files Browse the repository at this point in the history
  • Loading branch information
Mygod committed Jun 16, 2020
1 parent 6ae4207 commit 7b1f610
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package be.mygod.vpnhotspot.manage

import android.service.quicksettings.Tile
import androidx.annotation.RequiresApi
import be.mygod.vpnhotspot.R
import be.mygod.vpnhotspot.net.IpNeighbour
import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor
import be.mygod.vpnhotspot.util.KillableTileService

@RequiresApi(24)
abstract class IpNeighbourMonitoringTileService : KillableTileService(), IpNeighbourMonitor.Callback {
private var neighbours: Collection<IpNeighbour> = emptyList()
abstract fun updateTile()

override fun onStartListening() {
super.onStartListening()
IpNeighbourMonitor.registerCallback(this)
}

override fun onStopListening() {
IpNeighbourMonitor.unregisterCallback(this)
super.onStopListening()
}

protected fun Tile.subtitleDevices(filter: (String) -> Boolean) {
val size = neighbours
.filter { it.state != IpNeighbour.State.FAILED && filter(it.dev) }
.distinctBy { it.lladdr }
.size
if (size > 0) subtitle(resources.getQuantityString(
R.plurals.quick_settings_hotspot_secondary_label_num_devices, size, size))
}

override fun onIpNeighbourAvailable(neighbours: Collection<IpNeighbour>) {
this.neighbours = neighbours
updateTile()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import android.service.quicksettings.Tile
import androidx.annotation.RequiresApi
import be.mygod.vpnhotspot.LocalOnlyHotspotService
import be.mygod.vpnhotspot.R
import be.mygod.vpnhotspot.util.KillableTileService
import be.mygod.vpnhotspot.util.stopAndUnbind

@RequiresApi(26)
class LocalOnlyHotspotTileService : KillableTileService() {
class LocalOnlyHotspotTileService : IpNeighbourMonitoringTileService() {
private val tile by lazy { Icon.createWithResource(application, R.drawable.ic_action_perm_scan_wifi) }

private var binder: LocalOnlyHotspotService.Binder? = null
Expand All @@ -28,6 +27,24 @@ class LocalOnlyHotspotTileService : KillableTileService() {
super.onStopListening()
}

override fun updateTile() {
val binder = binder ?: return
qsTile?.run {
icon = tile
subtitle(null)
val iface = binder.iface
if (iface.isNullOrEmpty()) {
state = Tile.STATE_INACTIVE
label = getText(R.string.tethering_temp_hotspot)
} else {
state = Tile.STATE_ACTIVE
label = binder.configuration?.ssid ?: getText(R.string.tethering_temp_hotspot)
subtitleDevices { it == iface }
}
updateTile()
}
}

override fun onClick() {
val binder = binder
when {
Expand All @@ -39,19 +56,7 @@ class LocalOnlyHotspotTileService : KillableTileService() {

override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
binder = service as LocalOnlyHotspotService.Binder
service.ifaceChanged[this] = {
qsTile?.run {
icon = tile
if (it.isNullOrEmpty()) {
state = Tile.STATE_INACTIVE
label = getText(R.string.tethering_temp_hotspot)
} else {
state = Tile.STATE_ACTIVE
label = service.configuration?.ssid ?: getText(R.string.tethering_temp_hotspot)
}
updateTile()
}
}
service.ifaceChanged[this] = { updateTile() }
super.onServiceConnected(name, service)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import be.mygod.vpnhotspot.net.TetherType
import be.mygod.vpnhotspot.net.TetheringManager
import be.mygod.vpnhotspot.net.TetheringManager.tetheredIfaces
import be.mygod.vpnhotspot.net.wifi.WifiApManager
import be.mygod.vpnhotspot.util.KillableTileService
import be.mygod.vpnhotspot.util.broadcastReceiver
import be.mygod.vpnhotspot.util.readableMessage
import be.mygod.vpnhotspot.util.stopAndUnbind
Expand All @@ -26,14 +25,14 @@ import java.io.IOException
import java.lang.reflect.InvocationTargetException

@RequiresApi(24)
sealed class TetheringTileService : KillableTileService(), TetheringManager.StartTetheringCallback {
sealed class TetheringTileService : IpNeighbourMonitoringTileService(), TetheringManager.StartTetheringCallback {
protected val tileOff by lazy { Icon.createWithResource(application, icon) }
protected val tileOn by lazy { Icon.createWithResource(application, R.drawable.ic_quick_settings_tile_on) }

protected abstract val labelString: Int
protected abstract val tetherType: TetherType
protected open val icon get() = tetherType.icon
protected var tethered: List<String>? = null
private var tethered: List<String>? = null
protected val interested get() = tethered?.filter { TetherType.ofInterface(it) == tetherType }
protected var binder: TetheringService.Binder? = null

Expand Down Expand Up @@ -73,8 +72,9 @@ sealed class TetheringTileService : KillableTileService(), TetheringManager.Star
binder = null
}

protected open fun updateTile() {
override fun updateTile() {
qsTile?.run {
subtitle(null)
val interested = interested
when {
interested == null -> {
Expand All @@ -89,6 +89,7 @@ sealed class TetheringTileService : KillableTileService(), TetheringManager.Star
val binder = binder ?: return
state = Tile.STATE_ACTIVE
icon = if (interested.all(binder::isActive)) tileOn else tileOff
subtitleDevices(interested::contains)
}
}
label = getText(labelString)
Expand Down Expand Up @@ -172,6 +173,7 @@ sealed class TetheringTileService : KillableTileService(), TetheringManager.Star

override fun updateTile() {
qsTile?.run {
subtitle(null)
val interested = interested
if (interested == null) {
state = Tile.STATE_UNAVAILABLE
Expand All @@ -181,6 +183,7 @@ sealed class TetheringTileService : KillableTileService(), TetheringManager.Star
val binder = binder ?: return
state = Tile.STATE_ACTIVE
icon = if (interested.isNotEmpty() && interested.all(binder::isActive)) tileOn else tileOff
subtitleDevices(interested::contains)
}
false -> {
state = Tile.STATE_INACTIVE
Expand Down
7 changes: 5 additions & 2 deletions mobile/src/main/java/be/mygod/vpnhotspot/net/TetherType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ enum class TetherType(@DrawableRes val icon: Int) {
.map { it.toPattern() }

@RequiresApi(30)
private fun updateRegexs() {
private fun updateRegexs() = synchronized(this) {
if (!requiresUpdate) return@synchronized
requiresUpdate = false
TetheringManager.registerTetheringEventCallback(null, this)
val tethering = "com.android.networkstack.tethering" to app.packageManager.getResourcesForApplication(
Expand All @@ -59,7 +60,8 @@ enum class TetherType(@DrawableRes val icon: Int) {
}

@RequiresApi(30)
override fun onTetherableInterfaceRegexpsChanged(args: Array<out Any?>?) {
override fun onTetherableInterfaceRegexpsChanged(args: Array<out Any?>?) = synchronized(this) {
if (requiresUpdate) return@synchronized
Timber.i("onTetherableInterfaceRegexpsChanged: ${args?.contentToString()}")
TetheringManager.unregisterTetheringEventCallback(this)
requiresUpdate = true
Expand Down Expand Up @@ -92,6 +94,7 @@ enum class TetherType(@DrawableRes val icon: Int) {
iface == null -> NONE
iface == p2pDev -> WIFI_P2P
requiresUpdate -> {
Timber.d("requiresUpdate")
if (Build.VERSION.SDK_INT >= 30) updateRegexs() else error("unexpected requiresUpdate")
ofInterface(iface, p2pDev)
}
Expand Down

0 comments on commit 7b1f610

Please sign in to comment.