From 7eec6f7a0682f39099f8f70cc8bd684e4a7b4ed7 Mon Sep 17 00:00:00 2001 From: Mygod Date: Fri, 28 Dec 2018 14:18:02 +0800 Subject: [PATCH] Add starting state to temp hotspot --- .../vpnhotspot/LocalOnlyHotspotService.kt | 19 +++++--- .../java/be/mygod/vpnhotspot/manage/Data.kt | 1 + .../manage/LocalOnlyHotspotManager.kt | 6 +-- .../manage/LocalOnlyHotspotTileService.kt | 44 ++++++++++++------- .../vpnhotspot/manage/TetheringFragment.kt | 5 +-- .../main/res/layout/listitem_interface.xml | 1 + 6 files changed, 49 insertions(+), 27 deletions(-) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/LocalOnlyHotspotService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/LocalOnlyHotspotService.kt index 41b503ab..6617040f 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/LocalOnlyHotspotService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/LocalOnlyHotspotService.kt @@ -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() diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/Data.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/Data.kt index a38b8347..1e54045a 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/Data.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/Data.kt @@ -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 } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotManager.kt index 2511fe43..eb81cfbd 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotManager.kt @@ -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 } } 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 a808175f..ace834fb 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotTileService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotTileService.kt @@ -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() - } - } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt index 48e57501..3a154c36 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt @@ -62,10 +62,7 @@ class TetheringFragment : Fragment(), ServiceConnection { val list = ArrayList() 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) { diff --git a/mobile/src/main/res/layout/listitem_interface.xml b/mobile/src/main/res/layout/listitem_interface.xml index 650a072a..df58f1b7 100644 --- a/mobile/src/main/res/layout/listitem_interface.xml +++ b/mobile/src/main/res/layout/listitem_interface.xml @@ -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"/>