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

View File

@@ -7,5 +7,6 @@ abstract class Data : BaseObservable() {
abstract val title: CharSequence abstract val title: CharSequence
abstract val text: CharSequence abstract val text: CharSequence
abstract val active: Boolean abstract val active: Boolean
open val enabled get() = true
open val selectable 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() ?: "" return lookup[binder?.iface ?: return ""]?.formatAddresses() ?: ""
} }
override val active get() = binder?.iface != null override val active get() = binder?.iface != null
override val enabled get() = binder?.iface != ""
override val selectable get() = active override val selectable get() = active
} }
@@ -110,12 +111,11 @@ class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager()
override fun onServiceConnected(name: ComponentName?, service: IBinder?) { override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
binder = service as LocalOnlyHotspotService.Binder binder = service as LocalOnlyHotspotService.Binder
service.manager = this service.ifaceChanged[this] = { data.notifyChange() }
update()
} }
override fun onServiceDisconnected(name: ComponentName?) { override fun onServiceDisconnected(name: ComponentName?) {
binder?.manager = null binder?.ifaceChanged?.remove(this)
binder = null binder = null
} }
} }

View File

@@ -10,11 +10,13 @@ import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import be.mygod.vpnhotspot.LocalOnlyHotspotService import be.mygod.vpnhotspot.LocalOnlyHotspotService
import be.mygod.vpnhotspot.R import be.mygod.vpnhotspot.R
import be.mygod.vpnhotspot.util.KillableTileService
import be.mygod.vpnhotspot.util.stopAndUnbind import be.mygod.vpnhotspot.util.stopAndUnbind
@RequiresApi(26) @RequiresApi(26)
class LocalOnlyHotspotTileService : TetherListeningTileService() { class LocalOnlyHotspotTileService : KillableTileService() {
private val tile by lazy { Icon.createWithResource(application, R.drawable.ic_device_wifi_tethering) } private val tile by lazy { Icon.createWithResource(application, R.drawable.ic_device_wifi_tethering) }
private var binder: LocalOnlyHotspotService.Binder? = null private var binder: LocalOnlyHotspotService.Binder? = null
override fun onStartListening() { override fun onStartListening() {
@@ -29,29 +31,41 @@ class LocalOnlyHotspotTileService : TetherListeningTileService() {
override fun onClick() { override fun onClick() {
val binder = binder val binder = binder
when { if (binder == null) tapPending = true
binder == null -> tapPending = true else when (binder.iface) {
binder.iface != null -> binder.stop() null -> ContextCompat.startForegroundService(this, Intent(this, LocalOnlyHotspotService::class.java))
else -> ContextCompat.startForegroundService(this, Intent(this, LocalOnlyHotspotService::class.java)) "" -> { } // STARTING, ignored
else -> binder.stop()
} }
} }
override fun onServiceConnected(name: ComponentName?, service: IBinder?) { override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
binder = service as LocalOnlyHotspotService.Binder 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) super.onServiceConnected(name, service)
} }
override fun onServiceDisconnected(name: ComponentName?) { override fun onServiceDisconnected(name: ComponentName?) {
binder?.ifaceChanged?.remove(this)
binder = null 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>() val list = ArrayList<Manager>()
if (RepeaterService.supported) list.add(repeaterManager) if (RepeaterService.supported) list.add(repeaterManager)
if (Build.VERSION.SDK_INT >= 26) { if (Build.VERSION.SDK_INT >= 26) list.add(localOnlyHotspotManager)
list.add(localOnlyHotspotManager)
localOnlyHotspotManager.update()
}
list.addAll(activeIfaces.map { InterfaceManager(this@TetheringFragment, it) }.sortedBy { it.iface }) list.addAll(activeIfaces.map { InterfaceManager(this@TetheringFragment, it) }.sortedBy { it.iface })
list.add(ManageBar) list.add(ManageBar)
if (Build.VERSION.SDK_INT >= 24) { if (Build.VERSION.SDK_INT >= 24) {

View File

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