Implement ConstantLookup
This commit is contained in:
@@ -88,7 +88,7 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
|
|||||||
override fun onTetheringStarted() = data.notifyChange()
|
override fun onTetheringStarted() = data.notifyChange()
|
||||||
override fun onTetheringFailed(error: Int?) {
|
override fun onTetheringFailed(error: Int?) {
|
||||||
Timber.d("onTetheringFailed: $error")
|
Timber.d("onTetheringFailed: $error")
|
||||||
error?.let { SmartSnackbar.make("$tetherType: ${TetheringManager.tetherErrorMessage(it)}").show() }
|
error?.let { SmartSnackbar.make("$tetherType: ${TetheringManager.tetherErrorLookup(it)}").show() }
|
||||||
data.notifyChange()
|
data.notifyChange()
|
||||||
}
|
}
|
||||||
override fun onException(e: Exception) {
|
override fun onException(e: Exception) {
|
||||||
@@ -108,7 +108,7 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
|
|||||||
val interested = errored.filter { TetherType.ofInterface(it) == tetherType }
|
val interested = errored.filter { TetherType.ofInterface(it) == tetherType }
|
||||||
baseError = if (interested.isEmpty()) null else interested.joinToString("\n") { iface ->
|
baseError = if (interested.isEmpty()) null else interested.joinToString("\n") { iface ->
|
||||||
"$iface: " + try {
|
"$iface: " + try {
|
||||||
TetheringManager.tetherErrorMessage(TetheringManager.getLastTetherError(iface))
|
TetheringManager.tetherErrorLookup(TetheringManager.getLastTetherError(iface))
|
||||||
} catch (e: InvocationTargetException) {
|
} catch (e: InvocationTargetException) {
|
||||||
if (Build.VERSION.SDK_INT !in 24..25 || e.cause !is SecurityException) Timber.w(e) else Timber.d(e)
|
if (Build.VERSION.SDK_INT !in 24..25 || e.cause !is SecurityException) Timber.w(e) else Timber.d(e)
|
||||||
e.readableMessage
|
e.readableMessage
|
||||||
@@ -149,7 +149,7 @@ sealed class TetherManager(protected val parent: TetheringFragment) : Manager(),
|
|||||||
override val title get() = parent.getString(R.string.tethering_manage_wifi)
|
override val title get() = parent.getString(R.string.tethering_manage_wifi)
|
||||||
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.failureReason(it) },
|
override val text get() = listOfNotNull(failureReason?.let { WifiApManager.failureReasonLookup(it) },
|
||||||
baseError).joinToString("\n")
|
baseError).joinToString("\n")
|
||||||
|
|
||||||
override fun start() = TetheringManager.startTethering(TetheringManager.TETHERING_WIFI, true, this)
|
override fun start() = TetheringManager.startTethering(TetheringManager.TETHERING_WIFI, true, this)
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ sealed class TetheringTileService : IpNeighbourMonitoringTileService(), Tetherin
|
|||||||
override fun onTetheringStarted() = updateTile()
|
override fun onTetheringStarted() = updateTile()
|
||||||
override fun onTetheringFailed(error: Int?) {
|
override fun onTetheringFailed(error: Int?) {
|
||||||
Timber.d("onTetheringFailed: $error")
|
Timber.d("onTetheringFailed: $error")
|
||||||
error?.let { Toast.makeText(this, TetheringManager.tetherErrorMessage(it), Toast.LENGTH_LONG).show() }
|
error?.let { Toast.makeText(this, TetheringManager.tetherErrorLookup(it), Toast.LENGTH_LONG).show() }
|
||||||
updateTile()
|
updateTile()
|
||||||
}
|
}
|
||||||
override fun onException(e: Exception) {
|
override fun onException(e: Exception) {
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ import android.net.Network
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.collection.SparseArrayCompat
|
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.R
|
|
||||||
import be.mygod.vpnhotspot.root.RootManager
|
import be.mygod.vpnhotspot.root.RootManager
|
||||||
import be.mygod.vpnhotspot.root.StartTethering
|
import be.mygod.vpnhotspot.root.StartTethering
|
||||||
import be.mygod.vpnhotspot.root.StopTethering
|
import be.mygod.vpnhotspot.root.StopTethering
|
||||||
@@ -607,31 +605,12 @@ object TetheringManager {
|
|||||||
*/
|
*/
|
||||||
fun getLastTetherError(iface: String): Int = getLastTetherError(Services.connectivity, iface) as Int
|
fun getLastTetherError(iface: String): Int = getLastTetherError(Services.connectivity, iface) as Int
|
||||||
|
|
||||||
// tether errors defined in ConnectivityManager up to Android 10
|
val tetherErrorLookup = ConstantLookup(clazz, "TETHER_ERROR_",
|
||||||
private val tetherErrors29 = arrayOf("TETHER_ERROR_NO_ERROR", "TETHER_ERROR_UNKNOWN_IFACE",
|
"TETHER_ERROR_NO_ERROR", "TETHER_ERROR_UNKNOWN_IFACE", "TETHER_ERROR_SERVICE_UNAVAIL",
|
||||||
"TETHER_ERROR_SERVICE_UNAVAIL", "TETHER_ERROR_UNSUPPORTED", "TETHER_ERROR_UNAVAIL_IFACE",
|
"TETHER_ERROR_UNSUPPORTED", "TETHER_ERROR_UNAVAIL_IFACE", "TETHER_ERROR_MASTER_ERROR",
|
||||||
"TETHER_ERROR_MASTER_ERROR", "TETHER_ERROR_TETHER_IFACE_ERROR", "TETHER_ERROR_UNTETHER_IFACE_ERROR",
|
"TETHER_ERROR_TETHER_IFACE_ERROR", "TETHER_ERROR_UNTETHER_IFACE_ERROR", "TETHER_ERROR_ENABLE_NAT_ERROR",
|
||||||
"TETHER_ERROR_ENABLE_NAT_ERROR", "TETHER_ERROR_DISABLE_NAT_ERROR", "TETHER_ERROR_IFACE_CFG_ERROR",
|
"TETHER_ERROR_DISABLE_NAT_ERROR", "TETHER_ERROR_IFACE_CFG_ERROR", "TETHER_ERROR_PROVISION_FAILED",
|
||||||
"TETHER_ERROR_PROVISION_FAILED", "TETHER_ERROR_DHCPSERVER_ERROR", "TETHER_ERROR_ENTITLEMENT_UNKNOWN")
|
"TETHER_ERROR_DHCPSERVER_ERROR", "TETHER_ERROR_ENTITLEMENT_UNKNOWN")
|
||||||
@get:RequiresApi(30)
|
|
||||||
private val tetherErrors by lazy {
|
|
||||||
SparseArrayCompat<String>().apply {
|
|
||||||
for (field in clazz.declaredFields) try {
|
|
||||||
// all TETHER_ERROR_* are system-api since API 30
|
|
||||||
if (field.name.startsWith("TETHER_ERROR_")) put(field.get(null) as Int, field.name)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.w(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fun tetherErrorMessage(error: Int): String {
|
|
||||||
if (Build.VERSION.SDK_INT >= 30) try {
|
|
||||||
tetherErrors.get(error)?.let { return it }
|
|
||||||
} catch (e: ReflectiveOperationException) {
|
|
||||||
Timber.w(e)
|
|
||||||
}
|
|
||||||
return tetherErrors29.getOrNull(error) ?: app.getString(R.string.failure_reason_unknown, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
val Intent.tetheredIfaces get() = getStringArrayListExtra(
|
val Intent.tetheredIfaces get() = getStringArrayListExtra(
|
||||||
if (Build.VERSION.SDK_INT >= 26) EXTRA_ACTIVE_TETHER else EXTRA_ACTIVE_TETHER_LEGACY)
|
if (Build.VERSION.SDK_INT >= 26) EXTRA_ACTIVE_TETHER else EXTRA_ACTIVE_TETHER_LEGACY)
|
||||||
|
|||||||
@@ -8,15 +8,12 @@ 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.Looper
|
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.collection.SparseArrayCompat
|
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.R
|
|
||||||
import be.mygod.vpnhotspot.net.wifi.SoftApConfigurationCompat.Companion.toCompat
|
import be.mygod.vpnhotspot.net.wifi.SoftApConfigurationCompat.Companion.toCompat
|
||||||
|
import be.mygod.vpnhotspot.util.ConstantLookup
|
||||||
import be.mygod.vpnhotspot.util.Services
|
import be.mygod.vpnhotspot.util.Services
|
||||||
import be.mygod.vpnhotspot.util.callSuper
|
import be.mygod.vpnhotspot.util.callSuper
|
||||||
import be.mygod.vpnhotspot.util.makeExecutor
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.lang.reflect.InvocationHandler
|
import java.lang.reflect.InvocationHandler
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
@@ -96,25 +93,8 @@ object WifiApManager {
|
|||||||
@RequiresApi(30)
|
@RequiresApi(30)
|
||||||
fun onBlockedClientConnecting(client: MacAddress, blockedReason: Int) { }
|
fun onBlockedClientConnecting(client: MacAddress, blockedReason: Int) { }
|
||||||
}
|
}
|
||||||
private val startFailures29 = arrayOf("SAP_START_FAILURE_GENERAL", "SAP_START_FAILURE_NO_CHANNEL")
|
val failureReasonLookup = ConstantLookup<WifiManager>("SAP_START_FAILURE_",
|
||||||
private val startFailures by lazy {
|
"SAP_START_FAILURE_GENERAL", "SAP_START_FAILURE_NO_CHANNEL")
|
||||||
SparseArrayCompat<String>().apply {
|
|
||||||
for (field in WifiManager::class.java.declaredFields) try {
|
|
||||||
// all SAP_START_FAILURE_* are system-api since API 30
|
|
||||||
if (field.name.startsWith("SAP_START_FAILURE_")) put(field.get(null) as Int, field.name)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.w(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fun failureReason(reason: Int): String {
|
|
||||||
if (Build.VERSION.SDK_INT >= 30) try {
|
|
||||||
startFailures.get(reason)?.let { return it }
|
|
||||||
} catch (e: ReflectiveOperationException) {
|
|
||||||
Timber.w(e)
|
|
||||||
}
|
|
||||||
return startFailures29.getOrNull(reason) ?: app.getString(R.string.failure_reason_unknown, reason)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val interfaceSoftApCallback by lazy { Class.forName("android.net.wifi.WifiManager\$SoftApCallback") }
|
private val interfaceSoftApCallback by lazy { Class.forName("android.net.wifi.WifiManager\$SoftApCallback") }
|
||||||
private val registerSoftApCallback by lazy {
|
private val registerSoftApCallback by lazy {
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package be.mygod.vpnhotspot.util
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.collection.SparseArrayCompat
|
||||||
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
|
import be.mygod.vpnhotspot.R
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
class ConstantLookup(private val clazz: Class<*>, private val prefix: String, private val lookup29: Array<out String>) {
|
||||||
|
private val lookup by lazy {
|
||||||
|
SparseArrayCompat<String>().apply {
|
||||||
|
for (field in clazz.declaredFields) try {
|
||||||
|
if (field.name.startsWith(prefix)) put(field.get(null) as Int, field.name)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.w(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
operator fun invoke(reason: Int): String {
|
||||||
|
if (Build.VERSION.SDK_INT >= 30) try {
|
||||||
|
lookup.get(reason)?.let { return it }
|
||||||
|
} catch (e: ReflectiveOperationException) {
|
||||||
|
Timber.w(e)
|
||||||
|
}
|
||||||
|
return lookup29.getOrNull(reason) ?: app.getString(R.string.failure_reason_unknown, reason)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
fun ConstantLookup(clazz: Class<*>, prefix: String, vararg lookup29: String) = ConstantLookup(clazz, prefix, lookup29)
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
inline fun <reified T> ConstantLookup(prefix: String, vararg lookup29: String) =
|
||||||
|
ConstantLookup(T::class.java, prefix, lookup29)
|
||||||
Reference in New Issue
Block a user