Refine code style

This commit is contained in:
Mygod
2021-05-27 13:33:26 -04:00
parent b6bdf8cfb7
commit 87a1b8b08d
17 changed files with 65 additions and 52 deletions

View File

@@ -218,9 +218,9 @@ class RootServer {
throw e throw e
} finally { } finally {
Logger.me.d("Waiting for exit") Logger.me.d("Waiting for exit")
errorReader.await() withContext(NonCancellable) { errorReader.await() }
process.waitFor() 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) { if (active) {
active = false active = false
Logger.me.d(if (fromWorker) "Shutting down from worker" else "Shutting down from client") Logger.me.d(if (fromWorker) "Shutting down from worker" else "Shutting down from client")

View File

@@ -61,6 +61,7 @@ class App : Application() {
} }
} }
Timber.plant(object : Timber.DebugTree() { Timber.plant(object : Timber.DebugTree() {
@SuppressLint("LogNotTimber")
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
if (t == null) { if (t == null) {
if (priority != Log.DEBUG || BuildConfig.DEBUG) Log.println(priority, tag, message) if (priority != Log.DEBUG || BuildConfig.DEBUG) Log.println(priority, tag, message)

View File

@@ -389,7 +389,10 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene
setDeviceAddress(deviceAddress?.toPlatform()) setDeviceAddress(deviceAddress?.toPlatform())
}.build(), listener) }.build(), listener)
} }
} catch (e: RuntimeException) { } catch (e: SecurityException) {
Timber.w(e)
startFailure(e.readableMessage)
} catch (e: IllegalArgumentException) {
Timber.w(e) Timber.w(e)
startFailure(e.readableMessage) startFailure(e.readableMessage)
} }

View File

