Support ap identifier for WifiClient
This commit is contained in:
@@ -155,6 +155,7 @@ Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded
|
|||||||
* (since API 30) `Landroid/net/TetheringManager$TetheringEventCallback;->onTetherableInterfaceRegexpsChanged(Landroid/net/TetheringManager$TetheringInterfaceRegexps;)V,blocked`
|
* (since API 30) `Landroid/net/TetheringManager$TetheringEventCallback;->onTetherableInterfaceRegexpsChanged(Landroid/net/TetheringManager$TetheringInterfaceRegexps;)V,blocked`
|
||||||
* (since API 30) `Landroid/net/TetheringManager;->TETHERING_WIGIG:I,blocked`
|
* (since API 30) `Landroid/net/TetheringManager;->TETHERING_WIGIG:I,blocked`
|
||||||
* (since API 31) `Landroid/net/wifi/SoftApInfo;->getApInstanceIdentifier()Ljava/lang/String;,blocked`
|
* (since API 31) `Landroid/net/wifi/SoftApInfo;->getApInstanceIdentifier()Ljava/lang/String;,blocked`
|
||||||
|
* (since API 31) `Landroid/net/wifi/WifiClient;->getApInstanceIdentifier()Ljava/lang/String;,blocked`
|
||||||
* (prior to API 30) `Landroid/net/wifi/WifiConfiguration$KeyMgmt;->FT_PSK:I,lo-prio,max-target-o`
|
* (prior to API 30) `Landroid/net/wifi/WifiConfiguration$KeyMgmt;->FT_PSK:I,lo-prio,max-target-o`
|
||||||
* (prior to API 30) `Landroid/net/wifi/WifiConfiguration$KeyMgmt;->WPA_PSK_SHA256:I,blocked`
|
* (prior to API 30) `Landroid/net/wifi/WifiConfiguration$KeyMgmt;->WPA_PSK_SHA256:I,blocked`
|
||||||
* (since API 23, prior to API 30) `Landroid/net/wifi/WifiConfiguration;->AP_BAND_2GHZ:I,lo-prio,max-target-o`
|
* (since API 23, prior to API 30) `Landroid/net/wifi/WifiConfiguration;->AP_BAND_2GHZ:I,lo-prio,max-target-o`
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import android.content.ClipData
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.MacAddress
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
@@ -27,10 +26,7 @@ import be.mygod.vpnhotspot.R
|
|||||||
import be.mygod.vpnhotspot.databinding.ListitemInterfaceBinding
|
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.SoftApCapability
|
import be.mygod.vpnhotspot.net.wifi.*
|
||||||
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.root.WifiApCommands
|
import be.mygod.vpnhotspot.root.WifiApCommands
|
||||||
import be.mygod.vpnhotspot.util.format
|
import be.mygod.vpnhotspot.util.format
|
||||||
import be.mygod.vpnhotspot.util.joinToSpanned
|
import be.mygod.vpnhotspot.util.joinToSpanned
|
||||||
@@ -182,12 +178,18 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
|
|||||||
this.capability = capability
|
this.capability = capability
|
||||||
data.notifyChange()
|
data.notifyChange()
|
||||||
}
|
}
|
||||||
override fun onBlockedClientConnecting(client: MacAddress, blockedReason: Int) {
|
@RequiresApi(30)
|
||||||
|
override fun onBlockedClientConnecting(client: Parcelable, blockedReason: Int) {
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
val client = WifiClient(client)
|
||||||
|
val macAddress = client.macAddress
|
||||||
|
var name = macAddress.toString()
|
||||||
|
if (BuildCompat.isAtLeastS()) client.apInstanceIdentifier?.let { name += "%$it" }
|
||||||
val reason = WifiApManager.clientBlockLookup(blockedReason, true)
|
val reason = WifiApManager.clientBlockLookup(blockedReason, true)
|
||||||
Timber.i("$client blocked from connecting: $reason ($blockedReason)")
|
Timber.i("$name blocked from connecting: $reason ($blockedReason)")
|
||||||
SmartSnackbar.make(parent.getString(R.string.tethering_manage_wifi_client_blocked, client, reason)).apply {
|
SmartSnackbar.make(parent.getString(R.string.tethering_manage_wifi_client_blocked, name, reason)).apply {
|
||||||
action(R.string.tethering_manage_wifi_copy_mac) {
|
action(R.string.tethering_manage_wifi_copy_mac) {
|
||||||
app.clipboard.setPrimaryClip(ClipData.newPlainText(null, client.toString()))
|
app.clipboard.setPrimaryClip(ClipData.newPlainText(null, macAddress.toString()))
|
||||||
}
|
}
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,28 +20,26 @@ value class SoftApInfo(val inner: Parcelable) {
|
|||||||
@get:RequiresApi(31)
|
@get:RequiresApi(31)
|
||||||
private val getWifiStandard by lazy { clazz.getDeclaredMethod("getWifiStandard") }
|
private val getWifiStandard by lazy { clazz.getDeclaredMethod("getWifiStandard") }
|
||||||
@get:RequiresApi(31)
|
@get:RequiresApi(31)
|
||||||
private val getApInstanceIdentifier by lazy @TargetApi(31) {
|
private val getApInstanceIdentifier by lazy @TargetApi(31) { UnblockCentral.getApInstanceIdentifier(clazz) }
|
||||||
UnblockCentral.SoftApInfo_getApInstanceIdentifier(clazz)
|
|
||||||
}
|
|
||||||
@get:RequiresApi(31)
|
@get:RequiresApi(31)
|
||||||
private val getAutoShutdownTimeoutMillis by lazy { clazz.getDeclaredMethod("getAutoShutdownTimeoutMillis") }
|
private val getAutoShutdownTimeoutMillis by lazy { clazz.getDeclaredMethod("getAutoShutdownTimeoutMillis") }
|
||||||
|
|
||||||
val channelWidthLookup = ConstantLookup("CHANNEL_WIDTH_") { clazz }
|
val channelWidthLookup = ConstantLookup("CHANNEL_WIDTH_") { clazz }
|
||||||
}
|
}
|
||||||
|
|
||||||
val frequency get() = getFrequency.invoke(inner) as Int
|
val frequency get() = getFrequency(inner) as Int
|
||||||
val bandwidth get() = getBandwidth.invoke(inner) as Int
|
val bandwidth get() = getBandwidth(inner) as Int
|
||||||
@get:RequiresApi(31)
|
@get:RequiresApi(31)
|
||||||
val bssid get() = getBssid.invoke(inner) as MacAddress
|
val bssid get() = getBssid(inner) as MacAddress
|
||||||
@get:RequiresApi(31)
|
@get:RequiresApi(31)
|
||||||
val wifiStandard get() = getWifiStandard.invoke(inner) as Int
|
val wifiStandard get() = getWifiStandard(inner) as Int
|
||||||
@get:RequiresApi(31)
|
@get:RequiresApi(31)
|
||||||
val apInstanceIdentifier get() = try {
|
val apInstanceIdentifier get() = try {
|
||||||
getApInstanceIdentifier.invoke(inner) as? String
|
getApInstanceIdentifier(inner) as? String
|
||||||
} catch (e: ReflectiveOperationException) {
|
} catch (e: ReflectiveOperationException) {
|
||||||
Timber.w(e)
|
Timber.w(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@get:RequiresApi(31)
|
@get:RequiresApi(31)
|
||||||
val autoShutdownTimeoutMillis get() = getAutoShutdownTimeoutMillis.invoke(inner) as Long
|
val autoShutdownTimeoutMillis get() = getAutoShutdownTimeoutMillis(inner) as Long
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ object WifiApManager {
|
|||||||
fun onNumClientsChanged(numClients: Int) { }
|
fun onNumClientsChanged(numClients: Int) { }
|
||||||
|
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
fun onConnectedClientsChanged(clients: List<MacAddress>) {
|
fun onConnectedClientsChanged(clients: List<Parcelable>) {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
onNumClientsChanged(clients.size)
|
onNumClientsChanged(clients.size)
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ object WifiApManager {
|
|||||||
fun onCapabilityChanged(capability: Parcelable) { }
|
fun onCapabilityChanged(capability: Parcelable) { }
|
||||||
|
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
fun onBlockedClientConnecting(client: MacAddress, blockedReason: Int) { }
|
fun onBlockedClientConnecting(client: Parcelable, blockedReason: Int) { }
|
||||||
}
|
}
|
||||||
@RequiresApi(28)
|
@RequiresApi(28)
|
||||||
val failureReasonLookup = ConstantLookup<WifiManager>("SAP_START_FAILURE_",
|
val failureReasonLookup = ConstantLookup<WifiManager>("SAP_START_FAILURE_",
|
||||||
@@ -112,10 +112,6 @@ object WifiApManager {
|
|||||||
WifiManager::class.java.getDeclaredMethod("unregisterSoftApCallback", interfaceSoftApCallback)
|
WifiManager::class.java.getDeclaredMethod("unregisterSoftApCallback", interfaceSoftApCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val getMacAddress by lazy {
|
|
||||||
Class.forName("android.net.wifi.WifiClient").getDeclaredMethod("getMacAddress")
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresApi(28)
|
@RequiresApi(28)
|
||||||
fun registerSoftApCallback(callback: SoftApCallbackCompat, executor: Executor): Any {
|
fun registerSoftApCallback(callback: SoftApCallbackCompat, executor: Executor): Any {
|
||||||
val proxy = Proxy.newProxyInstance(interfaceSoftApCallback.classLoader,
|
val proxy = Proxy.newProxyInstance(interfaceSoftApCallback.classLoader,
|
||||||
@@ -140,18 +136,19 @@ object WifiApManager {
|
|||||||
}
|
}
|
||||||
"onConnectedClientsChanged" -> @TargetApi(30) {
|
"onConnectedClientsChanged" -> @TargetApi(30) {
|
||||||
if (Build.VERSION.SDK_INT < 30) Timber.w(Exception("Unexpected onConnectedClientsChanged"))
|
if (Build.VERSION.SDK_INT < 30) Timber.w(Exception("Unexpected onConnectedClientsChanged"))
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
callback.onConnectedClientsChanged(when (noArgs) {
|
callback.onConnectedClientsChanged(when (noArgs) {
|
||||||
1 -> args!![0] as? Iterable<*> ?: return null
|
1 -> args!![0] as List<Parcelable>
|
||||||
2 -> {
|
2 -> {
|
||||||
Timber.w(Exception("Unexpected onConnectedClientsChanged API 31+"))
|
Timber.w(Exception("Unexpected onConnectedClientsChanged API 31+"))
|
||||||
// dispatchInfoChanged(args!![0])
|
// dispatchInfoChanged(args!![0])
|
||||||
args!![1] as? Iterable<*> ?: return null
|
args!![1] as List<Parcelable>
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
Timber.w("Unexpected args for $name: ${args?.contentToString()}")
|
Timber.w("Unexpected args for $name: ${args?.contentToString()}")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}.map { getMacAddress(it) as MacAddress })
|
})
|
||||||
}
|
}
|
||||||
"onInfoChanged" -> @TargetApi(30) {
|
"onInfoChanged" -> @TargetApi(30) {
|
||||||
if (noArgs != 1) Timber.w("Unexpected args for $name: ${args?.contentToString()}")
|
if (noArgs != 1) Timber.w("Unexpected args for $name: ${args?.contentToString()}")
|
||||||
@@ -179,7 +176,7 @@ object WifiApManager {
|
|||||||
"onBlockedClientConnecting" -> @TargetApi(30) {
|
"onBlockedClientConnecting" -> @TargetApi(30) {
|
||||||
if (Build.VERSION.SDK_INT < 30) Timber.w(Exception("Unexpected onBlockedClientConnecting"))
|
if (Build.VERSION.SDK_INT < 30) Timber.w(Exception("Unexpected onBlockedClientConnecting"))
|
||||||
if (noArgs != 2) Timber.w("Unexpected args for $name: ${args?.contentToString()}")
|
if (noArgs != 2) Timber.w("Unexpected args for $name: ${args?.contentToString()}")
|
||||||
callback.onBlockedClientConnecting(getMacAddress(args!![0]) as MacAddress, args[1] as Int)
|
callback.onBlockedClientConnecting(args!![0] as Parcelable, args[1] as Int)
|
||||||
}
|
}
|
||||||
else -> callSuper(interfaceSoftApCallback, proxy, method, args)
|
else -> callSuper(interfaceSoftApCallback, proxy, method, args)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package be.mygod.vpnhotspot.net.wifi
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
|
import android.net.MacAddress
|
||||||
|
import android.os.Parcelable
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import be.mygod.vpnhotspot.util.UnblockCentral
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
@RequiresApi(30)
|
||||||
|
value class WifiClient(val inner: Parcelable) {
|
||||||
|
companion object {
|
||||||
|
private val clazz by lazy { Class.forName("android.net.wifi.WifiClient") }
|
||||||
|
private val getMacAddress by lazy { clazz.getDeclaredMethod("getMacAddress") }
|
||||||
|
@get:RequiresApi(31)
|
||||||
|
private val getApInstanceIdentifier by lazy @TargetApi(31) { UnblockCentral.getApInstanceIdentifier(clazz) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val macAddress get() = getMacAddress(inner) as MacAddress
|
||||||
|
@get:RequiresApi(31)
|
||||||
|
val apInstanceIdentifier get() = try {
|
||||||
|
getApInstanceIdentifier(inner) as? String
|
||||||
|
} catch (e: ReflectiveOperationException) {
|
||||||
|
Timber.w(e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@ object WifiApCommands {
|
|||||||
}
|
}
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
data class OnConnectedClientsChanged(val clients: List<MacAddress>) : SoftApCallbackParcel() {
|
data class OnConnectedClientsChanged(val clients: List<Parcelable>) : SoftApCallbackParcel() {
|
||||||
override fun dispatch(callback: WifiApManager.SoftApCallbackCompat) =
|
override fun dispatch(callback: WifiApManager.SoftApCallbackCompat) =
|
||||||
callback.onConnectedClientsChanged(clients)
|
callback.onConnectedClientsChanged(clients)
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ object WifiApCommands {
|
|||||||
}
|
}
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
data class OnBlockedClientConnecting(val client: MacAddress, val blockedReason: Int) : SoftApCallbackParcel() {
|
data class OnBlockedClientConnecting(val client: Parcelable, val blockedReason: Int) : SoftApCallbackParcel() {
|
||||||
override fun dispatch(callback: WifiApManager.SoftApCallbackCompat) =
|
override fun dispatch(callback: WifiApManager.SoftApCallbackCompat) =
|
||||||
callback.onBlockedClientConnecting(client, blockedReason)
|
callback.onBlockedClientConnecting(client, blockedReason)
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ object WifiApCommands {
|
|||||||
override fun onNumClientsChanged(numClients: Int) =
|
override fun onNumClientsChanged(numClients: Int) =
|
||||||
push(SoftApCallbackParcel.OnNumClientsChanged(numClients))
|
push(SoftApCallbackParcel.OnNumClientsChanged(numClients))
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
override fun onConnectedClientsChanged(clients: List<MacAddress>) =
|
override fun onConnectedClientsChanged(clients: List<Parcelable>) =
|
||||||
push(SoftApCallbackParcel.OnConnectedClientsChanged(clients))
|
push(SoftApCallbackParcel.OnConnectedClientsChanged(clients))
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
override fun onInfoChanged(info: List<Parcelable>) = push(SoftApCallbackParcel.OnInfoChanged(info))
|
override fun onInfoChanged(info: List<Parcelable>) = push(SoftApCallbackParcel.OnInfoChanged(info))
|
||||||
@@ -81,7 +81,7 @@ object WifiApCommands {
|
|||||||
override fun onCapabilityChanged(capability: Parcelable) =
|
override fun onCapabilityChanged(capability: Parcelable) =
|
||||||
push(SoftApCallbackParcel.OnCapabilityChanged(capability))
|
push(SoftApCallbackParcel.OnCapabilityChanged(capability))
|
||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
override fun onBlockedClientConnecting(client: MacAddress, blockedReason: Int) =
|
override fun onBlockedClientConnecting(client: Parcelable, blockedReason: Int) =
|
||||||
push(SoftApCallbackParcel.OnBlockedClientConnecting(client, blockedReason))
|
push(SoftApCallbackParcel.OnBlockedClientConnecting(client, blockedReason))
|
||||||
}) {
|
}) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
|
|||||||
@@ -26,7 +26,5 @@ object UnblockCentral {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(31)
|
@RequiresApi(31)
|
||||||
fun SoftApInfo_getApInstanceIdentifier(clazz: Class<*>) = init.let {
|
fun getApInstanceIdentifier(clazz: Class<*>) = init.let { clazz.getDeclaredMethod("getApInstanceIdentifier") }
|
||||||
clazz.getDeclaredMethod("getApInstanceIdentifier")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user