Add starting state to temp hotspot
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user