Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Target Android 14 #3165

Merged
merged 19 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ jobs:
build:
working_directory: ~/code
docker:
- image: cimg/android:2022.12.1-ndk
- image: cimg/android:2024.08.1-ndk
environment:
GRADLE_OPTS: -Dorg.gradle.workers.max=1 -Dorg.gradle.daemon=false -Dkotlin.compiler.execution.strategy="in-process"
RUST_VERSION: 1.67.0
RUST_VERSION: 1.80.0
steps:
- checkout
- run: git submodule update --init --recursive
Expand Down
17 changes: 7 additions & 10 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

plugins {
id("com.github.ben-manes.versions") version "0.45.0"
id("com.github.ben-manes.versions") version "0.51.0"
id("com.google.devtools.ksp") version "2.0.20-1.0.24" apply false
}

buildscript {
Expand All @@ -18,22 +19,18 @@ buildscript {
classpath(rootProject.extra["androidPlugin"].toString())
classpath(kotlin("gradle-plugin", kotlinVersion))
classpath("com.google.android.gms:oss-licenses-plugin:0.10.6")
classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.2")
classpath("com.google.gms:google-services:4.3.15")
classpath("com.vanniktech:gradle-maven-publish-plugin:0.24.0")
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.7.20")
classpath("org.mozilla.rust-android-gradle:plugin:0.9.3")
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.29.0")
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.9.20")
classpath("org.mozilla.rust-android-gradle:plugin:0.9.4")
}
}

allprojects {
apply(from = "${rootProject.projectDir}/repositories.gradle.kts")
}

tasks.register<Delete>("clean") {
delete(rootProject.buildDir)
}

// skip uploading the mapping to Crashlytics
subprojects {
tasks.whenTaskAdded {
Expand Down
43 changes: 15 additions & 28 deletions buildSrc/src/main/kotlin/Helpers.kt
Original file line number Diff line number Diff line change
@@ -1,39 +1,34 @@

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 org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
import java.util.Locale

const val lifecycleVersion = "2.5.1"
const val lifecycleVersion = "2.8.4"

private val Project.android get() = extensions.getByName<BaseExtension>("android")
private val BaseExtension.lint get() = (this as CommonExtension<*, *, *, *>).lint
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")
}
}

fun Project.setupCommon() {
val javaVersion = JavaVersion.VERSION_11
android.apply {
buildToolsVersion("33.0.1")
compileSdkVersion(33)
compileSdkVersion(34)
defaultConfig {
minSdk = 23
targetSdk = 33
targetSdk = 34
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
val javaVersion = JavaVersion.VERSION_11
compileOptions {
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
Expand All @@ -44,14 +39,14 @@ fun Project.setupCommon() {
informational += "MissingQuantity"
informational += "MissingTranslation"
}
(this as ExtensionAware).extensions.getByName<KotlinJvmOptions>("kotlinOptions").jvmTarget =
javaVersion.toString()
}
extensions.getByName<KotlinAndroidProjectExtension>("kotlin").compilerOptions.jvmTarget
.set(JvmTarget.fromTarget(javaVersion.toString()))

dependencies {
add("testImplementation", "junit:junit:4.13.2")
add("androidTestImplementation", "androidx.test:runner:1.5.2")
add("androidTestImplementation", "androidx.test.espresso:espresso-core:3.5.1")
add("androidTestImplementation", "androidx.test:runner:1.6.2")
add("androidTestImplementation", "androidx.test.espresso:espresso-core:3.6.1")
}
}

Expand All @@ -69,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.2")
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()

Expand Down Expand Up @@ -111,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
}
}
}
}
38 changes: 20 additions & 18 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import com.android.build.gradle.internal.tasks.factory.dependsOn

plugins {
id("com.android.library")
id("com.google.devtools.ksp")
id("org.mozilla.rust-android-gradle.rust-android")
kotlin("android")
kotlin("kapt")
id("kotlin-parcelize")
}

Expand All @@ -21,8 +21,8 @@ android {
arguments("-j${Runtime.getRuntime().availableProcessors()}")
}

kapt.arguments {
arg("room.incremental", true)
ksp {
arg("room.incremental", "true")
arg("room.schemaLocation", "$projectDir/schemas")
}
}
Expand All @@ -32,6 +32,8 @@ android {
sourceSets.getByName("androidTest") {
assets.setSrcDirs(assets.srcDirs + files("$projectDir/schemas"))
}

buildFeatures.aidl = true
}

