diff --git a/build.gradle.kts b/build.gradle.kts index fb98df06ca..150fbfdcb4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("com.github.ben-manes.versions") version "0.51.0" - id("com.google.devtools.ksp") version "2.0.10-1.0.24" apply false + id("com.google.devtools.ksp") version "2.0.20-1.0.24" apply false } buildscript { @@ -21,8 +21,8 @@ buildscript { classpath("com.google.android.gms:oss-licenses-plugin:0.10.6") classpath("com.google.firebase:firebase-crashlytics-gradle:3.0.2") classpath("com.google.gms:google-services:4.4.2") - classpath("com.vanniktech:gradle-maven-publish-plugin:0.24.0") - classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.7.20") + classpath("com.vanniktech:gradle-maven-publish-plugin:0.29.0") + classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.9.20") classpath("org.mozilla.rust-android-gradle:plugin:0.9.4") } } @@ -31,10 +31,6 @@ allprojects { apply(from = "${rootProject.projectDir}/repositories.gradle.kts") } -tasks.register("clean") { - delete(rootProject.layout.buildDirectory) -} - // skip uploading the mapping to Crashlytics subprojects { tasks.whenTaskAdded { diff --git a/buildSrc/src/main/kotlin/Helpers.kt b/buildSrc/src/main/kotlin/Helpers.kt index 0e4b80318d..434792fd66 100644 --- a/buildSrc/src/main/kotlin/Helpers.kt +++ b/buildSrc/src/main/kotlin/Helpers.kt @@ -1,24 +1,21 @@ -import com.android.build.VariantOutput import com.android.build.api.dsl.CommonExtension -import com.android.build.gradle.AbstractAppExtension import com.android.build.gradle.BaseExtension -import com.android.build.gradle.internal.api.ApkVariantOutputImpl import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.api.plugins.ExtensionAware import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.getByName import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions -import java.util.* +import java.util.Locale -const val lifecycleVersion = "2.5.1" +const val lifecycleVersion = "2.8.4" private val Project.android get() = extensions.getByName("android") private val BaseExtension.lint get() = (this as CommonExtension<*, *, *, *, *, *>).lint private val flavorRegex = "(assemble|generate)\\w*(Release|Debug)".toRegex() val Project.currentFlavor get() = gradle.startParameter.taskRequests.toString().let { task -> - flavorRegex.find(task)?.groupValues?.get(2)?.toLowerCase(Locale.ROOT) ?: "debug".also { + flavorRegex.find(task)?.groupValues?.get(2)?.lowercase(Locale.ROOT) ?: "debug".also { println("Warning: No match found for $task") } } @@ -67,11 +64,11 @@ fun Project.setupCore() { disable += "UseAppTint" } ndkVersion = "27.0.12077973" + buildFeatures.buildConfig = true } - dependencies.add("coreLibraryDesugaring", "com.android.tools:desugar_jdk_libs:2.0.4") + dependencies.add("coreLibraryDesugaring", "com.android.tools:desugar_jdk_libs:2.1.0") } -private val abiCodes = mapOf("armeabi-v7a" to 1, "arm64-v8a" to 2, "x86" to 3, "x86_64" to 4) fun Project.setupApp() { setupCore() @@ -109,12 +106,4 @@ fun Project.setupApp() { } dependencies.add("implementation", project(":core")) - - if (currentFlavor == "release") (android as AbstractAppExtension).applicationVariants.all { - for (output in outputs) { - abiCodes[(output as ApkVariantOutputImpl).getFilter(VariantOutput.ABI)]?.let { offset -> - output.versionCodeOverride = versionCode + offset - } - } - } } diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 67b888e688..580ae7bfd8 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,9 +1,9 @@ import com.android.build.gradle.internal.tasks.factory.dependsOn plugins { - id("org.mozilla.rust-android-gradle.rust-android") id("com.android.library") id("com.google.devtools.ksp") + id("org.mozilla.rust-android-gradle.rust-android") kotlin("android") id("kotlin-parcelize") } @@ -32,6 +32,8 @@ android { sourceSets.getByName("androidTest") { assets.setSrcDirs(assets.srcDirs + files("$projectDir/schemas")) } + + buildFeatures.aidl = true } cargo { @@ -84,7 +86,7 @@ tasks.register("cargoClean") { tasks.clean.dependsOn("cargoClean") dependencies { - val coroutinesVersion = "1.6.4" + val coroutinesVersion = "1.8.1" val roomVersion = "2.6.1" val workVersion = "2.9.1" @@ -97,7 +99,7 @@ dependencies { api("androidx.room:room-runtime:$roomVersion") api("androidx.work:work-multiprocess:$workVersion") api("androidx.work:work-runtime-ktx:$workVersion") - api("com.google.android.gms:play-services-oss-licenses:17.0.0") + api("com.google.android.gms:play-services-oss-licenses:17.1.0") api("com.google.code.gson:gson:2.11.0") api("com.google.firebase:firebase-analytics-ktx:22.1.0") api("com.google.firebase:firebase-crashlytics:19.0.3") diff --git a/core/src/main/java/com/github/shadowsocks/Core.kt b/core/src/main/java/com/github/shadowsocks/Core.kt index e93d114d3b..4101e807ea 100644 --- a/core/src/main/java/com/github/shadowsocks/Core.kt +++ b/core/src/main/java/com/github/shadowsocks/Core.kt @@ -20,9 +20,17 @@ package com.github.shadowsocks -import android.app.* +import android.app.ActivityManager +import android.app.Application +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent import android.app.admin.DevicePolicyManager -import android.content.* +import android.content.ClipData +import android.content.ClipDescription +import android.content.ClipboardManager +import android.content.Context +import android.content.Intent import android.content.pm.PackageInfo import android.content.pm.PackageManager import android.net.ConnectivityManager @@ -34,7 +42,6 @@ import androidx.annotation.VisibleForTesting import androidx.core.content.ContextCompat import androidx.core.content.getSystemService import androidx.core.os.persistableBundleOf -import androidx.work.Configuration import com.github.shadowsocks.acl.Acl import com.github.shadowsocks.aidl.ShadowsocksConnection import com.github.shadowsocks.core.BuildConfig @@ -47,18 +54,16 @@ import com.github.shadowsocks.utils.Action import com.github.shadowsocks.utils.DeviceStorageApp import com.github.shadowsocks.utils.DirectBoot import com.github.shadowsocks.utils.Key -import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.FirebaseApp +import com.google.firebase.crashlytics.FirebaseCrashlytics import kotlinx.coroutines.DEBUG_PROPERTY_NAME import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_ON -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch import timber.log.Timber import java.io.File import java.io.IOException import kotlin.reflect.KClass -object Core : Configuration.Provider { +object Core { lateinit var app: Application @VisibleForTesting set lateinit var configureIntent: (Context) -> PendingIntent @@ -141,14 +146,6 @@ object Core : Configuration.Provider { updateNotificationChannels() } - override val workManagerConfiguration : Configuration - get() = Configuration.Builder().apply { - setDefaultProcessName(app.packageName + ":bg") - setMinimumLoggingLevel(if (BuildConfig.DEBUG) Log.VERBOSE else Log.INFO) - setExecutor { GlobalScope.launch { it.run() } } - setTaskExecutor { GlobalScope.launch { it.run() } } - }.build() - fun updateNotificationChannels() { if (Build.VERSION.SDK_INT >= 26) @RequiresApi(26) { notification.createNotificationChannels(listOf( diff --git a/core/src/main/java/com/github/shadowsocks/acl/AclSyncer.kt b/core/src/main/java/com/github/shadowsocks/acl/AclSyncer.kt index f991358120..6ce31f3484 100644 --- a/core/src/main/java/com/github/shadowsocks/acl/AclSyncer.kt +++ b/core/src/main/java/com/github/shadowsocks/acl/AclSyncer.kt @@ -22,10 +22,22 @@ package com.github.shadowsocks.acl import android.content.Context import android.os.Build -import androidx.work.* +import android.util.Log +import androidx.work.Configuration +import androidx.work.Constraints +import androidx.work.CoroutineWorker +import androidx.work.Data +import androidx.work.ExistingWorkPolicy +import androidx.work.NetworkType +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkManager +import androidx.work.WorkerParameters import com.github.shadowsocks.Core import com.github.shadowsocks.Core.app +import com.github.shadowsocks.core.BuildConfig import com.github.shadowsocks.utils.useCancellable +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import timber.log.Timber import java.io.IOException import java.net.HttpURLConnection @@ -38,16 +50,21 @@ class AclSyncer(context: Context, workerParams: WorkerParameters) : CoroutineWor fun schedule(route: String) { if (Build.VERSION.SDK_INT >= 24 && !Core.user.isUserUnlocked) return // work does not support this + if (!WorkManager.isInitialized()) WorkManager.initialize(app, Configuration.Builder().apply { + setDefaultProcessName(app.packageName + ":bg") + setMinimumLoggingLevel(if (BuildConfig.DEBUG) Log.VERBOSE else Log.INFO) + setExecutor { GlobalScope.launch { it.run() } } + setTaskExecutor { GlobalScope.launch { it.run() } } + }.build()) WorkManager.getInstance(app).enqueueUniqueWork( - route, ExistingWorkPolicy.REPLACE, OneTimeWorkRequestBuilder().run { + route, ExistingWorkPolicy.REPLACE, OneTimeWorkRequestBuilder().apply { setInputData(Data.Builder().putString(KEY_ROUTE, route).build()) - setConstraints(Constraints.Builder() - .setRequiredNetworkType(NetworkType.UNMETERED) - .setRequiresCharging(true) - .build()) + setConstraints(Constraints.Builder().apply { + setRequiredNetworkType(NetworkType.UNMETERED) + setRequiresCharging(true) + }.build()) setInitialDelay(10, TimeUnit.SECONDS) - build() - }) + }.build()) } } diff --git a/core/src/main/java/com/github/shadowsocks/bg/VpnService.kt b/core/src/main/java/com/github/shadowsocks/bg/VpnService.kt index 098b88ec8d..5c3637b4fa 100644 --- a/core/src/main/java/com/github/shadowsocks/bg/VpnService.kt +++ b/core/src/main/java/com/github/shadowsocks/bg/VpnService.kt @@ -20,6 +20,7 @@ package com.github.shadowsocks.bg +import android.annotation.SuppressLint import android.app.Service import android.content.Intent import android.content.pm.PackageManager @@ -79,16 +80,9 @@ class VpnService : BaseVpnService(), BaseService.Interface { network.bindSocket(fd) return@let true } catch (e: IOException) { - if (Build.VERSION.SDK_INT >= 31) { - when ((e.cause as? ErrnoException)?.errno) { - OsConstants.EPERM, OsConstants.EACCES, OsConstants.ENONET -> Timber.d(e) - else -> Timber.w(e) - } - } else { - when ((e.cause as? ErrnoException)?.errno) { - OsConstants.EPERM, OsConstants.EACCES -> Timber.d(e) - else -> Timber.w(e) - } + when ((e.cause as? ErrnoException)?.errno) { + OsConstants.EPERM, OsConstants.EACCES, OsConstants.ENONET -> Timber.d(e) + else -> Timber.w(e) } return@let false } diff --git a/gradle.properties b/gradle.properties index 3d7286ef94..59cae693da 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,10 +9,11 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -android.useAndroidX=true +android.enableJetifier=true +android.enableR8.fullMode=true +android.enableResourceOptimizations=false android.nonTransitiveRClass=false -android.defaults.buildfeatures.aidl=true -android.defaults.buildfeatures.buildconfig=true +android.useAndroidX=true # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit diff --git a/mobile/src/main/java/com/github/shadowsocks/App.kt b/mobile/src/main/java/com/github/shadowsocks/App.kt index 97c6467d1d..13c58c9182 100644 --- a/mobile/src/main/java/com/github/shadowsocks/App.kt +++ b/mobile/src/main/java/com/github/shadowsocks/App.kt @@ -24,7 +24,7 @@ import android.app.Application import android.content.res.Configuration import androidx.appcompat.app.AppCompatDelegate -class App : Application(), androidx.work.Configuration.Provider by Core { +class App : Application() { override fun onCreate() { super.onCreate() Core.init(this, MainActivity::class) diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index f526294601..c53d55ede1 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -14,7 +14,7 @@ android { dependencies { api(kotlin("stdlib-jdk8")) - api("androidx.core:core-ktx:1.13.1") - api("androidx.fragment:fragment-ktx:1.8.2") - api("com.google.android.material:material:1.12.0") + api("androidx.core:core-ktx:1.7.0") + api("androidx.fragment:fragment-ktx:1.5.5") + api("com.google.android.material:material:1.6.0") } diff --git a/repositories.gradle.kts b/repositories.gradle.kts index f51fd97568..aeaeb4a4bb 100644 --- a/repositories.gradle.kts +++ b/repositories.gradle.kts @@ -1,6 +1,6 @@ rootProject.extra.apply { set("androidPlugin", "com.android.tools.build:gradle:8.5.2") - set("kotlinVersion", "2.0.10") + set("kotlinVersion", "2.0.20") } repositories { diff --git a/tv/src/main/java/com/github/shadowsocks/tv/App.kt b/tv/src/main/java/com/github/shadowsocks/tv/App.kt index 79180e6139..10d42e8fcc 100644 --- a/tv/src/main/java/com/github/shadowsocks/tv/App.kt +++ b/tv/src/main/java/com/github/shadowsocks/tv/App.kt @@ -24,7 +24,7 @@ import android.app.Application import android.content.res.Configuration import com.github.shadowsocks.Core -class App : Application(), androidx.work.Configuration.Provider by Core { +class App : Application() { override fun onCreate() { super.onCreate() Core.init(this, MainActivity::class)