diff --git a/Android.bp b/Android.bp index a0560a42b..da3c65f26 100644 --- a/Android.bp +++ b/Android.bp @@ -43,8 +43,6 @@ android_app { "com.celzero.bravedns_whitelist", ], - jni_libs: ["libgojni"], - static_libs: [ "androidx.activity_activity-ktx", "androidx.appcompat_appcompat", @@ -61,6 +59,8 @@ android_app { "koin-core", "krate", ], + + use_embedded_native_libs: true } android_library_import { @@ -84,32 +84,6 @@ android_library_import { aars: ["app/libs/krate*.aar"], } -cc_prebuilt_library_shared { - name: "libgojni", - - target: { - android_arm64: { - srcs: ["app/libs/jni/arm64-v8a/libgojni.so"], - }, - android_arm: { - srcs: ["app/libs/jni/armeabi-v7a/libgojni.so"], - }, - android_x86: { - srcs: ["app/libs/jni/x86/libgojni.so"], - }, - android_x86_64: { - srcs: ["app/libs/jni/x86_64/libgojni.so"], - }, - }, - - shared_libs: [ - "libandroid", - "liblog" - ], - - system_ext_specific: true, -} - java_import { name: "ipaddress", jars: ["app/libs/ipaddress*.jar"], diff --git a/app/build.gradle b/app/build.gradle index 55c279b2f..4976be379 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,7 +19,7 @@ try { } android { - compileSdkVersion 33 + compileSdk 33 // https://developer.android.com/studio/build/configure-app-module namespace 'com.celzero.bravedns' @@ -78,7 +78,16 @@ android { } } - flavorDimensions "releaseChannel", "releaseType" + variantFilter { variant -> + def releaseChannel = variant.getFlavors().get(0).name + def releaseType = variant.getFlavors().get(1).name + + if (releaseType == 'headless' && releaseChannel != 'fdroid') { + variant.setIgnore(true) + } + } + + flavorDimensions = ["releaseChannel", "releaseType"] productFlavors { play { dimension "releaseChannel" @@ -103,7 +112,7 @@ android { } } - tasks.whenTaskAdded { task -> + tasks.configureEach { task -> if (task.name.toLowerCase().contains('headless')) { task.dependsOn downloadBlocklists if (task.name.endsWith("BuildConfig")) { @@ -127,24 +136,24 @@ configurations { dependencies { androidTestImplementation 'androidx.test:rules:1.5.0' - def room_version = "2.5.1" - def paging_version = "3.1.1" + def room_version = "2.5.2" + def paging_version = "3.2.0" - implementation "com.google.guava:guava:31.1-jre" + implementation 'com.google.guava:guava:32.1.1-android' // https://developer.android.com/studio/write/java8-support // included to fix issues with Android 6 support, issue#563 coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3") - fullImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20" - fullImplementation 'androidx.appcompat:appcompat:1.7.0-alpha02' + fullImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0' + fullImplementation 'androidx.appcompat:appcompat:1.6.1' fullImplementation 'androidx.core:core-ktx:1.10.1' implementation 'androidx.preference:preference-ktx:1.2.0' fullImplementation 'androidx.constraintlayout:constraintlayout:2.1.4' fullImplementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - fullImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' - fullImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4' + fullImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3' + fullImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3' // For liveData implementation implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1' @@ -163,12 +172,12 @@ dependencies { // For paging - connection tracker implementation "androidx.paging:paging-runtime-ktx:$paging_version" - fullImplementation 'androidx.fragment:fragment-ktx:1.5.7' + fullImplementation 'androidx.fragment:fragment-ktx:1.6.1' implementation 'com.google.android.material:material:1.9.0' fullImplementation 'androidx.viewpager2:viewpager2:1.0.0' - fullImplementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.11' - fullImplementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:5.0.0-alpha.11' + fullImplementation 'com.squareup.okhttp3:okhttp:4.11.0' + fullImplementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:4.11.0' fullImplementation 'com.squareup.retrofit2:retrofit:2.9.0' fullImplementation 'com.squareup.retrofit2:converter-gson:2.9.0' @@ -187,11 +196,11 @@ dependencies { fullImplementation 'com.facebook.shimmer:shimmer:0.5.0' // Koin core features - download "io.insert-koin:koin-core:3.2.0" - implementation "io.insert-koin:koin-core:3.4.0" + download 'io.insert-koin:koin-core:3.2.0' + implementation 'io.insert-koin:koin-core:3.4.3' // Koin main features for Android (Scope,ViewModel ...) - download "io.insert-koin:koin-android:3.2.0" - implementation "io.insert-koin:koin-android:3.4.0" + download 'io.insert-koin:koin-android:3.2.0' + implementation 'io.insert-koin:koin-android:3.4.3' download 'hu.autsoft:krate:2.0.0' implementation 'hu.autsoft:krate:2.0.0' @@ -207,7 +216,13 @@ dependencies { // implementation project(":tun2socks") // Work manager - implementation 'androidx.work:work-runtime-ktx:2.8.1' + implementation('androidx.work:work-runtime-ktx:2.8.1') { + modules { + module("com.google.guava:listenablefuture") { + replacedBy("com.google.guava:guava", "listenablefuture is part of guava") + } + } + } // for handling IP addresses and subnets, both IPv4 and IPv6 // https://seancfoley.github.io/IPAddress/ipaddress.html @@ -218,10 +233,10 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - leakCanaryImplementation 'com.squareup.leakcanary:leakcanary-android:2.10' + leakCanaryImplementation 'com.squareup.leakcanary:leakcanary-android:2.12' - fullImplementation 'androidx.navigation:navigation-fragment-ktx:2.5.3' - fullImplementation 'androidx.navigation:navigation-ui-ktx:2.5.3' + fullImplementation 'androidx.navigation:navigation-fragment-ktx:2.6.0' + fullImplementation 'androidx.navigation:navigation-ui-ktx:2.6.0' fullImplementation 'androidx.biometric:biometric:1.1.0' @@ -239,19 +254,6 @@ dependencies { fullImplementation 'com.journeyapps:zxing-android-embedded:4.3.0' } -task downloadDependencies(type: Copy) { - from configurations.download - into "libs" -} - -task unzipJNI(type: Copy) { - dependsOn downloadDependencies - fileTree(dir: 'libs', includes: ['**/*.aar']).each { zipFile -> - from zipTree(zipFile).matching({ include 'jni/**' }) - } - into "libs" -} - // github.com/michel-kraemer/gradle-download-task/issues/131#issuecomment-464476903 task downloadBlocklists(type: Download) { // def assetsDir = new File(projectDir, 'src/main/assets' @@ -277,3 +279,9 @@ task downloadBlocklists(type: Download) { // overwrite older files as determined by last-modified, always overwrite true } + +task downloadDependencies(type: Copy) { + dependsOn downloadBlocklists + from configurations.download + into "libs" +} diff --git a/app/src/full/java/com/celzero/bravedns/NonStoreAppUpdater.kt b/app/src/full/java/com/celzero/bravedns/NonStoreAppUpdater.kt index 76c6473f6..15c8fb9e3 100644 --- a/app/src/full/java/com/celzero/bravedns/NonStoreAppUpdater.kt +++ b/app/src/full/java/com/celzero/bravedns/NonStoreAppUpdater.kt @@ -64,8 +64,8 @@ class NonStoreAppUpdater( override fun onResponse(call: Call, response: Response) { try { - val res = response.body.string() - if (res.isBlank()) { + val res = response.body?.string() + if (res?.isBlank() == true) { listener.onUpdateCheckFailed( AppUpdater.InstallSource.OTHER, isInteractive diff --git a/app/src/headless/java/com/celzero/bravedns/RethinkDnsApplication.kt b/app/src/headless/java/com/celzero/bravedns/RethinkDnsApplication.kt index f7331c434..03202303e 100644 --- a/app/src/headless/java/com/celzero/bravedns/RethinkDnsApplication.kt +++ b/app/src/headless/java/com/celzero/bravedns/RethinkDnsApplication.kt @@ -3,6 +3,7 @@ package com.celzero.bravedns import android.app.Application import android.content.pm.ApplicationInfo import com.celzero.bravedns.scheduler.ScheduleManager +import com.celzero.bravedns.service.ServiceModule import com.celzero.bravedns.util.LocalBlocklistUtil import org.koin.android.ext.android.get import org.koin.android.ext.koin.androidContext @@ -38,12 +39,10 @@ class RethinkDnsApplication : Application() { startKoin { if (DEBUG) androidLogger() androidContext(this@RethinkDnsApplication) + koin.loadModules(ServiceModule.modules) + LocalBlocklistUtil(this@RethinkDnsApplication, get()).init() koin.loadModules(AppModules) } - // copy the file from assets to local dir if not present - LocalBlocklistUtil(this).init() - // database refresh is used in both headless and main project get().scheduleDatabaseRefreshJob() - } } diff --git a/app/src/headless/java/com/celzero/bravedns/ServiceModuleProvider.kt b/app/src/headless/java/com/celzero/bravedns/ServiceModuleProvider.kt index 4ad6c99b9..8da955495 100644 --- a/app/src/headless/java/com/celzero/bravedns/ServiceModuleProvider.kt +++ b/app/src/headless/java/com/celzero/bravedns/ServiceModuleProvider.kt @@ -42,8 +42,7 @@ val AppModules: List by lazy { add(RootModule) addAll(DatabaseModule.modules) addAll(DataModule.modules) - addAll(ServiceModule.modules) - add(orbotHelperModule) add(schedulerModule) + add(orbotHelperModule) } } diff --git a/app/src/headless/java/com/celzero/bravedns/util/LocalBlocklistUtil.kt b/app/src/headless/java/com/celzero/bravedns/util/LocalBlocklistUtil.kt index e7cbdc0d7..97ef9f46f 100644 --- a/app/src/headless/java/com/celzero/bravedns/util/LocalBlocklistUtil.kt +++ b/app/src/headless/java/com/celzero/bravedns/util/LocalBlocklistUtil.kt @@ -16,55 +16,52 @@ package com.celzero.bravedns.util import android.content.Context +import com.celzero.bravedns.service.PersistentState import com.celzero.bravedns.util.Constants.Companion.ONDEVICE_BLOCKLISTS_IN_APP import com.celzero.bravedns.util.Constants.Companion.ONDEVICE_BLOCKLIST_FILE_BASIC_CONFIG import com.google.gson.JsonObject import com.google.gson.JsonParser import java.io.File import java.io.InputStreamReader -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -class LocalBlocklistUtil(val context: Context) { +class LocalBlocklistUtil(val context: Context, val persistentState: PersistentState) { fun init() { - CoroutineScope(Dispatchers.IO).launch { - val jsonObject: JsonObject = - JsonParser.parseReader( - InputStreamReader( - context.assets.open( - ONDEVICE_BLOCKLIST_FILE_BASIC_CONFIG.removePrefix(File.separator) - ) + val jsonObject: JsonObject = + JsonParser.parseReader( + InputStreamReader( + context.assets.open( + ONDEVICE_BLOCKLIST_FILE_BASIC_CONFIG.removePrefix(File.separator) ) - ) as JsonObject + ) + ) as JsonObject - val localBlocklistTimestamp = - jsonObject.get("timestamp").asString.split("/").last().toLong() + val localBlocklistTimestamp = + jsonObject.get("timestamp").asString.split("/").last().toLong() + persistentState.localBlocklistTimestamp = localBlocklistTimestamp - val assets = context.assets.list("") ?: return@launch - for (asset in assets) { - val file = - ONDEVICE_BLOCKLISTS_IN_APP.firstOrNull { - asset.contains(it.filename.removePrefix(File.separator)) - } - ?: continue - context.assets - .open(file.filename.removePrefix(File.separator)) - .copyTo( - File( - Utilities.blocklistDir( - context, - Constants.LOCAL_BLOCKLIST_DOWNLOAD_FOLDER_NAME, - localBlocklistTimestamp - ) - ?.apply { mkdirs() } - ?: return@launch, - file.filename.removePrefix(File.separator) - ) - .outputStream() - ) - } + val assets = context.assets.list("") ?: return + for (asset in assets) { + val file = + ONDEVICE_BLOCKLISTS_IN_APP.firstOrNull { + asset.contains(it.filename.removePrefix(File.separator)) + } + ?: continue + context.assets + .open(file.filename.removePrefix(File.separator)) + .copyTo( + File( + Utilities.blocklistDir( + context, + Constants.LOCAL_BLOCKLIST_DOWNLOAD_FOLDER_NAME, + localBlocklistTimestamp + ) + ?.apply { mkdirs() } + ?: return, + file.filename.removePrefix(File.separator) + ) + .outputStream() + ) } } } diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index a6b3daec9..d8ccb2560 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -1,2 +1,17 @@ - \ No newline at end of file + + 설정 + 통계 + 낮잠 자는 중… + 고도로 사용자 정의 가능한 DNS 및 방화벽 + 정보 + 네트워크 보안 위협 탐지 및 차단 + + 다음 + 넘기기 + 해제 + Rethink는 접근성 서비스를 사용하여 백그라운드 애플리케이션을 탐지하고 방화벽을 차단합니다. Rethink는 어떤 정보도 수집하거나 판매하지 않습니다. + 끝내기 + 취소 + 적용 + \ No newline at end of file diff --git a/build.gradle b/build.gradle index f31148122..833f6f46c 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.0.2' + classpath 'com.android.tools.build:gradle:8.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong