Fix new api usage
This commit is contained in:
@@ -161,6 +161,10 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lint {
|
||||||
|
fatal += "NewApi"
|
||||||
|
}
|
||||||
|
|
||||||
applicationVariants.configureEach {
|
applicationVariants.configureEach {
|
||||||
outputs.configureEach {
|
outputs.configureEach {
|
||||||
val output = this as com.android.build.gradle.internal.api.BaseVariantOutputImpl
|
val output = this as com.android.build.gradle.internal.api.BaseVariantOutputImpl
|
||||||
@@ -314,6 +318,9 @@ dependencies {
|
|||||||
// Debug/Test dependencies
|
// Debug/Test dependencies
|
||||||
debugImplementation("androidx.compose.ui:ui-tooling")
|
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||||
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
||||||
|
"androidTestPlayImplementation"(composeBom23)
|
||||||
|
"androidTestOtherImplementation"(composeBom23)
|
||||||
|
"androidTestOtherLegacyImplementation"(composeBom21)
|
||||||
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||||
|
|
||||||
// Common Compose-related libraries
|
// Common Compose-related libraries
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<lint>
|
||||||
|
<!--
|
||||||
|
Xposed/LSPosed code runs inside processes injected by the Xposed framework
|
||||||
|
(LSPosed requires Android 8.1+), not in the sfa app main process. Lint's
|
||||||
|
NewApi check based on the app's minSdk does not apply here.
|
||||||
|
-->
|
||||||
|
<issue id="NewApi">
|
||||||
|
<ignore path="src/main/java/io/nekohasekai/sfa/xposed" />
|
||||||
|
<ignore path="src/main/java/io/github/libxposed/service" />
|
||||||
|
</issue>
|
||||||
|
</lint>
|
||||||
@@ -4,6 +4,7 @@ import android.content.ComponentName
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.content.pm.PackageInfo
|
import android.content.pm.PackageInfo
|
||||||
|
import android.os.Build
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.os.RemoteException
|
import android.os.RemoteException
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
@@ -130,7 +131,13 @@ object RootClient {
|
|||||||
val list = slice.list as List<PackageInfo>
|
val list = slice.list as List<PackageInfo>
|
||||||
list
|
list
|
||||||
} catch (e: RemoteException) {
|
} catch (e: RemoteException) {
|
||||||
throw e.rethrowFromSystemServer()
|
throw e.rethrowAsRuntime()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun RemoteException.rethrowAsRuntime(): RuntimeException = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
rethrowFromSystemServer()
|
||||||
|
} else {
|
||||||
|
RuntimeException(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.core.os.LocaleListCompat
|
import androidx.core.os.LocaleListCompat
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.compose.LifecycleEventEffect
|
import androidx.lifecycle.compose.LifecycleEventEffect
|
||||||
@@ -195,7 +196,7 @@ fun AppSettingsScreen(navController: NavController) {
|
|||||||
val channel = Application.notification.getNotificationChannel("service")
|
val channel = Application.notification.getNotificationChannel("service")
|
||||||
notificationEnabled = channel?.importance != NotificationManager.IMPORTANCE_NONE
|
notificationEnabled = channel?.importance != NotificationManager.IMPORTANCE_NONE
|
||||||
} else {
|
} else {
|
||||||
notificationEnabled = Application.notification.areNotificationsEnabled()
|
notificationEnabled = NotificationManagerCompat.from(context).areNotificationsEnabled()
|
||||||
}
|
}
|
||||||
if (silentInstallEnabled) {
|
if (silentInstallEnabled) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.nekohasekai.sfa.qrs
|
package io.nekohasekai.sfa.qrs
|
||||||
|
|
||||||
|
import android.util.Base64
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.util.Base64
|
|
||||||
import java.util.zip.Inflater
|
import java.util.zip.Inflater
|
||||||
|
|
||||||
class QRSDecoder {
|
class QRSDecoder {
|
||||||
@@ -44,7 +44,7 @@ class QRSDecoder {
|
|||||||
@Synchronized
|
@Synchronized
|
||||||
fun processFrame(base64Content: String): DecodeProgress? {
|
fun processFrame(base64Content: String): DecodeProgress? {
|
||||||
val payload = try {
|
val payload = try {
|
||||||
Base64.getDecoder().decode(base64Content)
|
Base64.decode(base64Content, Base64.NO_WRAP)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.nekohasekai.sfa.qrs
|
package io.nekohasekai.sfa.qrs
|
||||||
|
|
||||||
|
import android.util.Base64
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.util.Base64
|
|
||||||
import java.util.zip.Deflater
|
import java.util.zip.Deflater
|
||||||
|
|
||||||
class QRSEncoder(private val sliceSize: Int = QRSConstants.DEFAULT_SLICE_SIZE) {
|
class QRSEncoder(private val sliceSize: Int = QRSConstants.DEFAULT_SLICE_SIZE) {
|
||||||
@@ -57,7 +57,7 @@ class QRSEncoder(private val sliceSize: Int = QRSConstants.DEFAULT_SLICE_SIZE) {
|
|||||||
|
|
||||||
return codec.encode(data, compressed, compressed.size).mapIndexed { index, block ->
|
return codec.encode(data, compressed, compressed.size).mapIndexed { index, block ->
|
||||||
val payload = buildPayload(block)
|
val payload = buildPayload(block)
|
||||||
val base64 = Base64.getEncoder().encodeToString(payload)
|
val base64 = Base64.encodeToString(payload, Base64.NO_WRAP)
|
||||||
QRSFrame("$urlPrefix$base64", index, block.totalBlocks)
|
QRSFrame("$urlPrefix$base64", index, block.totalBlocks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package io.nekohasekai.sfa.utils
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
|
import android.net.LinkProperties
|
||||||
import android.net.Network
|
import android.net.Network
|
||||||
import android.net.NetworkCapabilities
|
import android.net.NetworkCapabilities
|
||||||
|
import android.os.Build
|
||||||
import java.net.NetworkInterface
|
import java.net.NetworkInterface
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
|
|
||||||
@@ -67,7 +69,7 @@ object VpnDetectionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check activeLinkProperties interface
|
// Check activeLinkProperties interface
|
||||||
val activeLinkProperties = runCatching { cm.getLinkProperties(cm.activeNetwork) }.getOrNull()
|
val activeLinkProperties = readActiveLinkProperties(cm)
|
||||||
if (isVpnInterface(activeLinkProperties?.interfaceName)) {
|
if (isVpnInterface(activeLinkProperties?.interfaceName)) {
|
||||||
activeLinkProperties?.interfaceName?.let(frameworkInterfaces::add)
|
activeLinkProperties?.interfaceName?.let(frameworkInterfaces::add)
|
||||||
frameworkDetected += "LinkProperties"
|
frameworkDetected += "LinkProperties"
|
||||||
@@ -117,7 +119,7 @@ object VpnDetectionTest {
|
|||||||
} catch (_: Throwable) {
|
} catch (_: Throwable) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
val activeLinkProperties = runCatching { cm.getLinkProperties(cm.activeNetwork) }.getOrNull()
|
val activeLinkProperties = readActiveLinkProperties(cm)
|
||||||
val networks = cm.allNetworks ?: emptyArray()
|
val networks = cm.allNetworks ?: emptyArray()
|
||||||
val proxies = buildList {
|
val proxies = buildList {
|
||||||
add(formatProxyInfo(defaultProxy))
|
add(formatProxyInfo(defaultProxy))
|
||||||
@@ -129,7 +131,12 @@ object VpnDetectionTest {
|
|||||||
return proxies.firstOrNull { !it.isNullOrEmpty() }
|
return proxies.firstOrNull { !it.isNullOrEmpty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readProxyFromLinkProperties(lp: android.net.LinkProperties?): android.net.ProxyInfo? {
|
private fun readActiveLinkProperties(cm: ConnectivityManager): LinkProperties? {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return null
|
||||||
|
return runCatching { cm.getLinkProperties(cm.activeNetwork) }.getOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readProxyFromLinkProperties(lp: LinkProperties?): android.net.ProxyInfo? {
|
||||||
if (lp == null) return null
|
if (lp == null) return null
|
||||||
return try {
|
return try {
|
||||||
val method = lp.javaClass.getMethod("getHttpProxy")
|
val method = lp.javaClass.getMethod("getHttpProxy")
|
||||||
|
|||||||
Reference in New Issue
Block a user