cargo {
Expand All @@ -51,13 +53,13 @@ cargo {
exec = { spec, toolchain ->
run {
try {
Runtime.getRuntime().exec("python3 -V >/dev/null 2>&1")
Runtime.getRuntime().exec(arrayOf("python3", "-V"))
spec.environment("RUST_ANDROID_GRADLE_PYTHON_COMMAND", "python3")
project.logger.lifecycle("Python 3 detected.")
} catch (e: java.io.IOException) {
project.logger.lifecycle("No python 3 detected.")
try {
Runtime.getRuntime().exec("python -V >/dev/null 2>&1")
Runtime.getRuntime().exec(arrayOf("python", "-V"))
spec.environment("RUST_ANDROID_GRADLE_PYTHON_COMMAND", "python")
project.logger.lifecycle("Python detected.")
} catch (e: java.io.IOException) {
Expand All @@ -84,28 +86,28 @@ tasks.register<Exec>("cargoClean") {
tasks.clean.dependsOn("cargoClean")

dependencies {
val coroutinesVersion = "1.6.4"
val roomVersion = "2.5.0"
val workVersion = "2.7.1"
val coroutinesVersion = "1.8.1"
val roomVersion = "2.6.1"
val workVersion = "2.9.1"

api(project(":plugin"))
api("androidx.core:core-ktx:1.9.0")
api("com.google.android.material:material:1.8.0")
api("androidx.core:core-ktx:1.13.1")
api("com.google.android.material:material:1.12.0")

api("androidx.lifecycle:lifecycle-livedata-core-ktx:$lifecycleVersion")
api("androidx.preference:preference:1.2.0")
api("androidx.preference:preference:1.2.1")
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.code.gson:gson:2.10.1")
api("com.google.firebase:firebase-analytics-ktx:21.2.0")
api("com.google.firebase:firebase-crashlytics:18.3.3")
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")
api("com.jakewharton.timber:timber:5.0.1")
api("dnsjava:dnsjava:3.5.2")
api("dnsjava:dnsjava:3.6.1")
api("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")
api("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutinesVersion")
kapt("androidx.room:room-compiler:$roomVersion")
ksp("androidx.room:room-compiler:$roomVersion")
androidTestImplementation("androidx.room:room-testing:$roomVersion")
androidTestImplementation("androidx.test.ext:junit-ktx:1.1.5")
androidTestImplementation("androidx.test.ext:junit-ktx:1.2.1")
}
5 changes: 5 additions & 0 deletions core/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
-keepattributes SourceFile,LineNumberTable
-dontobfuscate

-dontwarn lombok.Generated
-dontwarn org.slf4j.impl.StaticLoggerBinder
-dontwarn org.xbill.DNS.spi.DnsjavaInetAddressResolverProvider
-dontwarn sun.net.spi.nameservice.NameServiceDescriptor

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
15 changes: 13 additions & 2 deletions core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Expand All @@ -27,7 +29,6 @@
android:fullBackupOnly="true"
android:hasFragileUserData="true"
android:label="@string/app_name"
android:localeConfig="@xml/locales_config"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:banner="@mipmap/banner">
Expand All @@ -43,7 +44,9 @@
android:directBootAware="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_VPN_SERVICE"
android:exported="false">
android:foregroundServiceType="systemExempted"
android:exported="false"
tools:ignore="ForegroundServicePermission">
<intent-filter>
<action android:name="android.net.VpnService"/>
</intent-filter>
Expand All @@ -53,14 +56,22 @@
android:name="com.github.shadowsocks.bg.TransproxyService"
android:process=":bg"
android:directBootAware="true"
android:foregroundServiceType="specialUse"
android:exported="false">
<property
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="Proxy service that handles incoming SOCKS5 and Transproxy traffic" />
</service>

<service
android:name="com.github.shadowsocks.bg.ProxyService"
android:process=":bg"
android:directBootAware="true"
android:foregroundServiceType="specialUse"
android:exported="false">
<property
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="Proxy service that handles incoming SOCKS5 traffic" />
</service>

<service
Expand Down
29 changes: 13 additions & 16 deletions core/src/main/java/com/github/shadowsocks/Core.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -47,19 +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.FirebaseApp
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.ktx.Firebase
import com.google.firebase.ktx.initialize
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
Expand Down Expand Up @@ -111,7 +115,7 @@ object Core : Configuration.Provider {

// overhead of debug mode is minimal: https://github.com/Kotlin/kotlinx.coroutines/blob/f528898/docs/debugging.md#debug-mode
System.setProperty(DEBUG_PROPERTY_NAME, DEBUG_PROPERTY_VALUE_ON)
Firebase.initialize(deviceStorage) // multiple processes needs manual set-up
FirebaseApp.initializeApp(deviceStorage) // multiple processes needs manual set-up
Timber.plant(object : Timber.DebugTree() {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
if (t == null) {
Expand Down Expand Up @@ -142,13 +146,6 @@ object Core : Configuration.Provider {
updateNotificationChannels()
}

override fun getWorkManagerConfiguration() = 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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class UrlImportActivity : AppCompatActivity() {
}

override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
requireActivity().finish()
}
}
Expand Down
Loading