From e8e00108e6f465687b2616bdfb99770d21856bd0 Mon Sep 17 00:00:00 2001 From: 5ec1cff <56485584+5ec1cff@users.noreply.github.com> Date: Tue, 21 Jan 2025 21:35:45 +0800 Subject: [PATCH] Update app (#428) --- .github/workflows/build-debug.yaml | 4 +- .github/workflows/build-pre-release.yaml | 4 +- .github/workflows/build-release.yaml | 4 +- .github/workflows/update-dependencies.yaml | 4 +- app/src/main/AndroidManifest.xml | 11 +++-- .../kr328/clash/AccessControlActivity.kt | 5 +- .../com/github/kr328/clash/BaseActivity.kt | 1 + .../kr328/clash/ExternalControlActivity.kt | 1 + .../com/github/kr328/clash/LogcatActivity.kt | 1 + .../com/github/kr328/clash/LogcatService.kt | 13 +++--- .../com/github/kr328/clash/MainActivity.kt | 24 ++++++++++ .../clash/MetaFeatureSettingsActivity.kt | 1 + .../github/kr328/clash/NewProfileActivity.kt | 1 + .../github/kr328/clash/ProfilesActivity.kt | 2 +- .../github/kr328/clash/PropertiesActivity.kt | 6 ++- .../github/kr328/clash/ProvidersActivity.kt | 1 + .../com/github/kr328/clash/TileService.kt | 4 +- .../github/kr328/clash/remote/Broadcasts.kt | 3 +- .../com/github/kr328/clash/util/Activity.kt | 6 +-- build.gradle.kts | 17 +++++-- common/src/main/AndroidManifest.xml | 3 +- .../kr328/clash/common/compat/Context.kt | 22 ++++++++- .../kr328/clash/common/compat/Services.kt | 13 +++++- core/.gitignore | 1 + core/build.gradle.kts | 17 +++++-- core/src/main/AndroidManifest.xml | 3 +- .../github/kr328/clash/core/bridge/Bridge.kt | 2 +- design/src/main/AndroidManifest.xml | 2 +- .../github/kr328/clash/design/MainDesign.kt | 2 +- .../github/kr328/clash/design/ProxyDesign.kt | 2 +- .../clash/design/adapter/PopupListAdapter.kt | 6 +-- .../clash/design/component/ProxyViewConfig.kt | 8 ++-- .../com/github/kr328/clash/design/util/App.kt | 4 +- .../github/kr328/clash/design/util/Inserts.kt | 2 +- .../clash/design/view/AppRecyclerView.kt | 10 +--- .../clash/design/view/LargeActionCard.kt | 2 +- design/src/main/res/values-vi/strings.xml | 4 +- gradle/libs.versions.toml | 43 +++++++++++++++++ gradle/wrapper/gradle-wrapper.properties | 6 +-- hideapi/src/main/AndroidManifest.xml | 2 +- service/build.gradle.kts | 2 +- service/src/main/AndroidManifest.xml | 21 +++++++-- .../kr328/clash/service/ProfileWorker.kt | 3 +- .../clash/module/AppListCacheModule.kt | 7 +-- .../clash/service/clash/module/Module.kt | 5 +- .../clash/module/StaticNotificationModule.kt | 5 +- settings.gradle.kts | 46 ------------------- 47 files changed, 224 insertions(+), 132 deletions(-) create mode 100644 core/.gitignore create mode 100644 gradle/libs.versions.toml diff --git a/.github/workflows/build-debug.yaml b/.github/workflows/build-debug.yaml index da1ebc5c..0474715b 100644 --- a/.github/workflows/build-debug.yaml +++ b/.github/workflows/build-debug.yaml @@ -20,8 +20,8 @@ jobs: - name: Setup Java uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 diff --git a/.github/workflows/build-pre-release.yaml b/.github/workflows/build-pre-release.yaml index 8e8c8886..e0e04cf6 100644 --- a/.github/workflows/build-pre-release.yaml +++ b/.github/workflows/build-pre-release.yaml @@ -19,8 +19,8 @@ jobs: - name: Setup Java uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 diff --git a/.github/workflows/build-release.yaml b/.github/workflows/build-release.yaml index 16c98a45..04ccd5fd 100644 --- a/.github/workflows/build-release.yaml +++ b/.github/workflows/build-release.yaml @@ -22,8 +22,8 @@ jobs: - name: Setup Java uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 diff --git a/.github/workflows/update-dependencies.yaml b/.github/workflows/update-dependencies.yaml index 476489f6..2624f5e1 100644 --- a/.github/workflows/update-dependencies.yaml +++ b/.github/workflows/update-dependencies.yaml @@ -18,8 +18,8 @@ jobs: - name: Setup Java uses: actions/setup-java@v4 with: - distribution: 'zulu' - java-version: 17 + distribution: "temurin" + java-version: 21 - name: Setup Go uses: actions/setup-go@v5 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cbb763a6..5a70cf03 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> + + + android:label="@string/clash_logcat" + android:foregroundServiceType="specialUse"> + + () { .filter { it.packageName == "android" || it.requestedPermissions?.contains(INTERNET) == true } + .filter { + it.applicationInfo != null + } .filter { systemApp || !it.isSystemApp } @@ -132,6 +135,6 @@ class AccessControlActivity : BaseActivity() { private val PackageInfo.isSystemApp: Boolean get() { - return applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0 + return applicationInfo?.flags?.and(ApplicationInfo.FLAG_SYSTEM) != 0 } } \ No newline at end of file diff --git a/app/src/main/java/com/github/kr328/clash/BaseActivity.kt b/app/src/main/java/com/github/kr328/clash/BaseActivity.kt index 402dc4c2..400dfb2b 100644 --- a/app/src/main/java/com/github/kr328/clash/BaseActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/BaseActivity.kt @@ -28,6 +28,7 @@ import java.util.* import java.util.concurrent.atomic.AtomicInteger import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine +import com.github.kr328.clash.design.R abstract class BaseActivity> : AppCompatActivity(), CoroutineScope by MainScope(), diff --git a/app/src/main/java/com/github/kr328/clash/ExternalControlActivity.kt b/app/src/main/java/com/github/kr328/clash/ExternalControlActivity.kt index d690e8ab..07645806 100644 --- a/app/src/main/java/com/github/kr328/clash/ExternalControlActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/ExternalControlActivity.kt @@ -20,6 +20,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import java.util.* +import com.github.kr328.clash.design.R class ExternalControlActivity : Activity(), CoroutineScope by MainScope() { override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app/src/main/java/com/github/kr328/clash/LogcatActivity.kt b/app/src/main/java/com/github/kr328/clash/LogcatActivity.kt index 04a24870..14ea46b9 100644 --- a/app/src/main/java/com/github/kr328/clash/LogcatActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/LogcatActivity.kt @@ -28,6 +28,7 @@ import kotlinx.coroutines.withContext import java.io.OutputStreamWriter import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine +import com.github.kr328.clash.design.R class LogcatActivity : BaseActivity() { private var conn: ServiceConnection? = null diff --git a/app/src/main/java/com/github/kr328/clash/LogcatService.kt b/app/src/main/java/com/github/kr328/clash/LogcatService.kt index da0673d3..af4c53be 100644 --- a/app/src/main/java/com/github/kr328/clash/LogcatService.kt +++ b/app/src/main/java/com/github/kr328/clash/LogcatService.kt @@ -14,6 +14,7 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import com.github.kr328.clash.common.compat.getColorCompat import com.github.kr328.clash.common.compat.pendingIntentFlags +import com.github.kr328.clash.common.compat.startForegroundCompat import com.github.kr328.clash.common.log.Log import com.github.kr328.clash.common.util.intent import com.github.kr328.clash.core.model.LogMessage @@ -130,17 +131,17 @@ class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.De NotificationChannelCompat.Builder( CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_DEFAULT - ).setName(getString(R.string.clash_logcat)).build() + ).setName(getString(com.github.kr328.clash.design.R.string.clash_logcat)).build() ) } private fun showNotification() { val notification = NotificationCompat .Builder(this, CHANNEL_ID) - .setSmallIcon(R.drawable.ic_logo_service) - .setColor(getColorCompat(R.color.color_clash_light)) - .setContentTitle(getString(R.string.clash_logcat)) - .setContentText(getString(R.string.running)) + .setSmallIcon(com.github.kr328.clash.service.R.drawable.ic_logo_service) + .setColor(getColorCompat(com.github.kr328.clash.design.R.color.color_clash_light)) + .setContentTitle(getString(com.github.kr328.clash.design.R.string.clash_logcat)) + .setContentText(getString(com.github.kr328.clash.design.R.string.running)) .setContentIntent( PendingIntent.getActivity( this, @@ -152,7 +153,7 @@ class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.De ) .build() - startForeground(R.id.nf_logcat_status, notification) + startForegroundCompat(R.id.nf_logcat_status, notification) } companion object { diff --git a/app/src/main/java/com/github/kr328/clash/MainActivity.kt b/app/src/main/java/com/github/kr328/clash/MainActivity.kt index dac30176..5e4fe134 100644 --- a/app/src/main/java/com/github/kr328/clash/MainActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/MainActivity.kt @@ -1,6 +1,13 @@ package com.github.kr328.clash +import android.content.pm.PackageManager +import android.os.Build +import android.os.Bundle +import android.os.PersistableBundle import androidx.activity.result.contract.ActivityResultContracts +import androidx.activity.result.contract.ActivityResultContracts.RequestPermission +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat import com.github.kr328.clash.common.util.intent import com.github.kr328.clash.common.util.ticker import com.github.kr328.clash.design.MainDesign @@ -15,6 +22,7 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.selects.select import kotlinx.coroutines.withContext import java.util.concurrent.TimeUnit +import com.github.kr328.clash.design.R class MainActivity : BaseActivity() { override suspend fun main() { @@ -129,4 +137,20 @@ class MainActivity : BaseActivity() { packageManager.getPackageInfo(packageName, 0).versionName + "\n" + Bridge.nativeCoreVersion().replace("_", "-") } } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + val requestPermissionLauncher = + registerForActivityResult(RequestPermission() + ) { isGranted: Boolean -> + } + if (ContextCompat.checkSelfPermission( + this, + android.Manifest.permission.POST_NOTIFICATIONS + ) != PackageManager.PERMISSION_GRANTED) { + requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/kr328/clash/MetaFeatureSettingsActivity.kt b/app/src/main/java/com/github/kr328/clash/MetaFeatureSettingsActivity.kt index 913bc07e..47f0c4c2 100644 --- a/app/src/main/java/com/github/kr328/clash/MetaFeatureSettingsActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/MetaFeatureSettingsActivity.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.selects.select import kotlinx.coroutines.withContext import java.io.File import java.io.FileOutputStream +import com.github.kr328.clash.design.R class MetaFeatureSettingsActivity : BaseActivity() { diff --git a/app/src/main/java/com/github/kr328/clash/NewProfileActivity.kt b/app/src/main/java/com/github/kr328/clash/NewProfileActivity.kt index 8df167d1..529c146f 100644 --- a/app/src/main/java/com/github/kr328/clash/NewProfileActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/NewProfileActivity.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.selects.select import kotlinx.coroutines.withContext import java.util.* +import com.github.kr328.clash.design.R class NewProfileActivity : BaseActivity() { private val self: NewProfileActivity diff --git a/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt b/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt index 75943dd2..fe570680 100644 --- a/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt @@ -9,7 +9,6 @@ import com.github.kr328.clash.common.util.setUUID import com.github.kr328.clash.common.util.ticker import com.github.kr328.clash.design.ProfilesDesign import com.github.kr328.clash.design.ui.ToastDuration -import com.github.kr328.clash.R import com.github.kr328.clash.service.model.Profile import com.github.kr328.clash.util.withProfile import kotlinx.coroutines.Dispatchers @@ -19,6 +18,7 @@ import kotlinx.coroutines.selects.select import kotlinx.coroutines.withContext import java.util.* import java.util.concurrent.TimeUnit +import com.github.kr328.clash.design.R class ProfilesActivity : BaseActivity() { override suspend fun main() { diff --git a/app/src/main/java/com/github/kr328/clash/PropertiesActivity.kt b/app/src/main/java/com/github/kr328/clash/PropertiesActivity.kt index 93e6ecce..62adc8bc 100644 --- a/app/src/main/java/com/github/kr328/clash/PropertiesActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/PropertiesActivity.kt @@ -12,9 +12,11 @@ import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.selects.select +import com.github.kr328.clash.design.R class PropertiesActivity : BaseActivity() { private var canceled: Boolean = false + private lateinit var original: Profile override suspend fun main() { setResult(RESULT_CANCELED) @@ -22,7 +24,7 @@ class PropertiesActivity : BaseActivity() { val uuid = intent.uuid ?: return finish() val design = PropertiesDesign(this) - val original = withProfile { queryByUUID(uuid) } ?: return finish() + original = withProfile { queryByUUID(uuid) } ?: return finish() design.profile = original @@ -71,7 +73,7 @@ class PropertiesActivity : BaseActivity() { design?.apply { launch { if (!progressing) { - if (requestExitWithoutSaving()) + if (original == profile || requestExitWithoutSaving()) finish() } } diff --git a/app/src/main/java/com/github/kr328/clash/ProvidersActivity.kt b/app/src/main/java/com/github/kr328/clash/ProvidersActivity.kt index 22bdbd07..991ebf87 100644 --- a/app/src/main/java/com/github/kr328/clash/ProvidersActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/ProvidersActivity.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.selects.select import java.util.concurrent.TimeUnit +import com.github.kr328.clash.design.R class ProvidersActivity : BaseActivity() { override suspend fun main() { diff --git a/app/src/main/java/com/github/kr328/clash/TileService.kt b/app/src/main/java/com/github/kr328/clash/TileService.kt index d00f2ad5..d24abbb4 100644 --- a/app/src/main/java/com/github/kr328/clash/TileService.kt +++ b/app/src/main/java/com/github/kr328/clash/TileService.kt @@ -9,11 +9,13 @@ import android.os.Build import android.service.quicksettings.Tile import android.service.quicksettings.TileService import androidx.annotation.RequiresApi +import com.github.kr328.clash.common.compat.registerReceiverCompat import com.github.kr328.clash.common.constants.Intents import com.github.kr328.clash.common.constants.Permissions import com.github.kr328.clash.remote.StatusClient import com.github.kr328.clash.util.startClashService import com.github.kr328.clash.util.stopClashService +import com.github.kr328.clash.service.R @RequiresApi(Build.VERSION_CODES.N) class TileService : TileService() { @@ -36,7 +38,7 @@ class TileService : TileService() { override fun onStartListening() { super.onStartListening() - registerReceiver( + registerReceiverCompat( receiver, IntentFilter().apply { addAction(Intents.ACTION_CLASH_STARTED) diff --git a/app/src/main/java/com/github/kr328/clash/remote/Broadcasts.kt b/app/src/main/java/com/github/kr328/clash/remote/Broadcasts.kt index 51d06927..9be7026b 100644 --- a/app/src/main/java/com/github/kr328/clash/remote/Broadcasts.kt +++ b/app/src/main/java/com/github/kr328/clash/remote/Broadcasts.kt @@ -5,6 +5,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import com.github.kr328.clash.common.compat.registerReceiverCompat import com.github.kr328.clash.common.constants.Intents import com.github.kr328.clash.common.log.Log import java.util.* @@ -88,7 +89,7 @@ class Broadcasts(private val context: Application) { return try { - context.registerReceiver(broadcastReceiver, IntentFilter().apply { + context.registerReceiverCompat(broadcastReceiver, IntentFilter().apply { addAction(Intents.ACTION_SERVICE_RECREATED) addAction(Intents.ACTION_CLASH_STARTED) addAction(Intents.ACTION_CLASH_STOPPED) diff --git a/app/src/main/java/com/github/kr328/clash/util/Activity.kt b/app/src/main/java/com/github/kr328/clash/util/Activity.kt index 61092487..ea901467 100644 --- a/app/src/main/java/com/github/kr328/clash/util/Activity.kt +++ b/app/src/main/java/com/github/kr328/clash/util/Activity.kt @@ -7,16 +7,12 @@ import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.withContext class ActivityResultLifecycle : LifecycleOwner { - private val lifecycle = LifecycleRegistry(this) + override val lifecycle = LifecycleRegistry(this) init { lifecycle.currentState = Lifecycle.State.INITIALIZED } - override fun getLifecycle(): Lifecycle { - return lifecycle - } - suspend fun use(block: suspend (lifecycle: ActivityResultLifecycle, start: () -> Unit) -> T): T { return try { markCreated() diff --git a/build.gradle.kts b/build.gradle.kts index 5400ca92..7fef7ddc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -32,13 +32,19 @@ subprojects { apply(plugin = if (isApp) "com.android.application" else "com.android.library") extensions.configure { + buildFeatures.buildConfig = true defaultConfig { if (isApp) { applicationId = "com.github.metacubex.clash" } + project.name.let { name -> + namespace = if (name == "app") "com.github.kr328.clash" + else "com.github.kr328.clash.$name" + } + minSdk = 21 - targetSdk = 31 + targetSdk = 35 versionName = "2.11.5" versionCode = 211005 @@ -59,7 +65,7 @@ subprojects { } } - ndkVersion = "23.0.7599858" + ndkVersion = "27.2.12479018" compileSdkVersion(defaultConfig.targetSdk!!) @@ -134,7 +140,7 @@ subprojects { named("release") { isMinifyEnabled = isApp isShrinkResources = isApp - signingConfig = signingConfigs.findByName("release") + signingConfig = signingConfigs.findByName("release") ?: signingConfigs["debug"] proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" @@ -161,6 +167,11 @@ subprojects { } } } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 + } } } diff --git a/common/src/main/AndroidManifest.xml b/common/src/main/AndroidManifest.xml index cda58854..63d06f46 100644 --- a/common/src/main/AndroidManifest.xml +++ b/common/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + = Build.VERSION_CODES.TIRAMISU) + registerReceiver(receiver, filter, permission, handler, + if (permission == null) Context.RECEIVER_EXPORTED else Context.RECEIVER_NOT_EXPORTED + ) + else + registerReceiver(receiver, filter, permission, handler) + diff --git a/common/src/main/java/com/github/kr328/clash/common/compat/Services.kt b/common/src/main/java/com/github/kr328/clash/common/compat/Services.kt index 5eded773..92628fc1 100644 --- a/common/src/main/java/com/github/kr328/clash/common/compat/Services.kt +++ b/common/src/main/java/com/github/kr328/clash/common/compat/Services.kt @@ -1,7 +1,10 @@ package com.github.kr328.clash.common.compat +import android.app.Notification +import android.app.Service import android.content.Context import android.content.Intent +import android.content.pm.ServiceInfo import android.os.Build fun Context.startForegroundServiceCompat(intent: Intent) { @@ -10,4 +13,12 @@ fun Context.startForegroundServiceCompat(intent: Intent) { } else { startService(intent) } -} \ No newline at end of file +} + +fun Service.startForegroundCompat(id: Int, notification: Notification) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + startForeground(id, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE) + } else { + startForeground(id, notification) + } +} diff --git a/core/.gitignore b/core/.gitignore new file mode 100644 index 00000000..c2ff5d84 --- /dev/null +++ b/core/.gitignore @@ -0,0 +1 @@ +/src/main/cpp/version.h diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 465edb57..3a0bca6c 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,8 +1,6 @@ +import android.databinding.tool.ext.capitalizeUS import com.github.kr328.golang.GolangBuildTask import com.github.kr328.golang.GolangPlugin -import java.io.FileOutputStream -import java.net.URL -import java.time.Duration plugins { kotlin("android") @@ -62,4 +60,15 @@ afterEvaluate { tasks.withType(GolangBuildTask::class.java).forEach { it.inputs.dir(golangSource) } -} \ No newline at end of file +} + +val abis = listOf("armeabi-v7a" to "ArmeabiV7a", "arm64-v8a" to "Arm64V8a", "x86_64" to "X8664", "x86" to "X86") + +androidComponents.onVariants { variant -> + afterEvaluate { + for ((abi, goAbi) in abis) { + val cmakeName = if (variant.buildType == "debug") "Debug" else "RelWithDebInfo" + tasks.getByName("buildCMake$cmakeName[$abi]").dependsOn(tasks.getByName("externalGolangBuild${variant.name.capitalizeUS()}$goAbi")) + } + } +} diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index 2584c46e..182d7298 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + diff --git a/core/src/main/java/com/github/kr328/clash/core/bridge/Bridge.kt b/core/src/main/java/com/github/kr328/clash/core/bridge/Bridge.kt index 8aa26fb4..66df597d 100644 --- a/core/src/main/java/com/github/kr328/clash/core/bridge/Bridge.kt +++ b/core/src/main/java/com/github/kr328/clash/core/bridge/Bridge.kt @@ -61,7 +61,7 @@ object Bridge { .detachFd() val home = ctx.filesDir.resolve("clash").apply { mkdirs() }.absolutePath - val versionName = ctx.packageManager.getPackageInfo(ctx.packageName, 0).versionName + val versionName = ctx.packageManager.getPackageInfo(ctx.packageName, 0).versionName ?: "unknown" val sdkVersion = Build.VERSION.SDK_INT Log.d("Home = $home") diff --git a/design/src/main/AndroidManifest.xml b/design/src/main/AndroidManifest.xml index c6fb9664..cc947c56 100644 --- a/design/src/main/AndroidManifest.xml +++ b/design/src/main/AndroidManifest.xml @@ -1 +1 @@ - + diff --git a/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt b/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt index d86e0c51..f418e488 100644 --- a/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt +++ b/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt @@ -81,7 +81,7 @@ class MainDesign(context: Context) : Design(context) { init { binding.self = this - binding.colorClashStarted = context.resolveThemedColor(R.attr.colorPrimary) + binding.colorClashStarted = context.resolveThemedColor(com.google.android.material.R.attr.colorPrimary) binding.colorClashStopped = context.resolveThemedColor(R.attr.colorClashStopped) } diff --git a/design/src/main/java/com/github/kr328/clash/design/ProxyDesign.kt b/design/src/main/java/com/github/kr328/clash/design/ProxyDesign.kt index 8f012636..7dc7f413 100644 --- a/design/src/main/java/com/github/kr328/clash/design/ProxyDesign.kt +++ b/design/src/main/java/com/github/kr328/clash/design/ProxyDesign.kt @@ -108,7 +108,7 @@ class ProxyDesign( binding.urlTestFloatView.visibility = View.GONE } else { binding.urlTestFloatView.supportImageTintList = ColorStateList.valueOf( - context.resolveThemedColor(R.attr.colorOnPrimary) + context.resolveThemedColor(com.google.android.material.R.attr.colorOnPrimary) ) binding.pagesView.apply { diff --git a/design/src/main/java/com/github/kr328/clash/design/adapter/PopupListAdapter.kt b/design/src/main/java/com/github/kr328/clash/design/adapter/PopupListAdapter.kt index 576c11cf..19d60ba9 100644 --- a/design/src/main/java/com/github/kr328/clash/design/adapter/PopupListAdapter.kt +++ b/design/src/main/java/com/github/kr328/clash/design/adapter/PopupListAdapter.kt @@ -15,9 +15,9 @@ class PopupListAdapter( private val texts: List, private val selected: Int, ) : BaseAdapter() { - private val colorPrimary = context.resolveThemedColor(R.attr.colorPrimary) - private val colorOnPrimary = context.resolveThemedColor(R.attr.colorOnPrimary) - private val colorControlNormal = context.resolveThemedColor(R.attr.colorControlNormal) + private val colorPrimary = context.resolveThemedColor(com.google.android.material.R.attr.colorPrimary) + private val colorOnPrimary = context.resolveThemedColor(com.google.android.material.R.attr.colorOnPrimary) + private val colorControlNormal = context.resolveThemedColor(com.google.android.material.R.attr.colorControlNormal) override fun getCount(): Int { return texts.size diff --git a/design/src/main/java/com/github/kr328/clash/design/component/ProxyViewConfig.kt b/design/src/main/java/com/github/kr328/clash/design/component/ProxyViewConfig.kt index 80a14ca7..0426e445 100644 --- a/design/src/main/java/com/github/kr328/clash/design/component/ProxyViewConfig.kt +++ b/design/src/main/java/com/github/kr328/clash/design/component/ProxyViewConfig.kt @@ -8,15 +8,15 @@ import com.github.kr328.clash.design.util.resolveThemedColor import com.github.kr328.clash.design.util.resolveThemedResourceId class ProxyViewConfig(val context: Context, var proxyLine: Int) { - private val colorSurface = context.resolveThemedColor(R.attr.colorSurface) + private val colorSurface = context.resolveThemedColor(com.google.android.material.R.attr.colorSurface) val clickableBackground = context.resolveThemedResourceId(android.R.attr.selectableItemBackground) - val selectedControl = context.resolveThemedColor(R.attr.colorOnPrimary) - val selectedBackground = context.resolveThemedColor(R.attr.colorPrimary) + val selectedControl = context.resolveThemedColor(com.google.android.material.R.attr.colorOnPrimary) + val selectedBackground = context.resolveThemedColor(com.google.android.material.R.attr.colorPrimary) - val unselectedControl = context.resolveThemedColor(R.attr.colorOnSurface) + val unselectedControl = context.resolveThemedColor(com.google.android.material.R.attr.colorOnSurface) val unselectedBackground: Int get() = if (proxyLine==1) Color.TRANSPARENT else colorSurface diff --git a/design/src/main/java/com/github/kr328/clash/design/util/App.kt b/design/src/main/java/com/github/kr328/clash/design/util/App.kt index 5dfeaee4..8bd37ac1 100644 --- a/design/src/main/java/com/github/kr328/clash/design/util/App.kt +++ b/design/src/main/java/com/github/kr328/clash/design/util/App.kt @@ -8,8 +8,8 @@ import com.github.kr328.clash.design.model.AppInfo fun PackageInfo.toAppInfo(pm: PackageManager): AppInfo { return AppInfo( packageName = packageName, - icon = applicationInfo.loadIcon(pm).foreground(), - label = applicationInfo.loadLabel(pm).toString(), + icon = applicationInfo!!.loadIcon(pm).foreground(), + label = applicationInfo!!.loadLabel(pm).toString(), installTime = firstInstallTime, updateDate = lastUpdateTime, ) diff --git a/design/src/main/java/com/github/kr328/clash/design/util/Inserts.kt b/design/src/main/java/com/github/kr328/clash/design/util/Inserts.kt index 65255781..f3e266fa 100644 --- a/design/src/main/java/com/github/kr328/clash/design/util/Inserts.kt +++ b/design/src/main/java/com/github/kr328/clash/design/util/Inserts.kt @@ -28,7 +28,7 @@ fun View.setOnInsertsChangedListener(adaptLandscape: Boolean = true, listener: ( listener(if (adaptLandscape) rInsets.landscape(v.context) else rInsets) - compat.toWindowInsets() + compat.toWindowInsets()!! } requestApplyInsets() diff --git a/design/src/main/java/com/github/kr328/clash/design/view/AppRecyclerView.kt b/design/src/main/java/com/github/kr328/clash/design/view/AppRecyclerView.kt index 00040ab6..e69fd234 100644 --- a/design/src/main/java/com/github/kr328/clash/design/view/AppRecyclerView.kt +++ b/design/src/main/java/com/github/kr328/clash/design/view/AppRecyclerView.kt @@ -14,12 +14,4 @@ class AppRecyclerView @JvmOverloads constructor( init { isFocusable = false } - - override fun onDraw(c: Canvas?) { - super.onDraw(c) - } - - override fun dispatchDraw(canvas: Canvas?) { - super.dispatchDraw(canvas) - } -} \ No newline at end of file +} diff --git a/design/src/main/java/com/github/kr328/clash/design/view/LargeActionCard.kt b/design/src/main/java/com/github/kr328/clash/design/view/LargeActionCard.kt index d0501f99..0b75496d 100644 --- a/design/src/main/java/com/github/kr328/clash/design/view/LargeActionCard.kt +++ b/design/src/main/java/com/github/kr328/clash/design/view/LargeActionCard.kt @@ -60,6 +60,6 @@ class LargeActionCard @JvmOverloads constructor( minimumHeight = context.getPixels(R.dimen.large_action_card_min_height) radius = context.getPixels(R.dimen.large_action_card_radius).toFloat() elevation = context.getPixels(R.dimen.large_action_card_elevation).toFloat() - setCardBackgroundColor(context.resolveThemedColor(R.attr.colorSurface)) + setCardBackgroundColor(context.resolveThemedColor(com.google.android.material.R.attr.colorSurface)) } } \ No newline at end of file diff --git a/design/src/main/res/values-vi/strings.xml b/design/src/main/res/values-vi/strings.xml index 2ff4f708..ea361405 100644 --- a/design/src/main/res/values-vi/strings.xml +++ b/design/src/main/res/values-vi/strings.xml @@ -1,8 +1,8 @@ Nhập thất bại - Cập nhật thành công - Cập nhật không thành công + Cập nhật thành công %s + Cập nhật không thành công %1$s %2$s Chạm để nhập... Tính năng của Clash Meta Cho phép Ipv6 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..5f8abde4 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,43 @@ +[versions] +agp = "8.8.0" +kotlin = "2.1.0" +ksp = "2.1.0-1.0.29" +golang = "1.0.4" +coroutine = "1.10.1" +coreKtx = "1.8.0" +activity = "1.5.0" +fragment = "1.5.0" +appcompat = "1.4.2" +coordinator = "1.2.0" +recyclerview = "1.2.1" +viewpager = "1.0.0" +material = "1.6.1" +serialization = "1.3.3" +kaidl = "1.15" +room = "2.4.2" +multiprocess = "1.0.0" + +[libraries] +build-android = { module = "com.android.tools.build:gradle", version.ref = "agp" } +build-kotlin-common = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +build-kotlin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } +build-ksp = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" } +build-golang = { module = "com.github.kr328.golang:gradle-plugin", version.ref = "golang" } +kotlin-coroutine = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutine" } +kotlin-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" } +androidx-core = { module = "androidx.core:core-ktx", version.ref = "coreKtx" } +androidx-activity = { module = "androidx.activity:activity", version.ref = "activity" } +androidx-fragment = { module = "androidx.fragment:fragment", version.ref = "fragment" } +androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" } +androidx-coordinator = { module = "androidx.coordinatorlayout:coordinatorlayout", version.ref = "coordinator" } +androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" } +androidx-viewpager = { module = "androidx.viewpager2:viewpager2", version.ref = "viewpager" } +androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } +androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } +androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } +google-material = { module = "com.google.android.material:material", version.ref = "material" } +kaidl-compiler = { module = "com.github.kr328.kaidl:kaidl", version.ref = "kaidl" } +kaidl-runtime = { module = "com.github.kr328.kaidl:kaidl-runtime", version.ref = "kaidl" } +rikkax-multiprocess = { module = "dev.rikka.rikkax.preference:multiprocess", version.ref = "multiprocess" } + +[plugins] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 50955b7f..b4eae466 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,8 +1,6 @@ +#Tue Jan 14 14:06:42 CST 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=fe696c020f241a5f69c30f763c5a7f38eec54b490db19cd2b0962dda420d7d12 -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-all.zip -networkTimeout=10000 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionSha256Sum=fe696c020f241a5f69c30f763c5a7f38eec54b490db19cd2b0962dda420d7d12 \ No newline at end of file diff --git a/hideapi/src/main/AndroidManifest.xml b/hideapi/src/main/AndroidManifest.xml index f7d0ec35..568741e5 100644 --- a/hideapi/src/main/AndroidManifest.xml +++ b/hideapi/src/main/AndroidManifest.xml @@ -1,2 +1,2 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/service/build.gradle.kts b/service/build.gradle.kts index e0ab915c..1c33c111 100644 --- a/service/build.gradle.kts +++ b/service/build.gradle.kts @@ -19,7 +19,7 @@ dependencies { implementation(libs.androidx.room.ktx) implementation(libs.kaidl.runtime) implementation(libs.rikkax.multiprocess) - implementation(platform("com.squareup.okhttp3:okhttp-bom:4.10.0")) + implementation(platform("com.squareup.okhttp3:okhttp-bom:4.12.0")) // define any required OkHttp artifacts without version implementation("com.squareup.okhttp3:okhttp") diff --git a/service/src/main/AndroidManifest.xml b/service/src/main/AndroidManifest.xml index 11beae54..167cddd5 100644 --- a/service/src/main/AndroidManifest.xml +++ b/service/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ + xmlns:tools="http://schemas.android.com/tools"> @@ -9,19 +8,27 @@ + + android:process=":background" + android:foregroundServiceType="specialUse"> + + + android:process=":background" + android:foregroundServiceType="specialUse"> + @@ -33,7 +40,11 @@ + android:process=":background" + android:foregroundServiceType="specialUse"> + + Unit) { diff --git a/service/src/main/java/com/github/kr328/clash/service/clash/module/AppListCacheModule.kt b/service/src/main/java/com/github/kr328/clash/service/clash/module/AppListCacheModule.kt index 04c96b24..f5d5b41e 100644 --- a/service/src/main/java/com/github/kr328/clash/service/clash/module/AppListCacheModule.kt +++ b/service/src/main/java/com/github/kr328/clash/service/clash/module/AppListCacheModule.kt @@ -11,10 +11,11 @@ import java.util.concurrent.TimeUnit class AppListCacheModule(service: Service) : Module(service) { private fun PackageInfo.uniqueUidName(): String = - if (sharedUserId != null && sharedUserId.isNotBlank()) sharedUserId else packageName + if (sharedUserId?.isNotBlank() == true) sharedUserId!! else packageName private fun reload() { val packages = service.packageManager.getInstalledPackages(0) + .filter { it.applicationInfo != null } .groupBy { it.uniqueUidName() } .map { (_, v) -> val info = v[0] @@ -23,9 +24,9 @@ class AppListCacheModule(service: Service) : Module(service) { // Force use package name if only one app in a single sharedUid group // Example: firefox - info.applicationInfo.uid to info.packageName + info.applicationInfo!!.uid to info.packageName } else { - info.applicationInfo.uid to info.uniqueUidName() + info.applicationInfo!!.uid to info.uniqueUidName() } } diff --git a/service/src/main/java/com/github/kr328/clash/service/clash/module/Module.kt b/service/src/main/java/com/github/kr328/clash/service/clash/module/Module.kt index 93d2c384..cb2dbead 100644 --- a/service/src/main/java/com/github/kr328/clash/service/clash/module/Module.kt +++ b/service/src/main/java/com/github/kr328/clash/service/clash/module/Module.kt @@ -5,6 +5,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import com.github.kr328.clash.common.compat.registerReceiverCompat import com.github.kr328.clash.common.constants.Permissions import com.github.kr328.clash.common.log.Log import kotlinx.coroutines.NonCancellable @@ -44,9 +45,9 @@ abstract class Module(val service: Service) { } if (requireSelf) { - service.registerReceiver(receiver, filter, Permissions.RECEIVE_SELF_BROADCASTS, null) + service.registerReceiverCompat(receiver, filter, Permissions.RECEIVE_SELF_BROADCASTS, null) } else { - service.registerReceiver(receiver, filter) + service.registerReceiverCompat(receiver, filter) } receivers.add(receiver) diff --git a/service/src/main/java/com/github/kr328/clash/service/clash/module/StaticNotificationModule.kt b/service/src/main/java/com/github/kr328/clash/service/clash/module/StaticNotificationModule.kt index 78120e89..962ba1d2 100644 --- a/service/src/main/java/com/github/kr328/clash/service/clash/module/StaticNotificationModule.kt +++ b/service/src/main/java/com/github/kr328/clash/service/clash/module/StaticNotificationModule.kt @@ -8,6 +8,7 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import com.github.kr328.clash.common.compat.getColorCompat import com.github.kr328.clash.common.compat.pendingIntentFlags +import com.github.kr328.clash.common.compat.startForegroundCompat import com.github.kr328.clash.common.constants.Components import com.github.kr328.clash.common.constants.Intents import com.github.kr328.clash.service.R @@ -47,7 +48,7 @@ class StaticNotificationModule(service: Service) : Module(service) { .setContentText(service.getText(R.string.running)) .build() - service.startForeground(R.id.nf_clash_status, notification) + service.startForegroundCompat(R.id.nf_clash_status, notification) } } @@ -74,7 +75,7 @@ class StaticNotificationModule(service: Service) : Module(service) { .setContentTitle(service.getText(R.string.loading)) .build() - service.startForeground(R.id.nf_clash_status, notification) + service.startForegroundCompat(R.id.nf_clash_status, notification) } } } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 47733250..0d6fbcc2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,49 +14,3 @@ pluginManagement { gradlePluginPortal() } } - -dependencyResolutionManagement { - versionCatalogs { - create("libs") { - val agp = "7.2.1" - val kotlin = "1.7.0" - val ksp = "$kotlin-1.0.6" - val golang = "1.0.4" - val coroutine = "1.7.3" - val coreKtx = "1.8.0" - val activity = "1.5.0" - val fragment = "1.5.0" - val appcompat = "1.4.2" - val coordinator = "1.2.0" - val recyclerview = "1.2.1" - val viewpager = "1.0.0" - val material = "1.6.1" - val serialization = "1.3.3" - val kaidl = "1.15" - val room = "2.4.2" - val multiprocess = "1.0.0" - - library("build-android", "com.android.tools.build:gradle:$agp") - library("build-kotlin-common", "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin") - library("build-kotlin-serialization", "org.jetbrains.kotlin:kotlin-serialization:$kotlin") - library("build-ksp", "com.google.devtools.ksp:symbol-processing-gradle-plugin:$ksp") - library("build-golang", "com.github.kr328.golang:gradle-plugin:$golang") - library("kotlin-coroutine", "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine") - library("kotlin-serialization-json", "org.jetbrains.kotlinx:kotlinx-serialization-json:$serialization") - library("androidx-core", "androidx.core:core-ktx:$coreKtx") - library("androidx-activity", "androidx.activity:activity:$activity") - library("androidx-fragment", "androidx.fragment:fragment:$fragment") - library("androidx-appcompat", "androidx.appcompat:appcompat:$appcompat") - library("androidx-coordinator", "androidx.coordinatorlayout:coordinatorlayout:$coordinator") - library("androidx-recyclerview", "androidx.recyclerview:recyclerview:$recyclerview") - library("androidx-viewpager", "androidx.viewpager2:viewpager2:$viewpager") - library("androidx-room-compiler", "androidx.room:room-compiler:$room") - library("androidx-room-runtime", "androidx.room:room-runtime:$room") - library("androidx-room-ktx", "androidx.room:room-ktx:$room") - library("google-material", "com.google.android.material:material:$material") - library("kaidl-compiler", "com.github.kr328.kaidl:kaidl:$kaidl") - library("kaidl-runtime", "com.github.kr328.kaidl:kaidl-runtime:$kaidl") - library("rikkax-multiprocess", "dev.rikka.rikkax.preference:multiprocess:$multiprocess") - } - } -} \ No newline at end of file