Support new onInfoChanged method
This commit is contained in:
@@ -264,6 +264,7 @@ Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded
|
|||||||
* (since API 30) `Landroid/net/wifi/WifiManager$SoftApCallback;->onCapabilityChanged(Landroid/net/wifi/SoftApCapability;)V,sdk,system-api,test-api`
|
* (since API 30) `Landroid/net/wifi/WifiManager$SoftApCallback;->onCapabilityChanged(Landroid/net/wifi/SoftApCapability;)V,sdk,system-api,test-api`
|
||||||
* (since API 30) `Landroid/net/wifi/WifiManager$SoftApCallback;->onConnectedClientsChanged(Ljava/util/List;)V,sdk,system-api,test-api`
|
* (since API 30) `Landroid/net/wifi/WifiManager$SoftApCallback;->onConnectedClientsChanged(Ljava/util/List;)V,sdk,system-api,test-api`
|
||||||
* (since API 30) `Landroid/net/wifi/WifiManager$SoftApCallback;->onInfoChanged(Landroid/net/wifi/SoftApInfo;)V,sdk,system-api,test-api`
|
* (since API 30) `Landroid/net/wifi/WifiManager$SoftApCallback;->onInfoChanged(Landroid/net/wifi/SoftApInfo;)V,sdk,system-api,test-api`
|
||||||
|
* (since API 31) `Landroid/net/wifi/WifiManager$SoftApCallback;->onInfoChanged(Ljava/util/List;)V,sdk,system-api,test-api`
|
||||||
* (since API 28) `Landroid/net/wifi/WifiManager$SoftApCallback;->onStateChanged(II)V,sdk,system-api,test-api`
|
* (since API 28) `Landroid/net/wifi/WifiManager$SoftApCallback;->onStateChanged(II)V,sdk,system-api,test-api`
|
||||||
* (since API 30) `Landroid/net/wifi/WifiManager;->SAP_CLIENT_BLOCK_REASON_CODE_*:I,sdk,system-api,test-api`
|
* (since API 30) `Landroid/net/wifi/WifiManager;->SAP_CLIENT_BLOCK_REASON_CODE_*:I,sdk,system-api,test-api`
|
||||||
* (since API 28) `Landroid/net/wifi/WifiManager;->SAP_START_FAILURE_*:I,sdk,system-api,test-api`
|
* (since API 28) `Landroid/net/wifi/WifiManager;->SAP_START_FAILURE_*:I,sdk,system-api,test-api`
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.content.Intent
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.MacAddress
|
import android.net.MacAddress
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.Parcelable
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@@ -25,6 +26,7 @@ import be.mygod.vpnhotspot.databinding.ListitemInterfaceBinding
|
|||||||
import be.mygod.vpnhotspot.net.TetherType
|
import be.mygod.vpnhotspot.net.TetherType
|
||||||
import be.mygod.vpnhotspot.net.TetheringManager
|
import be.mygod.vpnhotspot.net.TetheringManager
|
||||||
import be.mygod.vpnhotspot.net.wifi.SoftApConfigurationCompat
|
import be.mygod.vpnhotspot.net.wifi.SoftApConfigurationCompat
|
||||||
|
import be.mygod.vpnhotspot.net.wifi.SoftApInfo
|
||||||
import be.mygod.vpnhotspot.net.wifi.WifiApManager
|
import be.mygod.vpnhotspot.net.wifi.WifiApManager
|
||||||
import be.mygod.vpnhotspot.root.WifiApCommands
|
import be.mygod.vpnhotspot.root.WifiApCommands
|
||||||
import be.mygod.vpnhotspot.util.readableMessage
|
import be.mygod.vpnhotspot.util.readableMessage
|
||||||
@@ -137,8 +139,7 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
|
|||||||
WifiApManager.SoftApCallbackCompat {
|
WifiApManager.SoftApCallbackCompat {
|
||||||
private var failureReason: Int? = null
|
private var failureReason: Int? = null
|
||||||
private var numClients: Int? = null
|
private var numClients: Int? = null
|
||||||
private var frequency = 0
|
private var info = emptyList<Parcelable>()
|
||||||
private var bandwidth = WifiApManager.CHANNEL_WIDTH_INVALID
|
|
||||||
private var capability: Pair<Int, Long>? = null
|
private var capability: Pair<Int, Long>? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -166,9 +167,8 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
|
|||||||
this.numClients = numClients
|
this.numClients = numClients
|
||||||
if (Build.VERSION.SDK_INT >= 30) data.notifyChange() // only emits when onCapabilityChanged can be called
|
if (Build.VERSION.SDK_INT >= 30) data.notifyChange() // only emits when onCapabilityChanged can be called
|
||||||
}
|
}
|
||||||
override fun onInfoChanged(frequency: Int, bandwidth: Int) {
|
override fun onInfoChanged(info: List<Parcelable>) {
|
||||||
this.frequency = frequency
|
this.info = info
|
||||||
this.bandwidth = bandwidth
|
|
||||||
data.notifyChange()
|
data.notifyChange()
|
||||||
}
|
}
|
||||||
override fun onCapabilityChanged(maxSupportedClients: Int, supportedFeatures: Long) {
|
override fun onCapabilityChanged(maxSupportedClients: Int, supportedFeatures: Long) {
|
||||||
@@ -189,11 +189,15 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
|
|||||||
override val tetherType get() = TetherType.WIFI
|
override val tetherType get() = TetherType.WIFI
|
||||||
override val type get() = VIEW_TYPE_WIFI
|
override val type get() = VIEW_TYPE_WIFI
|
||||||
override val text get() = listOfNotNull(failureReason?.let { WifiApManager.failureReasonLookup(it) }, baseError,
|
override val text get() = listOfNotNull(failureReason?.let { WifiApManager.failureReasonLookup(it) }, baseError,
|
||||||
if (frequency != 0 || bandwidth != WifiApManager.CHANNEL_WIDTH_INVALID) {
|
info.run {
|
||||||
parent.getString(R.string.tethering_manage_wifi_info, frequency,
|
if (isEmpty()) null else joinToString("\n") @TargetApi(30) {
|
||||||
|
val info = SoftApInfo(it)
|
||||||
|
val frequency = info.frequency
|
||||||
|
parent.getString(R.string.tethering_manage_wifi_info, frequency,
|
||||||
SoftApConfigurationCompat.frequencyToChannel(frequency),
|
SoftApConfigurationCompat.frequencyToChannel(frequency),
|
||||||
WifiApManager.channelWidthLookup(bandwidth, true))
|
SoftApInfo.channelWidthLookup(info.bandwidth, true))
|
||||||
} else null,
|
}
|
||||||
|
},
|
||||||
capability?.let { (maxSupportedClients, supportedFeatures) ->
|
capability?.let { (maxSupportedClients, supportedFeatures) ->
|
||||||
app.resources.getQuantityString(R.plurals.tethering_manage_wifi_capabilities, maxSupportedClients,
|
app.resources.getQuantityString(R.plurals.tethering_manage_wifi_capabilities, maxSupportedClients,
|
||||||
numClients ?: "?", maxSupportedClients, sequence {
|
numClients ?: "?", maxSupportedClients, sequence {
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package be.mygod.vpnhotspot.net.wifi
|
||||||
|
|
||||||
|
import android.os.Parcelable
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import be.mygod.vpnhotspot.util.ConstantLookup
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
@RequiresApi(30)
|
||||||
|
value class SoftApInfo(val inner: Parcelable) {
|
||||||
|
companion object {
|
||||||
|
private val classSoftApInfo by lazy { Class.forName("android.net.wifi.SoftApInfo") }
|
||||||
|
private val getFrequency by lazy { classSoftApInfo.getDeclaredMethod("getFrequency") }
|
||||||
|
private val getBandwidth by lazy { classSoftApInfo.getDeclaredMethod("getBandwidth") }
|
||||||
|
|
||||||
|
val channelWidthLookup = ConstantLookup("CHANNEL_WIDTH_") { classSoftApInfo }
|
||||||
|
}
|
||||||
|
|
||||||
|
val frequency get() = getFrequency.invoke(inner) as Int
|
||||||
|
val bandwidth get() = getBandwidth.invoke(inner) as Int
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import android.net.wifi.SoftApConfiguration
|
|||||||
import android.net.wifi.WifiManager
|
import android.net.wifi.WifiManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
|
import android.os.Parcelable
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.core.os.BuildCompat
|
import androidx.core.os.BuildCompat
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
@@ -87,7 +88,7 @@ object WifiApManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
fun onInfoChanged(frequency: Int, bandwidth: Int) { }
|
fun onInfoChanged(info: List<Parcelable>) { }
|
||||||
|
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
fun onCapabilityChanged(maxSupportedClients: Int, supportedFeatures: Long) { }
|
fun onCapabilityChanged(maxSupportedClients: Int, supportedFeatures: Long) { }
|
||||||
@@ -116,13 +117,6 @@ object WifiApManager {
|
|||||||
Class.forName("android.net.wifi.WifiClient").getDeclaredMethod("getMacAddress")
|
Class.forName("android.net.wifi.WifiClient").getDeclaredMethod("getMacAddress")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val classSoftApInfo by lazy { Class.forName("android.net.wifi.SoftApInfo") }
|
|
||||||
private val getFrequency by lazy { classSoftApInfo.getDeclaredMethod("getFrequency") }
|
|
||||||
private val getBandwidth by lazy { classSoftApInfo.getDeclaredMethod("getBandwidth") }
|
|
||||||
@RequiresApi(30)
|
|
||||||
val channelWidthLookup = ConstantLookup("CHANNEL_WIDTH_") { classSoftApInfo }
|
|
||||||
const val CHANNEL_WIDTH_INVALID = 0
|
|
||||||
|
|
||||||
private val classSoftApCapability by lazy { Class.forName("android.net.wifi.SoftApCapability") }
|
private val classSoftApCapability by lazy { Class.forName("android.net.wifi.SoftApCapability") }
|
||||||
private val getMaxSupportedClients by lazy { classSoftApCapability.getDeclaredMethod("getMaxSupportedClients") }
|
private val getMaxSupportedClients by lazy { classSoftApCapability.getDeclaredMethod("getMaxSupportedClients") }
|
||||||
private val areFeaturesSupported by lazy {
|
private val areFeaturesSupported by lazy {
|
||||||
@@ -141,9 +135,6 @@ object WifiApManager {
|
|||||||
null // no return value as of API 30
|
null // no return value as of API 30
|
||||||
} else invokeActual(proxy, method, args)
|
} else invokeActual(proxy, method, args)
|
||||||
|
|
||||||
@RequiresApi(30)
|
|
||||||
private fun dispatchInfoChanged(softApInfo: Any?) =
|
|
||||||
callback.onInfoChanged(getFrequency(softApInfo) as Int, getBandwidth(softApInfo) as Int)
|
|
||||||
private fun invokeActual(proxy: Any, method: Method, args: Array<out Any?>?): Any? {
|
private fun invokeActual(proxy: Any, method: Method, args: Array<out Any?>?): Any? {
|
||||||
val noArgs = args?.size ?: 0
|
val noArgs = args?.size ?: 0
|
||||||
return when (val name = method.name) {
|
return when (val name = method.name) {
|
||||||
@@ -172,14 +163,22 @@ object WifiApManager {
|
|||||||
}.map { getMacAddress(it) as MacAddress })
|
}.map { getMacAddress(it) as MacAddress })
|
||||||
}
|
}
|
||||||
"onInfoChanged" -> @TargetApi(30) {
|
"onInfoChanged" -> @TargetApi(30) {
|
||||||
if (Build.VERSION.SDK_INT < 30) Timber.w(Exception("Unexpected onInfoChanged"))
|
|
||||||
if (noArgs != 1) Timber.w("Unexpected args for $name: ${args?.contentToString()}")
|
if (noArgs != 1) Timber.w("Unexpected args for $name: ${args?.contentToString()}")
|
||||||
val arg = args!![0]
|
val arg = args!![0]
|
||||||
if (arg is List<*>) {
|
if (arg is List<*>) {
|
||||||
if (!BuildCompat.isAtLeastS()) Timber.w(Exception("Unexpected onInfoChanged API 31+"))
|
if (!BuildCompat.isAtLeastS()) Timber.w(Exception("Unexpected onInfoChanged API 31+"))
|
||||||
if (arg.size != 1) Timber.w("Unexpected args for $name: ${args.contentToString()}")
|
@Suppress("UNCHECKED_CAST")
|
||||||
else dispatchInfoChanged(arg[0])
|
callback.onInfoChanged(arg as List<Parcelable>)
|
||||||
} else dispatchInfoChanged(arg)
|
} else {
|
||||||
|
when (Build.VERSION.SDK_INT) {
|
||||||
|
30 -> { }
|
||||||
|
in 31..Int.MAX_VALUE -> return null // ignore old version calls
|
||||||
|
else -> Timber.w(Exception("Unexpected onInfoChanged API 30"))
|
||||||
|
}
|
||||||
|
val info = SoftApInfo(arg as Parcelable)
|
||||||
|
callback.onInfoChanged( // check for legacy empty info with CHANNEL_WIDTH_INVALID
|
||||||
|
if (info.frequency == 0 && info.bandwidth == 0) emptyList() else listOf(arg))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"onCapabilityChanged" -> @TargetApi(30) {
|
"onCapabilityChanged" -> @TargetApi(30) {
|
||||||
if (Build.VERSION.SDK_INT < 30) Timber.w(Exception("Unexpected onCapabilityChanged"))
|
if (Build.VERSION.SDK_INT < 30) Timber.w(Exception("Unexpected onCapabilityChanged"))
|
||||||
|
|||||||
@@ -38,9 +38,8 @@ object WifiApCommands {
|
|||||||
}
|
}
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
data class OnInfoChanged(val frequency: Int, val bandwidth: Int) : SoftApCallbackParcel() {
|
data class OnInfoChanged(val info: List<Parcelable>) : SoftApCallbackParcel() {
|
||||||
override fun dispatch(callback: WifiApManager.SoftApCallbackCompat) =
|
override fun dispatch(callback: WifiApManager.SoftApCallbackCompat) = callback.onInfoChanged(info)
|
||||||
callback.onInfoChanged(frequency, bandwidth)
|
|
||||||
}
|
}
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
@@ -78,8 +77,7 @@ object WifiApCommands {
|
|||||||
override fun onConnectedClientsChanged(clients: List<MacAddress>) =
|
override fun onConnectedClientsChanged(clients: List<MacAddress>) =
|
||||||
push(SoftApCallbackParcel.OnConnectedClientsChanged(clients))
|
push(SoftApCallbackParcel.OnConnectedClientsChanged(clients))
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
override fun onInfoChanged(frequency: Int, bandwidth: Int) =
|
override fun onInfoChanged(info: List<Parcelable>) = push(SoftApCallbackParcel.OnInfoChanged(info))
|
||||||
push(SoftApCallbackParcel.OnInfoChanged(frequency, bandwidth))
|
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
override fun onCapabilityChanged(maxSupportedClients: Int, supportedFeatures: Long) =
|
override fun onCapabilityChanged(maxSupportedClients: Int, supportedFeatures: Long) =
|
||||||
push(SoftApCallbackParcel.OnCapabilityChanged(maxSupportedClients, supportedFeatures))
|
push(SoftApCallbackParcel.OnCapabilityChanged(maxSupportedClients, supportedFeatures))
|
||||||
|
|||||||
Reference in New Issue
Block a user