diff --git a/mobile/src/main/java/be/mygod/librootkotlinx/RootServer.kt b/mobile/src/main/java/be/mygod/librootkotlinx/RootServer.kt index f6f5fc4e..b962bc87 100644 --- a/mobile/src/main/java/be/mygod/librootkotlinx/RootServer.kt +++ b/mobile/src/main/java/be/mygod/librootkotlinx/RootServer.kt @@ -218,9 +218,9 @@ class RootServer { throw e } finally { Logger.me.d("Waiting for exit") - errorReader.await() + withContext(NonCancellable) { errorReader.await() } process.waitFor() - withContext(NonCancellable) { closeInternal(true) } + closeInternal(true) } } } @@ -290,7 +290,7 @@ class RootServer { } } - private suspend fun closeInternal(fromWorker: Boolean = false) = synchronized(callbackLookup) { + private fun closeInternal(fromWorker: Boolean = false) = synchronized(callbackLookup) { if (active) { active = false Logger.me.d(if (fromWorker) "Shutting down from worker" else "Shutting down from client") diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/App.kt b/mobile/src/main/java/be/mygod/vpnhotspot/App.kt index 9a17ac79..714a162e 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/App.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/App.kt @@ -61,6 +61,7 @@ class App : Application() { } } Timber.plant(object : Timber.DebugTree() { + @SuppressLint("LogNotTimber") override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { if (t == null) { if (priority != Log.DEBUG || BuildConfig.DEBUG) Log.println(priority, tag, message) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt index 56b20c56..72127da6 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt @@ -389,7 +389,10 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene setDeviceAddress(deviceAddress?.toPlatform()) }.build(), listener) } - } catch (e: RuntimeException) { + } catch (e: SecurityException) { + Timber.w(e) + startFailure(e.readableMessage) + } catch (e: IllegalArgumentException) { Timber.w(e) startFailure(e.readableMessage) } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotManager.kt index c2d7d51e..75906a0c 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/LocalOnlyHotspotManager.kt @@ -1,7 +1,6 @@ package be.mygod.vpnhotspot.manage import android.Manifest -import android.annotation.TargetApi import android.content.* import android.location.LocationManager import android.os.Build @@ -9,6 +8,7 @@ import android.os.IBinder import android.provider.Settings import android.view.View import android.widget.Toast +import androidx.annotation.RequiresApi import androidx.core.content.getSystemService import androidx.recyclerview.widget.RecyclerView import be.mygod.vpnhotspot.App.Companion.app @@ -20,7 +20,7 @@ import be.mygod.vpnhotspot.util.formatAddresses import be.mygod.vpnhotspot.widget.SmartSnackbar import java.net.NetworkInterface -@TargetApi(26) +@RequiresApi(26) class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager(), ServiceConnection { companion object { val permission = if (Build.VERSION.SDK_INT >= 29) { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt index e3f0b3fe..4637a66c 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/manage/TetheringFragment.kt @@ -45,24 +45,27 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick inner class ManagerAdapter : ListAdapter(Manager), TetheringManager.TetheringEventCallback { internal val repeaterManager by lazy { RepeaterManager(this@TetheringFragment) } + @delegate:TargetApi(26) @get:RequiresApi(26) - internal val localOnlyHotspotManager by lazy @TargetApi(26) { LocalOnlyHotspotManager(this@TetheringFragment) } - internal val bluetoothManager by lazy @TargetApi(24) { TetherManager.Bluetooth(this@TetheringFragment) } + internal val localOnlyHotspotManager by lazy { LocalOnlyHotspotManager(this@TetheringFragment) } + @delegate:TargetApi(24) @get:RequiresApi(24) - private val tetherManagers by lazy @TargetApi(24) { + internal val bluetoothManager by lazy { TetherManager.Bluetooth(this@TetheringFragment) } + @delegate:TargetApi(24) + @get:RequiresApi(24) + private val tetherManagers by lazy { listOf(TetherManager.Wifi(this@TetheringFragment), TetherManager.Usb(this@TetheringFragment), bluetoothManager) } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val tetherManagers30 by lazy @TargetApi(30) { + private val tetherManagers30 by lazy { listOf(TetherManager.Ethernet(this@TetheringFragment), TetherManager.Ncm(this@TetheringFragment), TetherManager.WiGig(this@TetheringFragment)) } - private val wifiManagerLegacy by lazy @Suppress("Deprecation") { - TetherManager.WifiLegacy(this@TetheringFragment) - } + private val wifiManagerLegacy by lazy { TetherManager.WifiLegacy(this@TetheringFragment) } private var enabledIfaces = emptyList() private var listDeferred = CompletableDeferred>(emptyList()) @@ -225,7 +228,7 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick } } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { AlertDialogFragment.setResultListener(this) { which, ret -> if (which == DialogInterface.BUTTON_POSITIVE) viewLifecycleOwner.lifecycleScope.launchWhenCreated { val configuration = ret!!.configuration diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/TetheringManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/TetheringManager.kt index e60406b2..610ca7c3 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/TetheringManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/TetheringManager.kt @@ -7,7 +7,6 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.content.pm.PackageManager -import android.content.pm.ResolveInfo import android.net.ConnectivityManager import android.net.Network import android.os.Build @@ -173,8 +172,9 @@ object TetheringManager { @get:RequiresApi(30) private val clazz by lazy { Class.forName("android.net.TetheringManager") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val instance by lazy @TargetApi(30) { + private val instance by lazy { @SuppressLint("WrongConstant") // hidden services are not included in constants as of R preview 4 val service = Services.context.getSystemService(TETHERING_SERVICE) service diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt index b6ff123e..fe83a470 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt @@ -108,41 +108,48 @@ data class SoftApConfigurationCompat( android.net.wifi.WifiConfiguration::class.java.getDeclaredField("apChannel") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val getAllowedClientList by lazy @TargetApi(30) { + private val getAllowedClientList by lazy { SoftApConfiguration::class.java.getDeclaredMethod("getAllowedClientList") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val getBand by lazy @TargetApi(30) { SoftApConfiguration::class.java.getDeclaredMethod("getBand") } + private val getBand by lazy { SoftApConfiguration::class.java.getDeclaredMethod("getBand") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val getBlockedClientList by lazy @TargetApi(30) { + private val getBlockedClientList by lazy { SoftApConfiguration::class.java.getDeclaredMethod("getBlockedClientList") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val getChannel by lazy @TargetApi(30) { - SoftApConfiguration::class.java.getDeclaredMethod("getChannel") - } + private val getChannel by lazy { SoftApConfiguration::class.java.getDeclaredMethod("getChannel") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val getMaxNumberOfClients by lazy @TargetApi(30) { + private val getMaxNumberOfClients by lazy { SoftApConfiguration::class.java.getDeclaredMethod("getMaxNumberOfClients") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val getShutdownTimeoutMillis by lazy @TargetApi(30) { + private val getShutdownTimeoutMillis by lazy { SoftApConfiguration::class.java.getDeclaredMethod("getShutdownTimeoutMillis") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val isAutoShutdownEnabled by lazy @TargetApi(30) { + private val isAutoShutdownEnabled by lazy { SoftApConfiguration::class.java.getDeclaredMethod("isAutoShutdownEnabled") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val isClientControlByUserEnabled by lazy @TargetApi(30) { + private val isClientControlByUserEnabled by lazy { SoftApConfiguration::class.java.getDeclaredMethod("isClientControlByUserEnabled") } @get:RequiresApi(30) private val classBuilder by lazy { Class.forName("android.net.wifi.SoftApConfiguration\$Builder") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val newBuilder by lazy @TargetApi(30) { classBuilder.getConstructor(SoftApConfiguration::class.java) } + private val newBuilder by lazy { classBuilder.getConstructor(SoftApConfiguration::class.java) } @get:RequiresApi(30) private val build by lazy { classBuilder.getDeclaredMethod("build") } @get:RequiresApi(30) @@ -159,10 +166,9 @@ data class SoftApConfigurationCompat( private val setBlockedClientList by lazy { classBuilder.getDeclaredMethod("setBlockedClientList", java.util.List::class.java) } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val setBssid by lazy @TargetApi(30) { - classBuilder.getDeclaredMethod("setBssid", MacAddress::class.java) - } + private val setBssid by lazy { classBuilder.getDeclaredMethod("setBssid", MacAddress::class.java) } @get:RequiresApi(30) private val setChannel by lazy { classBuilder.getDeclaredMethod("setChannel", Int::class.java, Int::class.java) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApInfo.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApInfo.kt index ccec77cf..413260b9 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApInfo.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApInfo.kt @@ -19,8 +19,9 @@ value class SoftApInfo(val inner: Parcelable) { private val getBssid by lazy { clazz.getDeclaredMethod("getBssid") } @get:RequiresApi(31) private val getWifiStandard by lazy { clazz.getDeclaredMethod("getWifiStandard") } + @delegate:TargetApi(31) @get:RequiresApi(31) - private val getApInstanceIdentifier by lazy @TargetApi(31) { UnblockCentral.getApInstanceIdentifier(clazz) } + private val getApInstanceIdentifier by lazy { UnblockCentral.getApInstanceIdentifier(clazz) } @get:RequiresApi(31) private val getAutoShutdownTimeoutMillis by lazy { clazz.getDeclaredMethod("getAutoShutdownTimeoutMillis") } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApManager.kt index 16e11e06..1e3fb1df 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiApManager.kt @@ -3,7 +3,6 @@ package be.mygod.vpnhotspot.net.wifi import android.annotation.TargetApi import android.content.Intent import android.content.pm.PackageManager -import android.net.MacAddress import android.net.wifi.SoftApConfiguration import android.net.wifi.WifiManager import android.os.Build @@ -43,8 +42,9 @@ object WifiApManager { } @get:RequiresApi(30) private val getSoftApConfiguration by lazy { WifiManager::class.java.getDeclaredMethod("getSoftApConfiguration") } + @delegate:TargetApi(30) @get:RequiresApi(30) - private val setSoftApConfiguration by lazy @TargetApi(30) { + private val setSoftApConfiguration by lazy { WifiManager::class.java.getDeclaredMethod("setSoftApConfiguration", SoftApConfiguration::class.java) } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiClient.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiClient.kt index 57edc1a3..c14de2b4 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiClient.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/WifiClient.kt @@ -13,8 +13,9 @@ value class WifiClient(val inner: Parcelable) { companion object { private val clazz by lazy { Class.forName("android.net.wifi.WifiClient") } private val getMacAddress by lazy { clazz.getDeclaredMethod("getMacAddress") } + @delegate:TargetApi(31) @get:RequiresApi(31) - private val getApInstanceIdentifier by lazy @TargetApi(31) { UnblockCentral.getApInstanceIdentifier(clazz) } + private val getApInstanceIdentifier by lazy { UnblockCentral.getApInstanceIdentifier(clazz) } } val macAddress get() = getMacAddress(inner) as MacAddress 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 bbbc216e..e43dce63 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 @@ -95,10 +95,10 @@ object WifiP2pManagerHelper { return result.future.await() } - private val interfacePersistentGroupInfoListener by lazy @SuppressLint("PrivateApi") { + private val interfacePersistentGroupInfoListener by lazy { Class.forName("android.net.wifi.p2p.WifiP2pManager\$PersistentGroupInfoListener") } - private val getGroupList by lazy @SuppressLint("PrivateApi") { + private val getGroupList by lazy { Class.forName("android.net.wifi.p2p.WifiP2pGroupList").getDeclaredMethod("getGroupList") } private val requestPersistentGroupInfo by lazy { @@ -111,7 +111,6 @@ object WifiP2pManagerHelper { * Requires one of NETWORK_SETTING, NETWORK_STACK, or READ_WIFI_CREDENTIAL permission since API 30. * * @param c is the channel created at {@link #initialize} - * @param listener for callback when persistent group info list is available. Can be null. */ suspend fun WifiP2pManager.requestPersistentGroupInfo(c: WifiP2pManager.Channel): Collection { val result = CompletableDeferred>() diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/root/MiscCommands.kt b/mobile/src/main/java/be/mygod/vpnhotspot/root/MiscCommands.kt index 34773089..7f588c79 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/root/MiscCommands.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/root/MiscCommands.kt @@ -102,8 +102,8 @@ class ProcessListener(private val terminateRegex: Regex, try { launch(parent) { try { - process.inputStream.bufferedReader().useLines { - for (line in it) { + process.inputStream.bufferedReader().useLines { lines -> + for (line in lines) { trySend(ProcessData.StdoutLine(line)).onClosed { return@useLines }.onFailure { throw it!! } if (terminateRegex.containsMatchIn(line)) process.destroy() } @@ -112,8 +112,8 @@ class ProcessListener(private val terminateRegex: Regex, } launch(parent) { try { - process.errorStream.bufferedReader().useLines { - for (line in it) trySend(ProcessData.StdoutLine(line)).onClosed { + process.errorStream.bufferedReader().useLines { lines -> + for (line in lines) trySend(ProcessData.StdoutLine(line)).onClosed { return@useLines }.onFailure { throw it!! } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/root/RootManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/root/RootManager.kt index d874958f..a9bebf3b 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/root/RootManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/root/RootManager.kt @@ -1,5 +1,6 @@ package be.mygod.vpnhotspot.root +import android.annotation.SuppressLint import android.os.Parcelable import android.util.Log import be.mygod.librootkotlinx.* @@ -13,6 +14,7 @@ object RootManager : RootSession(), Logger { class RootInit : RootCommandNoResult { override suspend fun execute(): Parcelable? { Timber.plant(object : Timber.DebugTree() { + @SuppressLint("LogNotTimber") override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { if (priority >= Log.WARN) { System.err.println("$priority/$tag: $message") diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/root/RoutingCommands.kt b/mobile/src/main/java/be/mygod/vpnhotspot/root/RoutingCommands.kt index 4bef650d..f43fbad9 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/root/RoutingCommands.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/root/RoutingCommands.kt @@ -1,7 +1,6 @@ package be.mygod.vpnhotspot.root import android.os.Parcelable -import android.util.Log import be.mygod.librootkotlinx.RootCommand import be.mygod.librootkotlinx.RootCommandOneWay import be.mygod.vpnhotspot.net.Routing @@ -10,6 +9,7 @@ import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize +import timber.log.Timber object RoutingCommands { @Parcelize @@ -20,7 +20,7 @@ object RoutingCommands { process.outputStream.bufferedWriter().use(Routing.Companion::appendCleanCommands) when (val code = process.waitFor()) { 0 -> { } - else -> Log.d("RoutingCommands.Clean", "Unexpected exit code $code") + else -> Timber.w("Unexpected exit code $code") } check(process.waitFor() == 0) } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/root/WifiApCommands.kt b/mobile/src/main/java/be/mygod/vpnhotspot/root/WifiApCommands.kt index 23c6bbd1..a8be8569 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/root/WifiApCommands.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/root/WifiApCommands.kt @@ -1,6 +1,5 @@ package be.mygod.vpnhotspot.root -import android.net.MacAddress import android.os.Parcelable import androidx.annotation.RequiresApi import be.mygod.librootkotlinx.ParcelableBoolean @@ -58,7 +57,7 @@ object WifiApCommands { @Parcelize @RequiresApi(28) class RegisterSoftApCallback : RootCommandChannel { - override fun create(scope: CoroutineScope) = scope.produce(capacity = capacity) { + override fun create(scope: CoroutineScope) = scope.produce(capacity = capacity) { val finish = CompletableDeferred() val key = WifiApManager.registerSoftApCallback(object : WifiApManager.SoftApCallbackCompat { private fun push(parcel: SoftApCallbackParcel) { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/util/Services.kt b/mobile/src/main/java/be/mygod/vpnhotspot/util/Services.kt index 03ae7e29..4d17d675 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/util/Services.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/util/Services.kt @@ -1,15 +1,12 @@ package be.mygod.vpnhotspot.util -import android.annotation.SuppressLint import android.content.Context import android.net.ConnectivityManager import android.net.wifi.WifiManager import android.net.wifi.p2p.WifiP2pManager -import android.util.Log import androidx.core.content.getSystemService import timber.log.Timber -@SuppressLint("LogNotTimber") object Services { private lateinit var contextInit: () -> Context val context by lazy { contextInit() } @@ -22,7 +19,7 @@ object Services { try { context.getSystemService() } catch (e: RuntimeException) { - if (android.os.Process.myUid() == 0) Log.w("WifiP2pManager", e) else Timber.w(e) + Timber.w(e) null } } 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 49b0ac70..0e6bc5c3 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/util/Utils.kt @@ -90,7 +90,6 @@ private val formatSequence = "%([0-9]+\\$|