Fix persistent group on Android 11
Also only request persistent group when necessary.
This commit is contained in:
@@ -162,7 +162,6 @@ Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded
|
|||||||
* (since API 26) [`Landroid/net/wifi/WifiManager;->cancelLocalOnlyHotspotRequest()V,greylist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#154947s)
|
* (since API 26) [`Landroid/net/wifi/WifiManager;->cancelLocalOnlyHotspotRequest()V,greylist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#154947s)
|
||||||
* (prior to API 26) `Landroid/net/wifi/WifiManager;->setWifiApEnabled(Landroid/net/wifi/WifiConfiguration;Z)Z`
|
* (prior to API 26) `Landroid/net/wifi/WifiManager;->setWifiApEnabled(Landroid/net/wifi/WifiConfiguration;Z)Z`
|
||||||
* [`Landroid/net/wifi/p2p/WifiP2pConfig$Builder;->MAC_ANY_ADDRESS:Landroid/net/MacAddress;,blacklist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#157883)
|
* [`Landroid/net/wifi/p2p/WifiP2pConfig$Builder;->MAC_ANY_ADDRESS:Landroid/net/MacAddress;,blacklist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#157883)
|
||||||
* (prior to API 30) [`Landroid/net/wifi/p2p/WifiP2pManager;->WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION:Ljava/lang/String;,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#134686)
|
|
||||||
* [`Landroid/net/wifi/p2p/WifiP2pManager;->startWps(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/WpsInfo;Landroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V,greylist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158332)
|
* [`Landroid/net/wifi/p2p/WifiP2pManager;->startWps(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/WpsInfo;Landroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V,greylist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158332)
|
||||||
* (since API 28) [`Landroid/provider/Settings$Global;->SOFT_AP_TIMEOUT_ENABLED:Ljava/lang/String;,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#183735)
|
* (since API 28) [`Landroid/provider/Settings$Global;->SOFT_AP_TIMEOUT_ENABLED:Ljava/lang/String;,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#183735)
|
||||||
* (prior to API 30) [`Lcom/android/internal/R$array;->config_tether_bluetooth_regexs:I,greylist-max-q`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#272546)
|
* (prior to API 30) [`Lcom/android/internal/R$array;->config_tether_bluetooth_regexs:I,greylist-max-q`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#272546)
|
||||||
@@ -251,7 +250,6 @@ Hidden whitelisted APIs: (same catch as above, however, things in this list are
|
|||||||
* (prior to API 30) [`Landroid/net/wifi/WifiManager;->setWifiApConfiguration(Landroid/net/wifi/WifiConfiguration;)Z,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#155067)
|
* (prior to API 30) [`Landroid/net/wifi/WifiManager;->setWifiApConfiguration(Landroid/net/wifi/WifiConfiguration;)Z,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#155067)
|
||||||
* [`Landroid/net/wifi/p2p/WifiP2pGroupList;->getGroupList()Ljava/util/List;,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158079)
|
* [`Landroid/net/wifi/p2p/WifiP2pGroupList;->getGroupList()Ljava/util/List;,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158079)
|
||||||
* [`Landroid/net/wifi/p2p/WifiP2pManager$PersistentGroupInfoListener;->onPersistentGroupInfoAvailable(Landroid/net/wifi/p2p/WifiP2pGroupList;)V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158156)
|
* [`Landroid/net/wifi/p2p/WifiP2pManager$PersistentGroupInfoListener;->onPersistentGroupInfoAvailable(Landroid/net/wifi/p2p/WifiP2pGroupList;)V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158156)
|
||||||
* (since API 30) [`Landroid/net/wifi/p2p/WifiP2pManager;->ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED:Ljava/lang/String;,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158160)
|
|
||||||
* [`Landroid/net/wifi/p2p/WifiP2pManager;->deletePersistentGroup(Landroid/net/wifi/p2p/WifiP2pManager$Channel;ILandroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158296)
|
* [`Landroid/net/wifi/p2p/WifiP2pManager;->deletePersistentGroup(Landroid/net/wifi/p2p/WifiP2pManager$Channel;ILandroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158296)
|
||||||
* [`Landroid/net/wifi/p2p/WifiP2pManager;->requestPersistentGroupInfo(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/p2p/WifiP2pManager$PersistentGroupInfoListener;)V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158320)
|
* [`Landroid/net/wifi/p2p/WifiP2pManager;->requestPersistentGroupInfo(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/p2p/WifiP2pManager$PersistentGroupInfoListener;)V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158320)
|
||||||
* [`Landroid/net/wifi/p2p/WifiP2pManager;->setWifiP2pChannels(Landroid/net/wifi/p2p/WifiP2pManager$Channel;IILandroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158330)
|
* [`Landroid/net/wifi/p2p/WifiP2pManager;->setWifiP2pChannels(Landroid/net/wifi/p2p/WifiP2pManager$Channel;IILandroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V,system-api,whitelist`](https://android.googlesource.com/platform/prebuilts/runtime/+/4601d91/appcompat/hiddenapi-flags.csv#158330)
|
||||||
@@ -270,7 +268,6 @@ Nonexported system resources:
|
|||||||
Other:
|
Other:
|
||||||
|
|
||||||
* (since API 29) `android.net.wifi.p2p.WifiP2pConfig` needs to be parcelized in a very specific order, except for possible extra fields at the end. (used only for safe mode)
|
* (since API 29) `android.net.wifi.p2p.WifiP2pConfig` needs to be parcelized in a very specific order, except for possible extra fields at the end. (used only for safe mode)
|
||||||
* Broadcast `android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED` is assumed to be sticky.
|
|
||||||
* Activity `com.android.settings/.Settings$TetherSettingsActivity` is assumed to be exported.
|
* Activity `com.android.settings/.Settings$TetherSettingsActivity` is assumed to be exported.
|
||||||
|
|
||||||
For `ip rule` priorities, `RULE_PRIORITY_SECURE_VPN` and `RULE_PRIORITY_TETHERING` is assumed to be 12000 and 18000 respectively;
|
For `ip rule` priorities, `RULE_PRIORITY_SECURE_VPN` and `RULE_PRIORITY_TETHERING` is assumed to be 12000 and 18000 respectively;
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import be.mygod.vpnhotspot.widget.SmartSnackbar
|
|||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.lang.reflect.InvocationTargetException
|
import java.lang.reflect.InvocationTargetException
|
||||||
import java.net.NetworkInterface
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,6 +114,57 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
|
|||||||
}
|
}
|
||||||
val groupChanged = StickyEvent1 { group }
|
val groupChanged = StickyEvent1 { group }
|
||||||
|
|
||||||
|
@SuppressLint("NewApi") // networkId is available since Android 4.2
|
||||||
|
suspend fun fetchPersistentGroup() {
|
||||||
|
val ownerAddress = lastMac?.let(MacAddressCompat.Companion::fromString) ?: try {
|
||||||
|
P2pSupplicantConfiguration().apply { init() }.bssid
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.d(e)
|
||||||
|
null
|
||||||
|
} ?: return
|
||||||
|
val channel = channel ?: return
|
||||||
|
fun Collection<WifiP2pGroup>.filterUselessGroups(): List<WifiP2pGroup> {
|
||||||
|
if (isNotEmpty()) persistentSupported = true
|
||||||
|
val ownedGroups = filter {
|
||||||
|
if (!it.isGroupOwner) return@filter false
|
||||||
|
val address = MacAddressCompat.fromString(it.owner.deviceAddress)
|
||||||
|
// WifiP2pServiceImpl only removes self address
|
||||||
|
Build.VERSION.SDK_INT >= 29 && address == MacAddressCompat.ANY_ADDRESS || address == ownerAddress
|
||||||
|
}
|
||||||
|
val main = ownedGroups.minBy { it.networkId }
|
||||||
|
// do not replace current group if it's better
|
||||||
|
if (binder.group?.passphrase == null) binder.group = main
|
||||||
|
return if (main != null) ownedGroups.filter { it.networkId != main.networkId } else emptyList()
|
||||||
|
}
|
||||||
|
fun Int?.print(group: WifiP2pGroup) {
|
||||||
|
if (this == null) Timber.i("Removed redundant owned group: $group")
|
||||||
|
else SmartSnackbar.make(formatReason(R.string.repeater_clean_pog_failure, this)).show()
|
||||||
|
}
|
||||||
|
// we only get empty list on permission denial. Is there a better permission check?
|
||||||
|
if (Build.VERSION.SDK_INT < 30 || checkSelfPermission("android.permission.READ_WIFI_CREDENTIAL") ==
|
||||||
|
PackageManager.PERMISSION_GRANTED) try {
|
||||||
|
for (group in p2pManager.requestPersistentGroupInfo(channel).filterUselessGroups()) {
|
||||||
|
p2pManager.deletePersistentGroup(channel, group.networkId).print(group)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} catch (e: ReflectiveOperationException) {
|
||||||
|
Timber.w(e)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
RootManager.use { server ->
|
||||||
|
if (deinitPending.getAndSet(false)) server.execute(RepeaterCommands.Deinit())
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val groups = server.execute(RepeaterCommands.RequestPersistentGroupInfo()).value as List<WifiP2pGroup>
|
||||||
|
for (group in groups.filterUselessGroups()) {
|
||||||
|
server.execute(RepeaterCommands.DeletePersistentGroup(group.networkId))?.value.print(group)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.w(e)
|
||||||
|
SmartSnackbar.make(e).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun startWps(pin: String? = null) {
|
fun startWps(pin: String? = null) {
|
||||||
val channel = channel
|
val channel = channel
|
||||||
if (channel == null) SmartSnackbar.make(R.string.repeater_failure_disconnected).show()
|
if (channel == null) SmartSnackbar.make(R.string.repeater_failure_disconnected).show()
|
||||||
@@ -154,15 +204,10 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private val deviceListener = broadcastReceiver { _, intent ->
|
private val deviceListener = broadcastReceiver { _, intent ->
|
||||||
when (intent.action) {
|
|
||||||
WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION -> {
|
|
||||||
val addr = intent.getParcelableExtra<WifiP2pDevice>(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)?.deviceAddress
|
val addr = intent.getParcelableExtra<WifiP2pDevice>(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)?.deviceAddress
|
||||||
if (!addr.isNullOrEmpty() && (Build.VERSION.SDK_INT < 29 ||
|
if (!addr.isNullOrEmpty() && (Build.VERSION.SDK_INT < 29 ||
|
||||||
MacAddressCompat.fromString(addr) != MacAddressCompat.ANY_ADDRESS)) lastMac = addr
|
MacAddressCompat.fromString(addr) != MacAddressCompat.ANY_ADDRESS)) lastMac = addr
|
||||||
}
|
}
|
||||||
WifiP2pManagerHelper.ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED -> if (!safeMode) onPersistentGroupsChanged()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Writes and critical reads to routingManager should be protected with this context.
|
* Writes and critical reads to routingManager should be protected with this context.
|
||||||
*/
|
*/
|
||||||
@@ -193,8 +238,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
onChannelDisconnected()
|
onChannelDisconnected()
|
||||||
registerReceiver(deviceListener, intentFilter(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION,
|
registerReceiver(deviceListener, intentFilter(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION))
|
||||||
WifiP2pManagerHelper.ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED))
|
|
||||||
app.pref.registerOnSharedPreferenceChangeListener(this)
|
app.pref.registerOnSharedPreferenceChangeListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,62 +295,10 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
|
|||||||
KEY_SAFE_MODE -> {
|
KEY_SAFE_MODE -> {
|
||||||
deinitPending.set(true)
|
deinitPending.set(true)
|
||||||
setOperatingChannel()
|
setOperatingChannel()
|
||||||
onPersistentGroupsChanged()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi") // networkId is available since Android 4.2
|
|
||||||
private fun onPersistentGroupsChanged() = launch {
|
|
||||||
val ownerAddress = lastMac?.let(MacAddressCompat.Companion::fromString) ?: try {
|
|
||||||
P2pSupplicantConfiguration().apply { init() }.bssid
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.d(e)
|
|
||||||
null
|
|
||||||
} ?: return@launch
|
|
||||||
val channel = channel ?: return@launch
|
|
||||||
fun Collection<WifiP2pGroup>.filterUselessGroups(): List<WifiP2pGroup> {
|
|
||||||
if (isNotEmpty()) persistentSupported = true
|
|
||||||
val ownedGroups = filter {
|
|
||||||
if (!it.isGroupOwner) return@filter false
|
|
||||||
val address = MacAddressCompat.fromString(it.owner.deviceAddress)
|
|
||||||
// WifiP2pServiceImpl only removes self address
|
|
||||||
Build.VERSION.SDK_INT >= 29 && address == MacAddressCompat.ANY_ADDRESS || address == ownerAddress
|
|
||||||
}
|
|
||||||
val main = ownedGroups.minBy { it.networkId }
|
|
||||||
// do not replace current group if it's better
|
|
||||||
if (binder.group?.passphrase == null) binder.group = main
|
|
||||||
return if (main != null) ownedGroups.filter { it.networkId != main.networkId } else emptyList()
|
|
||||||
}
|
|
||||||
fun Int?.print(group: WifiP2pGroup) {
|
|
||||||
if (this == null) Timber.i("Removed redundant owned group: $group")
|
|
||||||
else SmartSnackbar.make(formatReason(R.string.repeater_clean_pog_failure, this)).show()
|
|
||||||
}
|
|
||||||
// we only get empty list on permission denial. Is there a better permission check?
|
|
||||||
if (Build.VERSION.SDK_INT < 30 || checkSelfPermission("android.permission.READ_WIFI_CREDENTIAL") ==
|
|
||||||
PackageManager.PERMISSION_GRANTED) try {
|
|
||||||
for (group in p2pManager.requestPersistentGroupInfo(channel).filterUselessGroups()) {
|
|
||||||
p2pManager.deletePersistentGroup(channel, group.networkId).print(group)
|
|
||||||
}
|
|
||||||
return@launch
|
|
||||||
} catch (e: ReflectiveOperationException) {
|
|
||||||
Timber.w(e)
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
RootManager.use { server ->
|
|
||||||
if (deinitPending.getAndSet(false)) server.execute(RepeaterCommands.Deinit())
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
val groups = server.execute(RepeaterCommands.RequestPersistentGroupInfo()).value as List<WifiP2pGroup>
|
|
||||||
for (group in groups.filterUselessGroups()) {
|
|
||||||
server.execute(RepeaterCommands.DeletePersistentGroup(group.networkId))?.value.print(group)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.w(e)
|
|
||||||
SmartSnackbar.make(e).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* startService Step 1
|
* startService Step 1
|
||||||
*/
|
*/
|
||||||
@@ -328,7 +320,9 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
|
|||||||
else -> {
|
else -> {
|
||||||
Timber.i("Removing old group ($it)")
|
Timber.i("Removing old group ($it)")
|
||||||
p2pManager.removeGroup(channel, object : WifiP2pManager.ActionListener {
|
p2pManager.removeGroup(channel, object : WifiP2pManager.ActionListener {
|
||||||
override fun onSuccess() = doStart()
|
override fun onSuccess() {
|
||||||
|
doStart()
|
||||||
|
}
|
||||||
override fun onFailure(reason: Int) =
|
override fun onFailure(reason: Int) =
|
||||||
startFailure(formatReason(R.string.repeater_remove_old_group_failure, reason))
|
startFailure(formatReason(R.string.repeater_remove_old_group_failure, reason))
|
||||||
})
|
})
|
||||||
@@ -345,7 +339,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
|
|||||||
/**
|
/**
|
||||||
* startService Step 2 (if a group isn't already available)
|
* startService Step 2 (if a group isn't already available)
|
||||||
*/
|
*/
|
||||||
private fun doStart() {
|
private fun doStart() = launch {
|
||||||
val listener = object : WifiP2pManager.ActionListener {
|
val listener = object : WifiP2pManager.ActionListener {
|
||||||
override fun onFailure(reason: Int) {
|
override fun onFailure(reason: Int) {
|
||||||
startFailure(formatReason(R.string.repeater_create_group_failure, reason),
|
startFailure(formatReason(R.string.repeater_create_group_failure, reason),
|
||||||
@@ -353,7 +347,8 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
|
|||||||
}
|
}
|
||||||
override fun onSuccess() { } // wait for WIFI_P2P_CONNECTION_CHANGED_ACTION to fire to go to step 3
|
override fun onSuccess() { } // wait for WIFI_P2P_CONNECTION_CHANGED_ACTION to fire to go to step 3
|
||||||
}
|
}
|
||||||
val channel = channel ?: return listener.onFailure(WifiP2pManager.BUSY)
|
val channel = channel ?: return@launch listener.onFailure(WifiP2pManager.BUSY)
|
||||||
|
if (!safeMode) binder.fetchPersistentGroup()
|
||||||
val networkName = networkName
|
val networkName = networkName
|
||||||
val passphrase = passphrase
|
val passphrase = passphrase
|
||||||
try {
|
try {
|
||||||
@@ -431,11 +426,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
|
|||||||
persistNextGroup = false
|
persistNextGroup = false
|
||||||
}
|
}
|
||||||
check(routingManager == null)
|
check(routingManager == null)
|
||||||
routingManager = object : RoutingManager.LocalOnly(this@RepeaterService, group.`interface`!!) {
|
routingManager = RoutingManager.LocalOnly(this@RepeaterService, group.`interface`!!).apply { start() }
|
||||||
override fun ifaceHandler(iface: NetworkInterface) {
|
|
||||||
iface.hardwareAddress?.let { lastMac = MacAddressCompat.bytesToString(it) }
|
|
||||||
}
|
|
||||||
}.apply { start() }
|
|
||||||
status = Status.ACTIVE
|
status = Status.ACTIVE
|
||||||
showNotification(group)
|
showNotification(group)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ abstract class RoutingManager(private val caller: Any, val downstream: String, p
|
|||||||
/**
|
/**
|
||||||
* Both repeater and local-only hotspot are Wi-Fi based.
|
* Both repeater and local-only hotspot are Wi-Fi based.
|
||||||
*/
|
*/
|
||||||
open class LocalOnly(caller: Any, downstream: String) : RoutingManager(caller, downstream, true) {
|
class LocalOnly(caller: Any, downstream: String) : RoutingManager(caller, downstream, true) {
|
||||||
override fun Routing.configure() {
|
override fun Routing.configure() {
|
||||||
ipForward() // local only interfaces need to enable ip_forward
|
ipForward() // local only interfaces need to enable ip_forward
|
||||||
forward()
|
forward()
|
||||||
@@ -84,10 +84,8 @@ abstract class RoutingManager(private val caller: Any, val downstream: String, p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun ifaceHandler(iface: NetworkInterface) { }
|
|
||||||
|
|
||||||
private fun initRoutingLocked() = try {
|
private fun initRoutingLocked() = try {
|
||||||
routing = Routing(caller, downstream, this::ifaceHandler).apply {
|
routing = Routing(caller, downstream).apply {
|
||||||
try {
|
try {
|
||||||
configure()
|
configure()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|||||||
@@ -202,8 +202,8 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic
|
|||||||
bssid = RepeaterService.deviceAddress
|
bssid = RepeaterService.deviceAddress
|
||||||
} to false
|
} to false
|
||||||
}
|
}
|
||||||
} else {
|
} else binder?.let { binder ->
|
||||||
val group = binder?.group
|
val group = binder.group ?: binder.fetchPersistentGroup().let { binder.group }
|
||||||
if (group != null) return SoftApConfigurationCompat.empty().run {
|
if (group != null) return SoftApConfigurationCompat.empty().run {
|
||||||
ssid = group.networkName
|
ssid = group.networkName
|
||||||
securityType = SoftApConfiguration.SECURITY_TYPE_WPA2_PSK // is not actually used
|
securityType = SoftApConfiguration.SECURITY_TYPE_WPA2_PSK // is not actually used
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ import java.net.SocketException
|
|||||||
*
|
*
|
||||||
* Once revert is called, this object no longer serves any purpose.
|
* Once revert is called, this object no longer serves any purpose.
|
||||||
*/
|
*/
|
||||||
class Routing(private val caller: Any, private val downstream: String,
|
class Routing(private val caller: Any, private val downstream: String) : IpNeighbourMonitor.Callback {
|
||||||
ifaceHandler: (NetworkInterface) -> Unit) : IpNeighbourMonitor.Callback {
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* Since Android 5.0, RULE_PRIORITY_TETHERING = 18000.
|
* Since Android 5.0, RULE_PRIORITY_TETHERING = 18000.
|
||||||
@@ -130,7 +129,6 @@ class Routing(private val caller: Any, private val downstream: String,
|
|||||||
|
|
||||||
private val hostAddress = try {
|
private val hostAddress = try {
|
||||||
val iface = NetworkInterface.getByName(downstream) ?: error("iface not found")
|
val iface = NetworkInterface.getByName(downstream) ?: error("iface not found")
|
||||||
ifaceHandler(iface)
|
|
||||||
val addresses = iface.interfaceAddresses!!.filter { it.address is Inet4Address }
|
val addresses = iface.interfaceAddresses!!.filter { it.address is Inet4Address }
|
||||||
if (addresses.size > 1) error("More than one addresses was found: $addresses")
|
if (addresses.size > 1) error("More than one addresses was found: $addresses")
|
||||||
addresses.first()
|
addresses.first()
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint
|
|||||||
import android.net.wifi.WpsInfo
|
import android.net.wifi.WpsInfo
|
||||||
import android.net.wifi.p2p.WifiP2pGroup
|
import android.net.wifi.p2p.WifiP2pGroup
|
||||||
import android.net.wifi.p2p.WifiP2pManager
|
import android.net.wifi.p2p.WifiP2pManager
|
||||||
import android.os.Build
|
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.util.callSuper
|
import be.mygod.vpnhotspot.util.callSuper
|
||||||
import kotlinx.coroutines.CompletableDeferred
|
import kotlinx.coroutines.CompletableDeferred
|
||||||
@@ -27,9 +26,6 @@ object WifiP2pManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const val UNSUPPORTED = -2
|
const val UNSUPPORTED = -2
|
||||||
val ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = if (Build.VERSION.SDK_INT >= 30) {
|
|
||||||
"android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED"
|
|
||||||
} else "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Available since Android 4.4.
|
* Available since Android 4.4.
|
||||||
|
|||||||
Reference in New Issue
Block a user