diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt index 67274ce7..f16f5bff 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt @@ -17,10 +17,10 @@ import be.mygod.librootkotlinx.useParcel import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.net.MacAddressCompat import be.mygod.vpnhotspot.net.monitor.TetherTimeoutMonitor -import be.mygod.vpnhotspot.net.wifi.P2pSupplicantConfiguration import be.mygod.vpnhotspot.net.wifi.SoftApConfigurationCompat import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.deletePersistentGroup +import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.requestDeviceAddress import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.requestPersistentGroupInfo import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.setWifiP2pChannels import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.startWps @@ -40,7 +40,6 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene SharedPreferences.OnSharedPreferenceChangeListener { companion object { const val KEY_SAFE_MODE = "service.repeater.safeMode" - private const val KEY_LAST_MAC = "service.repeater.lastMac.v2" private const val KEY_NETWORK_NAME = "service.repeater.networkName" private const val KEY_PASSPHRASE = "service.repeater.passphrase" @@ -64,9 +63,6 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene val safeModeConfigurable get() = Build.VERSION.SDK_INT >= 29 && hasP2pValidateName val safeMode get() = Build.VERSION.SDK_INT >= 29 && (!hasP2pValidateName || app.pref.getBoolean(KEY_SAFE_MODE, true)) - var lastMac: String? - get() = app.pref.getString(KEY_LAST_MAC, null) - set(value) = app.pref.edit { putString(KEY_LAST_MAC, value) } var networkName: String? get() = app.pref.getString(KEY_NETWORK_NAME, null) @@ -121,14 +117,18 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene } 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 + suspend fun obtainDeviceAddress(): MacAddressCompat? { + return if (Build.VERSION.SDK_INT >= 29) p2pManager.requestDeviceAddress(channel ?: return null) ?: try { + RootManager.use { it.execute(RepeaterCommands.RequestDeviceAddress()) } } catch (e: Exception) { Timber.d(e) null - } ?: return + }?.let { MacAddressCompat(it.value) } else lastMac?.let { MacAddressCompat.fromString(it) } + } + + @SuppressLint("NewApi") // networkId is available since Android 4.2 + suspend fun fetchPersistentGroup() { + val ownerAddress = obtainDeviceAddress() ?: return val channel = channel ?: return fun Collection.filterUselessGroups(): List { if (isNotEmpty()) persistentSupported = true @@ -212,9 +212,9 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene } private val deviceListener = broadcastReceiver { _, intent -> val addr = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)?.deviceAddress - if (!addr.isNullOrEmpty() && (Build.VERSION.SDK_INT < 29 || - MacAddressCompat.fromString(addr) != MacAddressCompat.ANY_ADDRESS)) lastMac = addr + if (!addr.isNullOrEmpty()) lastMac = addr } + private var lastMac: String? = null /** * Writes and critical reads to routingManager should be protected with this context. */ @@ -245,7 +245,9 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene override fun onCreate() { super.onCreate() onChannelDisconnected() - registerReceiver(deviceListener, intentFilter(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)) + if (Build.VERSION.SDK_INT < 29) { + registerReceiver(deviceListener, intentFilter(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)) + } app.pref.registerOnSharedPreferenceChangeListener(this) } @@ -494,7 +496,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene dispatcher.close() } app.pref.unregisterOnSharedPreferenceChangeListener(this) - unregisterReceiver(deviceListener) + if (Build.VERSION.SDK_INT < 29) unregisterReceiver(deviceListener) status = Status.DESTROYED if (Build.VERSION.SDK_INT >= 27) channel?.close() super.onDestroy() diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt index 2ead5f8e..ddbe1251 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/RepeaterManager.kt @@ -209,7 +209,7 @@ class RepeaterManager(private val parent: TetheringFragment) : Manager(), Servic shutdownTimeoutMillis = RepeaterService.shutdownTimeoutMillis).run { try { val config = P2pSupplicantConfiguration(group) - config.init(RepeaterService.lastMac) + config.init(binder.obtainDeviceAddress()?.toString()) holder.config = config passphrase = config.psk bssid = config.bssid diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/P2pSupplicantConfiguration.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/P2pSupplicantConfiguration.kt index 0fb8be86..13870aac 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/P2pSupplicantConfiguration.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/P2pSupplicantConfiguration.kt @@ -122,9 +122,7 @@ class P2pSupplicantConfiguration(private val group: WifiP2pGroup? = null) { if (target == null) target = this }) } - content = Content(result, target!!.apply { - RepeaterService.lastMac = bssid!! - }, persistentMacLine, legacy) + content = Content(result, target!!, persistentMacLine, legacy) } catch (e: Exception) { FirebaseCrashlytics.getInstance().apply { setCustomKey(TAG, config) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiP2pManagerHelper.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiP2pManagerHelper.kt index 6a617325..bbbc216e 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiP2pManagerHelper.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiP2pManagerHelper.kt @@ -4,7 +4,9 @@ import android.annotation.SuppressLint import android.net.wifi.WpsInfo import android.net.wifi.p2p.WifiP2pGroup import android.net.wifi.p2p.WifiP2pManager +import androidx.annotation.RequiresApi import be.mygod.vpnhotspot.App.Companion.app +import be.mygod.vpnhotspot.net.MacAddressCompat import be.mygod.vpnhotspot.util.callSuper import kotlinx.coroutines.CompletableDeferred import timber.log.Timber @@ -126,4 +128,15 @@ object WifiP2pManagerHelper { })) return result.await() } + + @SuppressLint("MissingPermission") + @RequiresApi(29) + suspend fun WifiP2pManager.requestDeviceAddress(c: WifiP2pManager.Channel): MacAddressCompat? { + val future = CompletableDeferred() + requestDeviceInfo(c) { future.complete(it?.deviceAddress) } + return future.await()?.let { + val address = if (it.isEmpty()) null else MacAddressCompat.fromString(it) + if (address == MacAddressCompat.ANY_ADDRESS) null else address + } + } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/root/RepeaterCommands.kt b/mobile/src/main/java/be/mygod/vpnhotspot/root/RepeaterCommands.kt index 9bfdaa23..43f87d58 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/root/RepeaterCommands.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/root/RepeaterCommands.kt @@ -6,11 +6,10 @@ import android.os.Parcelable import android.system.Os import android.system.OsConstants import android.text.TextUtils -import be.mygod.librootkotlinx.ParcelableInt -import be.mygod.librootkotlinx.ParcelableList -import be.mygod.librootkotlinx.RootCommand -import be.mygod.librootkotlinx.RootCommandNoResult +import androidx.annotation.RequiresApi +import be.mygod.librootkotlinx.* import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.deletePersistentGroup +import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.requestDeviceAddress import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.requestPersistentGroupInfo import be.mygod.vpnhotspot.net.wifi.WifiP2pManagerHelper.setWifiP2pChannels import be.mygod.vpnhotspot.util.Services @@ -34,6 +33,14 @@ object RepeaterCommands { } } + @Parcelize + @RequiresApi(29) + class RequestDeviceAddress : RootCommand { + override suspend fun execute() = Services.p2p!!.run { + requestDeviceAddress(obtainChannel())?.let { ParcelableLong(it.addr) } + } + } + @Parcelize class RequestPersistentGroupInfo : RootCommand { override suspend fun execute() = Services.p2p!!.run {