Implement ConstantLookup

This commit is contained in:
Mygod
2020-07-03 08:10:23 +08:00
parent 9231681b45
commit 4f97f9bf74
5 changed files with 46 additions and 54 deletions

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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)