diff --git a/README.md b/README.md index 14c0014f..074983b0 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,8 @@ Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded * (since API 24, prior to API 30) [`Landroid/net/ConnectivityManager$OnStartTetheringCallback;->onTetheringStarted()V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#144097) * (since API 24, prior to API 30) [`Landroid/net/ConnectivityManager;->startTethering(IZLandroid/net/ConnectivityManager$OnStartTetheringCallback;Landroid/os/Handler;)V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#144406) * (since API 24, prior to API 30) [`Landroid/net/ConnectivityManager;->stopTethering(I)V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#144408) +* [`Landroid/net/LinkProperties;->getAllInterfaceNames()Ljava/util/List;,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#146558) +* [`Landroid/net/LinkProperties;->getAllRoutes()Ljava/util/List;,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#146560) * (since API 30) [`Landroid/net/TetheringManager$StartTetheringCallback;->onTetheringFailed(I)V,system-api,test-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#148881) * (since API 30) [`Landroid/net/TetheringManager$StartTetheringCallback;->onTetheringStarted()V,system-api,test-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#148882) * (since API 30) [`Landroid/net/TetheringManager$TetheringEventCallback;->onClientsChanged(Ljava/util/Collection;)V,system-api,test-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#148896) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt index d416ed4d..3829b13b 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/SettingsPreferenceFragment.kt @@ -20,6 +20,7 @@ import be.mygod.vpnhotspot.preference.SummaryFallbackProvider import be.mygod.vpnhotspot.root.Dump import be.mygod.vpnhotspot.root.RootManager import be.mygod.vpnhotspot.util.Services +import be.mygod.vpnhotspot.util.allInterfaceNames import be.mygod.vpnhotspot.util.launchUrl import be.mygod.vpnhotspot.util.showAllowingStateLoss import be.mygod.vpnhotspot.widget.SmartSnackbar @@ -148,8 +149,8 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() { UpstreamMonitor.KEY, FallbackUpstreamMonitor.KEY -> AlwaysAutoCompleteEditTextPreferenceDialogFragment().apply { setArguments(preference.key, Services.connectivity.allNetworks.mapNotNull { - Services.connectivity.getLinkProperties(it)?.interfaceName - }.toTypedArray()) + Services.connectivity.getLinkProperties(it)?.allInterfaceNames + }.flatten().toTypedArray()) setTargetFragment(this@SettingsPreferenceFragment, 0) }.showAllowingStateLoss(parentFragmentManager, preference.key) else -> super.onDisplayPreferenceDialog(preference) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/InterfaceMonitor.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/InterfaceMonitor.kt index 76929848..3b2c4cc8 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/InterfaceMonitor.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/monitor/InterfaceMonitor.kt @@ -2,6 +2,7 @@ package be.mygod.vpnhotspot.net.monitor import android.net.LinkProperties import be.mygod.vpnhotspot.util.Services +import be.mygod.vpnhotspot.util.allInterfaceNames import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -29,7 +30,7 @@ class InterfaceMonitor(val iface: String) : UpstreamMonitor() { private set override val currentLinkProperties get() = Services.connectivity.allNetworks .map { Services.connectivity.getLinkProperties(it) } - .singleOrNull { it?.interfaceName == iface } + .singleOrNull { it?.allInterfaceNames?.contains(iface) == true } override fun registerCallbackLocked(callback: Callback) { if (!registered) { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/preference/UpstreamsPreference.kt b/mobile/src/main/java/be/mygod/vpnhotspot/preference/UpstreamsPreference.kt index 8c739dd9..07cf5f1f 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/preference/UpstreamsPreference.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/preference/UpstreamsPreference.kt @@ -14,6 +14,7 @@ import be.mygod.vpnhotspot.R import be.mygod.vpnhotspot.net.monitor.FallbackUpstreamMonitor import be.mygod.vpnhotspot.net.monitor.UpstreamMonitor import be.mygod.vpnhotspot.util.SpanFormatter +import be.mygod.vpnhotspot.util.allRoutes import be.mygod.vpnhotspot.util.parseNumericAddress import timber.log.Timber @@ -33,7 +34,7 @@ class UpstreamsPreference(context: Context, attrs: AttributeSet) : Preference(co } ?: "∅" override fun onAvailable(ifname: String, properties: LinkProperties) { - currentInterface = Interface(ifname, properties.routes.any { + currentInterface = Interface(ifname, properties.allRoutes.any { try { it.matches(internetAddress) } catch (e: RuntimeException) { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt b/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt index 8fd8f8d4..6b7c3ddd 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt @@ -4,6 +4,8 @@ import android.annotation.SuppressLint import android.annotation.TargetApi import android.content.* import android.net.InetAddresses +import android.net.LinkProperties +import android.net.RouteInfo import android.os.Build import android.os.Handler import android.os.RemoteException @@ -109,6 +111,13 @@ fun parseNumericAddress(address: String) = if (Build.VERSION.SDK_INT >= 29) { InetAddresses.parseNumericAddress(address) } else parseNumericAddress(null, address) as InetAddress +private val getAllInterfaceNames by lazy { LinkProperties::class.java.getDeclaredMethod("getAllInterfaceNames") } +@Suppress("UNCHECKED_CAST") +val LinkProperties.allInterfaceNames get() = getAllInterfaceNames.invoke(this) as List +private val getAllRoutes by lazy { LinkProperties::class.java.getDeclaredMethod("getAllRoutes") } +@Suppress("UNCHECKED_CAST") +val LinkProperties.allRoutes get() = getAllRoutes.invoke(this) as List + fun Context.launchUrl(url: String) { if (app.hasTouch) try { app.customTabsIntent.launchUrl(this, url.toUri())