@@ -1,7 +1,6 @@
package be.mygod.vpnhotspot.manage package be.mygod.vpnhotspot.manage
import android.Manifest import android.Manifest
import android.annotation.TargetApi
import android.content.* import android.content.*
import android.location.LocationManager import android.location.LocationManager
import android.os.Build import android.os.Build
@@ -9,6 +8,7 @@ import android.os.IBinder
import android.provider.Settings import android.provider.Settings
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.App.Companion.app
@@ -20,7 +20,7 @@ import be.mygod.vpnhotspot.util.formatAddresses
import be.mygod.vpnhotspot.widget.SmartSnackbar import be.mygod.vpnhotspot.widget.SmartSnackbar
import java.net.NetworkInterface import java.net.NetworkInterface
@TargetApi(26) @RequiresApi(26)
class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager(), ServiceConnection { class LocalOnlyHotspotManager(private val parent: TetheringFragment) : Manager(), ServiceConnection {
companion object { companion object {
val permission = if (Build.VERSION.SDK_INT >= 29) { val permission = if (Build.VERSION.SDK_INT >= 29) {

View File

@@ -45,24 +45,27 @@ class TetheringFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClick
inner class ManagerAdapter : ListAdapter<Manager, RecyclerView.ViewHolder>(Manager), inner class ManagerAdapter : ListAdapter<Manager, RecyclerView.ViewHolder>(Manager),
TetheringManager.TetheringEventCallback { TetheringManager.TetheringEventCallback {
internal val repeaterManager by lazy { RepeaterManager(this@TetheringFragment) } internal val repeaterManager by lazy { RepeaterManager(this@TetheringFragment) }
@delegate:TargetApi(26)
@get:RequiresApi(26) @get:RequiresApi(26)
internal val localOnlyHotspotManager by lazy @TargetApi(26) { LocalOnlyHotspotManager(this@TetheringFragment) } internal val localOnlyHotspotManager by lazy { LocalOnlyHotspotManager(this@TetheringFragment) }
internal val bluetoothManager by lazy @TargetApi(24) { TetherManager.Bluetooth(this@TetheringFragment) } @delegate:TargetApi(24)
@get:RequiresApi(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), listOf(TetherManager.Wifi(this@TetheringFragment),
TetherManager.Usb(this@TetheringFragment), TetherManager.Usb(this@TetheringFragment),
bluetoothManager) bluetoothManager)
} }
@delegate:TargetApi(30)
@get:RequiresApi(30) @get:RequiresApi(30)
private val tetherManagers30 by lazy @TargetApi(30) { private val tetherManagers30 by lazy {
listOf(TetherManager.Ethernet(this@TetheringFragment), listOf(TetherManager.Ethernet(this@TetheringFragment),
TetherManager.Ncm(this@TetheringFragment), TetherManager.Ncm(this@TetheringFragment),
TetherManager.WiGig(this@TetheringFragment)) TetherManager.WiGig(this@TetheringFragment))
} }
private val wifiManagerLegacy by lazy @Suppress("Deprecation") { private val wifiManagerLegacy by lazy { TetherManager.WifiLegacy(this@TetheringFragment) }
TetherManager.WifiLegacy(this@TetheringFragment)
}
private var enabledIfaces = emptyList<String>() private var enabledIfaces = emptyList<String>()
private var listDeferred = CompletableDeferred<List<Manager>>(emptyList()) private var listDeferred = CompletableDeferred<List<Manager>>(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<WifiApDialogFragment, WifiApDialogFragment.Arg>(this) { which, ret -> AlertDialogFragment.setResultListener<WifiApDialogFragment, WifiApDialogFragment.Arg>(this) { which, ret ->
if (which == DialogInterface.BUTTON_POSITIVE) viewLifecycleOwner.lifecycleScope.launchWhenCreated { if (which == DialogInterface.BUTTON_POSITIVE) viewLifecycleOwner.lifecycleScope.launchWhenCreated {
val configuration = ret!!.configuration val configuration = ret!!.configuration

View File

@@ -7,7 +7,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.Network import android.net.Network
import android.os.Build import android.os.Build
@@ -173,8 +172,9 @@ object TetheringManager {
@get:RequiresApi(30) @get:RequiresApi(30)
private val clazz by lazy { Class.forName("android.net.TetheringManager") } private val clazz by lazy { Class.forName("android.net.TetheringManager") }
@delegate:TargetApi(30)
@get:RequiresApi(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 @SuppressLint("WrongConstant") // hidden services are not included in constants as of R preview 4
val service = Services.context.getSystemService(TETHERING_SERVICE) val service = Services.context.getSystemService(TETHERING_SERVICE)
service service

View File

@@ -108,41 +108,48 @@ data class SoftApConfigurationCompat(
android.net.wifi.WifiConfiguration::class.java.getDeclaredField("apChannel") android.net.wifi.WifiConfiguration::class.java.getDeclaredField("apChannel")
} }
@delegate:TargetApi(30)
@get:RequiresApi(30) @get:RequiresApi(30)
private val getAllowedClientList by lazy @TargetApi(30) { private val getAllowedClientList by lazy {
SoftApConfiguration::class.java.getDeclaredMethod("getAllowedClientList") SoftApConfiguration::class.java.getDeclaredMethod("getAllowedClientList")
} }
@delegate:TargetApi(30)
@get:RequiresApi(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) @get:RequiresApi(30)
private val getBlockedClientList by lazy @TargetApi(30) { private val getBlockedClientList by lazy {
SoftApConfiguration::class.java.getDeclaredMethod("getBlockedClientList") SoftApConfiguration::class.java.getDeclaredMethod("getBlockedClientList")
} }
@delegate:TargetApi(30)
@get:RequiresApi(30) @get:RequiresApi(30)
private val getChannel by lazy @TargetApi(30) { private val getChannel by lazy { SoftApConfiguration::class.java.getDeclaredMethod("getChannel") }
SoftApConfiguration::class.java.getDeclaredMethod("getChannel") @delegate:TargetApi(30)
}
@get:RequiresApi(30) @get:RequiresApi(30)
private val getMaxNumberOfClients by lazy @TargetApi(30) { private val getMaxNumberOfClients by lazy {
SoftApConfiguration::class.java.getDeclaredMethod("getMaxNumberOfClients") SoftApConfiguration::class.java.getDeclaredMethod("getMaxNumberOfClients")
} }
@delegate:TargetApi(30)
@get:RequiresApi(30) @get:RequiresApi(30)
private val getShutdownTimeoutMillis by lazy @TargetApi(30) { private val getShutdownTimeoutMillis by lazy {
SoftApConfiguration::class.java.getDeclaredMethod("getShutdownTimeoutMillis") SoftApConfiguration::class.java.getDeclaredMethod("getShutdownTimeoutMillis")
} }
@delegate:TargetApi(30)
@get:RequiresApi(30) @get:RequiresApi(30)
private val isAutoShutdownEnabled by lazy @TargetApi(30) { private val isAutoShutdownEnabled by lazy {
SoftApConfiguration::class.java.getDeclaredMethod("isAutoShutdownEnabled") SoftApConfiguration::class.java.getDeclaredMethod("isAutoShutdownEnabled")
} }
@delegate:TargetApi(30)
@get:RequiresApi(30) @get:RequiresApi(30)
private val isClientControlByUserEnabled by lazy @TargetApi(30) { private val isClientControlByUserEnabled by lazy {
SoftApConfiguration::class.java.getDeclaredMethod("isClientControlByUserEnabled") SoftApConfiguration::class.java.getDeclaredMethod("isClientControlByUserEnabled")
} }
@get:RequiresApi(30) @get:RequiresApi(30)
private val classBuilder by lazy { Class.forName("android.net.wifi.SoftApConfiguration\$Builder") } private val classBuilder by lazy { Class.forName("android.net.wifi.SoftApConfiguration\$Builder") }
@delegate:TargetApi(30)
@get:RequiresApi(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) @get:RequiresApi(30)
private val build by lazy { classBuilder.getDeclaredMethod("build") } private val build by lazy { classBuilder.getDeclaredMethod("build") }
@get:RequiresApi(30) @get:RequiresApi(30)
@@ -159,10 +166,9 @@ data class SoftApConfigurationCompat(
private val setBlockedClientList by lazy { private val setBlockedClientList by lazy {
classBuilder.getDeclaredMethod("setBlockedClientList", java.util.List::class.java) classBuilder.getDeclaredMethod("setBlockedClientList", java.util.List::class.java)
} }
@delegate:TargetApi(30)
@get:RequiresApi(30) @get:RequiresApi(30)
private val setBssid by lazy @TargetApi(30) { private val setBssid by lazy { classBuilder.getDeclaredMethod("setBssid", MacAddress::class.java) }
classBuilder.getDeclaredMethod("setBssid", MacAddress::class.java)
}
@get:RequiresApi(30) @get:RequiresApi(30)
private val setChannel by lazy { private val setChannel by lazy {
classBuilder.getDeclaredMethod("setChannel", Int::class.java, Int::class.java) classBuilder.getDeclaredMethod("setChannel", Int::class.java, Int::class.java)

View File

@@ -19,8 +19,9 @@ value class SoftApInfo(val inner: Parcelable) {
private val getBssid by lazy { clazz.getDeclaredMethod("getBssid") } private val getBssid by lazy { clazz.getDeclaredMethod("getBssid") }
@get:RequiresApi(31) @get:RequiresApi(31)
private val getWifiStandard by lazy { clazz.getDeclaredMethod("getWifiStandard") } private val getWifiStandard by lazy { clazz.getDeclaredMethod("getWifiStandard") }
@delegate:TargetApi(31)
@get:RequiresApi(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) @get:RequiresApi(31)
private val getAutoShutdownTimeoutMillis by lazy { clazz.getDeclaredMethod("getAutoShutdownTimeoutMillis") } private val getAutoShutdownTimeoutMillis by lazy { clazz.getDeclaredMethod("getAutoShutdownTimeoutMillis") }

View File

@@ -3,7 +3,6 @@ package be.mygod.vpnhotspot.net.wifi
import android.annotation.TargetApi import android.annotation.TargetApi
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.net.MacAddress
import android.net.wifi.SoftApConfiguration import android.net.wifi.SoftApConfiguration
import android.net.wifi.WifiManager import android.net.wifi.WifiManager
import android.os.Build import android.os.Build
@@ -43,8 +42,9 @@ object WifiApManager {
} }
@get:RequiresApi(30) @get:RequiresApi(30)
private val getSoftApConfiguration by lazy { WifiManager::class.java.getDeclaredMethod("getSoftApConfiguration") } private val getSoftApConfiguration by lazy { WifiManager::class.java.getDeclaredMethod("getSoftApConfiguration") }
@delegate:TargetApi(30)
@get:RequiresApi(30) @get:RequiresApi(30)
private val setSoftApConfiguration by lazy @TargetApi(30) { private val setSoftApConfiguration by lazy {
WifiManager::class.java.getDeclaredMethod("setSoftApConfiguration", SoftApConfiguration::class.java) WifiManager::class.java.getDeclaredMethod("setSoftApConfiguration", SoftApConfiguration::class.java)
} }

View File

@@ -13,8 +13,9 @@ value class WifiClient(val inner: Parcelable) {
companion object { companion object {
private val clazz by lazy { Class.forName("android.net.wifi.WifiClient") } private val clazz by lazy { Class.forName("android.net.wifi.WifiClient") }
private val getMacAddress by lazy { clazz.getDeclaredMethod("getMacAddress") } private val getMacAddress by lazy { clazz.getDeclaredMethod("getMacAddress") }
@delegate:TargetApi(31)
@get:RequiresApi(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 val macAddress get() = getMacAddress(inner) as MacAddress

View File

@@ -95,10 +95,10 @@ object WifiP2pManagerHelper {
return result.future.await() return result.future.await()
} }
private val interfacePersistentGroupInfoListener by lazy @SuppressLint("PrivateApi") { private val interfacePersistentGroupInfoListener by lazy {
Class.forName("android.net.wifi.p2p.WifiP2pManager\$PersistentGroupInfoListener") 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") Class.forName("android.net.wifi.p2p.WifiP2pGroupList").getDeclaredMethod("getGroupList")
} }
private val requestPersistentGroupInfo by lazy { 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. * 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 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<WifiP2pGroup> { suspend fun WifiP2pManager.requestPersistentGroupInfo(c: WifiP2pManager.Channel): Collection<WifiP2pGroup> {
val result = CompletableDeferred<Collection<WifiP2pGroup>>() val result = CompletableDeferred<Collection<WifiP2pGroup>>()

View File

@@ -102,8 +102,8 @@ class ProcessListener(private val terminateRegex: Regex,
try { try {
launch(parent) { launch(parent) {
try { try {
process.inputStream.bufferedReader().useLines { process.inputStream.bufferedReader().useLines { lines ->
for (line in it) { for (line in lines) {
trySend(ProcessData.StdoutLine(line)).onClosed { return@useLines }.onFailure { throw it!! } trySend(ProcessData.StdoutLine(line)).onClosed { return@useLines }.onFailure { throw it!! }
if (terminateRegex.containsMatchIn(line)) process.destroy() if (terminateRegex.containsMatchIn(line)) process.destroy()
} }
@@ -112,8 +112,8 @@ class ProcessListener(private val terminateRegex: Regex,
} }
launch(parent) { launch(parent) {
try { try {
process.errorStream.bufferedReader().useLines { process.errorStream.bufferedReader().useLines { lines ->
for (line in it) trySend(ProcessData.StdoutLine(line)).onClosed { for (line in lines) trySend(ProcessData.StdoutLine(line)).onClosed {
return@useLines return@useLines
}.onFailure { throw it!! } }.onFailure { throw it!! }
} }

View File

@@ -1,5 +1,6 @@
package be.mygod.vpnhotspot.root package be.mygod.vpnhotspot.root
import android.annotation.SuppressLint
import android.os.Parcelable import android.os.Parcelable
import android.util.Log import android.util.Log
import be.mygod.librootkotlinx.* import be.mygod.librootkotlinx.*
@@ -13,6 +14,7 @@ object RootManager : RootSession(), Logger {
class RootInit : RootCommandNoResult { class RootInit : RootCommandNoResult {
override suspend fun execute(): Parcelable? { override suspend fun execute(): Parcelable? {
Timber.plant(object : Timber.DebugTree() { Timber.plant(object : Timber.DebugTree() {
@SuppressLint("LogNotTimber")
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
if (priority >= Log.WARN) { if (priority >= Log.WARN) {
System.err.println("$priority/$tag: $message") System.err.println("$priority/$tag: $message")

View File

@@ -1,7 +1,6 @@
package be.mygod.vpnhotspot.root package be.mygod.vpnhotspot.root
import android.os.Parcelable import android.os.Parcelable
import android.util.Log
import be.mygod.librootkotlinx.RootCommand import be.mygod.librootkotlinx.RootCommand
import be.mygod.librootkotlinx.RootCommandOneWay import be.mygod.librootkotlinx.RootCommandOneWay
import be.mygod.vpnhotspot.net.Routing import be.mygod.vpnhotspot.net.Routing
@@ -10,6 +9,7 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import timber.log.Timber
object RoutingCommands { object RoutingCommands {
@Parcelize @Parcelize
@@ -20,7 +20,7 @@ object RoutingCommands {
process.outputStream.bufferedWriter().use(Routing.Companion::appendCleanCommands) process.outputStream.bufferedWriter().use(Routing.Companion::appendCleanCommands)
when (val code = process.waitFor()) { when (val code = process.waitFor()) {
0 -> { } 0 -> { }
else -> Log.d("RoutingCommands.Clean", "Unexpected exit code $code") else -> Timber.w("Unexpected exit code $code")
} }
check(process.waitFor() == 0) check(process.waitFor() == 0)
} }

View File

@@ -1,6 +1,5 @@
package be.mygod.vpnhotspot.root package be.mygod.vpnhotspot.root
import android.net.MacAddress
import android.os.Parcelable import android.os.Parcelable
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import be.mygod.librootkotlinx.ParcelableBoolean import be.mygod.librootkotlinx.ParcelableBoolean
@@ -58,7 +57,7 @@ object WifiApCommands {
@Parcelize @Parcelize
@RequiresApi(28) @RequiresApi(28)
class RegisterSoftApCallback : RootCommandChannel<SoftApCallbackParcel> { class RegisterSoftApCallback : RootCommandChannel<SoftApCallbackParcel> {
override fun create(scope: CoroutineScope) = scope.produce<SoftApCallbackParcel>(capacity = capacity) { override fun create(scope: CoroutineScope) = scope.produce(capacity = capacity) {
val finish = CompletableDeferred<Unit>() val finish = CompletableDeferred<Unit>()
val key = WifiApManager.registerSoftApCallback(object : WifiApManager.SoftApCallbackCompat { val key = WifiApManager.registerSoftApCallback(object : WifiApManager.SoftApCallbackCompat {
private fun push(parcel: SoftApCallbackParcel) { private fun push(parcel: SoftApCallbackParcel) {

View File

@@ -1,15 +1,12 @@
package be.mygod.vpnhotspot.util package be.mygod.vpnhotspot.util
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.wifi.WifiManager import android.net.wifi.WifiManager
import android.net.wifi.p2p.WifiP2pManager import android.net.wifi.p2p.WifiP2pManager
import android.util.Log
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import timber.log.Timber import timber.log.Timber
@SuppressLint("LogNotTimber")
object Services { object Services {
private lateinit var contextInit: () -> Context private lateinit var contextInit: () -> Context
val context by lazy { contextInit() } val context by lazy { contextInit() }
@@ -22,7 +19,7 @@ object Services {
try { try {
context.getSystemService<WifiP2pManager>() context.getSystemService<WifiP2pManager>()
} catch (e: RuntimeException) { } catch (e: RuntimeException) {
if (android.os.Process.myUid() == 0) Log.w("WifiP2pManager", e) else Timber.w(e) Timber.w(e)
null null
} }
} }

View File

@@ -90,7 +90,6 @@ private val formatSequence = "%([0-9]+\\$|<?)([^a-zA-z%]*)([[a-zA-Z%]&&[^tT]]|[t
* *
* @param locale * @param locale
* the locale to apply; `null` value means no localization. * the locale to apply; `null` value means no localization.
* @param format the format string (see [java.util.Formatter.format])
* @param args * @param args
* the list of arguments passed to the formatter. * the list of arguments passed to the formatter.
* @return the formatted string (with spans). * @return the formatted string (with spans).
@@ -160,7 +159,8 @@ fun NetworkInterface.formatAddresses(macOnly: Boolean = false) = SpannableString
} }
}.trimEnd() }.trimEnd()
private val parseNumericAddress by lazy @SuppressLint("SoonBlockedPrivateApi") { @delegate:SuppressLint("SoonBlockedPrivateApi")
private val parseNumericAddress by lazy {
InetAddress::class.java.getDeclaredMethod("parseNumericAddress", String::class.java).apply { InetAddress::class.java.getDeclaredMethod("parseNumericAddress", String::class.java).apply {
isAccessible = true isAccessible = true
} }
@@ -201,8 +201,9 @@ fun Resources.findIdentifier(name: String, defType: String, defPackage: String,
if (alternativePackage != null && it == 0) getIdentifier(name, defType, alternativePackage) else it if (alternativePackage != null && it == 0) getIdentifier(name, defType, alternativePackage) else it
} }
@delegate:TargetApi(26)
@get:RequiresApi(26) @get:RequiresApi(26)
private val newLookup by lazy @TargetApi(26) { private val newLookup by lazy {
MethodHandles.Lookup::class.java.getDeclaredConstructor(Class::class.java, Int::class.java).apply { MethodHandles.Lookup::class.java.getDeclaredConstructor(Class::class.java, Int::class.java).apply {
isAccessible = true isAccessible = true
} }