Add starting state to temp hotspot

This commit is contained in:
Mygod
2018-12-28 14:18:02 +08:00
parent e5b3e7e5d0
commit 7eec6f7a06
6 changed files with 49 additions and 27 deletions

View File

@@ -5,10 +5,10 @@ import android.content.IntentFilter
import android.net.wifi.WifiManager
import androidx.annotation.RequiresApi
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.manage.LocalOnlyHotspotManager
import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor
import be.mygod.vpnhotspot.net.TetheringManager
import be.mygod.vpnhotspot.net.monitor.IpNeighbourMonitor
import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock
import be.mygod.vpnhotspot.util.StickyEvent1
import be.mygod.vpnhotspot.util.broadcastReceiver
import be.mygod.vpnhotspot.widget.SmartSnackbar
import timber.log.Timber
@@ -20,8 +20,16 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() {
}
inner class Binder : android.os.Binder() {
var manager: LocalOnlyHotspotManager? = null
/**
* null represents IDLE, "" represents CONNECTING, "something" represents CONNECTED.
*/
var iface: String? = null
set(value) {
field = value
ifaceChanged(value)
}
val ifaceChanged = StickyEvent1 { iface }
val configuration get() = reservation?.wifiConfiguration
fun stop() = reservation?.close()
@@ -39,7 +47,7 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() {
check(ifaces.size <= 1)
val iface = ifaces.singleOrNull()
binder.iface = iface
if (iface == null) {
if (iface.isNullOrEmpty()) {
unregisterReceiver()
ServiceNotification.stopForeground(this)
stopSelf()
@@ -50,13 +58,13 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() {
IpNeighbourMonitor.registerCallback(this)
} else check(iface == routingManager.downstream)
}
app.handler.post { binder.manager?.update() }
}
override val activeIfaces get() = listOfNotNull(binder.iface)
override fun onBind(intent: Intent?) = binder
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
binder.iface = ""
// throws IllegalStateException if the caller attempts to start the LocalOnlyHotspot while they
// have an outstanding request.
// https://android.googlesource.com/platform/frameworks/opt/net/wifi/+/53e0284/service/java/com/android/server/wifi/WifiServiceImpl.java#1192
@@ -111,6 +119,7 @@ class LocalOnlyHotspotService : IpNeighbourMonitoringService() {
}
private fun startFailure() {
binder.iface = null
updateNotification()
ServiceNotification.stopForeground(this@LocalOnlyHotspotService)
stopSelf()

View File

@@ -7,5 +7,6 @@ abstract class Data : BaseObservable() {
abstract val title: CharSequence
abstract val text: CharSequence
abstract val active: Boolean
open val enabled get() = true
open val selectable get() = true
}

View File

@@ -89,6 +89,7 @@ class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager()
return lookup[binder?.iface ?: return ""]?.formatAddresses() ?: ""
}
override val active get() = binder?.iface != null
override val enabled get() = binder?.iface != ""
override val selectable get() = active
}
@@ -110,12 +111,11 @@ class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager()
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
binder = service as LocalOnlyHotspotService.Binder
service.manager = this
update()
service.ifaceChanged[this] = { data.notifyChange() }
}
override fun onServiceDisconnected(name: ComponentName?) {
binder?.manager = null
binder?.ifaceChanged?.remove(this)
binder = null
}
}

View File

@@ -10,11 +10,13 @@ import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
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 : TetherListeningTileService() {
class LocalOnlyHotspotTileService : KillableTileService() {
private val tile by lazy { Icon.createWithResource(application, R.drawable.ic_device_wifi_tethering) }
private var binder: LocalOnlyHotspotService.Binder? = null
override fun onStartListening() {
@@ -29,29 +31,41 @@ class LocalOnlyHotspotTileService : TetherListeningTileService() {
override fun onClick() {
val binder = binder
when {
binder == null -> tapPending = true
binder.iface != null -> binder.stop()
else -> ContextCompat.startForegroundService(this, Intent(this, LocalOnlyHotspotService::class.java))
if (binder == null) tapPending = true
else when (binder.iface) {
null -> ContextCompat.startForegroundService(this, Intent(this, LocalOnlyHotspotService::class.java))
"" -> { } // STARTING, ignored
else -> binder.stop()
}
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
binder = service as LocalOnlyHotspotService.Binder
updateTile()
service.ifaceChanged[this] = {
qsTile?.run {
icon = tile
when (it) {
null -> {
state = Tile.STATE_INACTIVE
label = getText(R.string.tethering_temp_hotspot)
}
"" -> {
state = Tile.STATE_UNAVAILABLE
label = getText(R.string.tethering_temp_hotspot)
}
else -> {
state = Tile.STATE_ACTIVE
label = service.configuration!!.SSID
}
}
updateTile()
}
}
super.onServiceConnected(name, service)
}
override fun onServiceDisconnected(name: ComponentName?) {
binder?.ifaceChanged?.remove(this)
binder = null
}
override fun updateTile() {
qsTile?.run {
state = if ((binder ?: return).iface == null) Tile.STATE_INACTIVE else Tile.STATE_ACTIVE
icon = tile
label = getText(R.string.tethering_temp_hotspot)
updateTile()
}
}
}

View File

@@ -62,10 +62,7 @@ class TetheringFragment : Fragment(), ServiceConnection {
val list = ArrayList<Manager>()
if (RepeaterService.supported) list.add(repeaterManager)
if (Build.VERSION.SDK_INT >= 26) {
list.add(localOnlyHotspotManager)
localOnlyHotspotManager.update()
}
if (Build.VERSION.SDK_INT >= 26) list.add(localOnlyHotspotManager)
list.addAll(activeIfaces.map { InterfaceManager(this@TetheringFragment, it) }.sortedBy { it.iface })
list.add(ManageBar)
if (Build.VERSION.SDK_INT >= 24) {

View File

@@ -55,6 +55,7 @@
android:checked="@{data.active}"
android:clickable="false"
android:ellipsize="end"
android:enabled="@{data.enabled}"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center_vertical"/>