diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9f3b9c6..773d63f 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,14 +1,9 @@
-val rExtra = rootProject.extra
-
plugins {
- id("com.android.application")
- id("org.jetbrains.kotlin.android")
- kotlin("kapt")
- id("com.google.dagger.hilt.android")
- id("com.google.gms.google-services")
- id("com.google.firebase.crashlytics")
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.hilt.android)
id("org.jetbrains.kotlin.plugin.serialization")
- id("io.objectbox")
+ alias(libs.plugins.ksp)
}
android {
@@ -16,8 +11,8 @@ android {
compileSdk = 34
val versionMajor = 2
- val versionMinor = 4
- val versionPatch = 5
+ val versionMinor = 5
+ val versionPatch = 0
val versionBuild = 0
defaultConfig {
@@ -27,6 +22,10 @@ android {
versionCode = versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
versionName = "${versionMajor}.${versionMinor}.${versionPatch}"
+ multiDexEnabled = true
+
+ resourceConfigurations.addAll(listOf("en"))
+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
@@ -36,13 +35,35 @@ android {
buildTypes {
release {
isDebuggable = false
- isMinifyEnabled = false
+ isMinifyEnabled = true
+ isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
+ //for release testing
+ signingConfig = signingConfigs.getByName("debug")
+ }
+ debug {
+ isDebuggable = true
}
}
+ flavorDimensions.add("type")
+ productFlavors {
+ create("floss") {
+ dimension = "type"
+ applicationIdSuffix = ".floss"
+ }
+ create("general") {
+ dimension = "type"
+ if (BuildHelper.isReleaseBuild(gradle) && BuildHelper.isGeneralFlavor(gradle))
+ {
+ apply(plugin = "com.google.gms.google-services")
+ apply(plugin = "com.google.firebase.crashlytics")
+ }
+ }
+ }
+
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
@@ -52,9 +73,11 @@ android {
}
buildFeatures {
compose = true
+ buildConfig = true
+
}
composeOptions {
- kotlinCompilerExtensionVersion = "1.4.8"
+ kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get()
}
packaging {
resources {
@@ -63,68 +86,69 @@ android {
}
}
+val generalImplementation by configurations
dependencies {
- implementation("androidx.core:core-ktx:1.12.0")
- implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
- implementation("androidx.activity:activity-compose:1.7.2")
- implementation(platform("androidx.compose:compose-bom:2023.03.00"))
- implementation("androidx.compose.ui:ui")
- implementation("androidx.compose.ui:ui-graphics")
- implementation("androidx.compose.ui:ui-tooling-preview")
- implementation("androidx.compose.material3:material3:1.1.1")
- implementation("androidx.appcompat:appcompat:1.6.1")
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.androidx.activity.compose)
+ implementation(platform(libs.androidx.compose.bom))
+ implementation(libs.androidx.compose.ui)
+ implementation(libs.androidx.compose.ui.graphics)
+ implementation(libs.androidx.compose.ui.tooling.preview)
+ implementation(libs.androidx.material3)
+ implementation(libs.androidx.appcompat)
- testImplementation("junit:junit:4.13.2")
- androidTestImplementation("androidx.test.ext:junit:1.1.5")
- androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
- androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
- androidTestImplementation("androidx.compose.ui:ui-test-junit4")
- debugImplementation("androidx.compose.ui:ui-tooling")
- debugImplementation("androidx.compose.ui:ui-test-manifest")
+ //test
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+ androidTestImplementation(platform(libs.androidx.compose.bom))
+ androidTestImplementation(libs.androidx.compose.ui.test)
+ debugImplementation(libs.androidx.compose.ui.tooling)
+ debugImplementation(libs.androidx.compose.manifest)
- //wireguard tunnel
- implementation("com.wireguard.android:tunnel:1.0.20230706")
+ //wg
+ implementation(libs.tunnel)
//logging
- implementation("com.jakewharton.timber:timber:5.0.1")
+ implementation(libs.timber)
// compose navigation
- implementation("androidx.navigation:navigation-compose:2.7.2")
- implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
+ implementation(libs.androidx.navigation.compose)
+ implementation(libs.androidx.hilt.navigation.compose)
// hilt
- implementation("com.google.dagger:hilt-android:${rExtra.get("hiltVersion")}")
- kapt("com.google.dagger:hilt-android-compiler:${rExtra.get("hiltVersion")}")
+ implementation(libs.hilt.android)
+ ksp(libs.hilt.android.compiler)
//accompanist
- implementation("com.google.accompanist:accompanist-systemuicontroller:${rExtra.get("accompanistVersion")}")
- implementation("com.google.accompanist:accompanist-permissions:${rExtra.get("accompanistVersion")}")
- implementation("com.google.accompanist:accompanist-flowlayout:${rExtra.get("accompanistVersion")}")
- implementation("com.google.accompanist:accompanist-navigation-animation:${rExtra.get("accompanistVersion")}")
- implementation("com.google.accompanist:accompanist-drawablepainter:${rExtra.get("accompanistVersion")}")
+ implementation(libs.accompanist.systemuicontroller)
+ implementation(libs.accompanist.permissions)
+ implementation(libs.accompanist.flowlayout)
+ implementation(libs.accompanist.navigation.animation)
+ implementation(libs.accompanist.drawablepainter)
+
+ //room
+ implementation(libs.androidx.room.runtime)
+ annotationProcessor(libs.androidx.room.compiler)
+ ksp(libs.androidx.room.compiler)
+ implementation(libs.androidx.room.ktx)
+
- //db
- implementation("io.objectbox:objectbox-kotlin:${rExtra.get("objectBoxVersion")}")
//lifecycle
- implementation("androidx.lifecycle:lifecycle-runtime-compose:2.6.2")
+ implementation(libs.lifecycle.runtime.compose)
//icons
- implementation("androidx.compose.material:material-icons-extended:1.5.1")
-
-
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
-
+ implementation(libs.material.icons.extended)
+ //serialization
+ implementation(libs.kotlinx.serialization.json)
//firebase crashlytics
- implementation(platform("com.google.firebase:firebase-bom:32.0.0"))
- implementation("com.google.firebase:firebase-crashlytics-ktx")
- implementation("com.google.firebase:firebase-analytics-ktx")
+ generalImplementation(platform(libs.firebase.bom))
+ generalImplementation(libs.google.firebase.crashlytics.ktx)
+ generalImplementation(libs.google.firebase.analytics.ktx)
//barcode scanning
- implementation("com.google.android.gms:play-services-code-scanner:16.1.0")
-}
-
-kapt {
- correctErrorTypes = true
+ implementation(libs.play.services.code.scanner)
}
\ No newline at end of file
diff --git a/app/objectbox-models/default.json b/app/objectbox-models/default.json
deleted file mode 100644
index dd7a8ab..0000000
--- a/app/objectbox-models/default.json
+++ /dev/null
@@ -1,99 +0,0 @@
-{
- "_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
- "_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
- "_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
- "entities": [
- {
- "id": "1:2692736974585027589",
- "lastPropertyId": "15:5057486545428188436",
- "name": "TunnelConfig",
- "properties": [
- {
- "id": "1:1985347930017457084",
- "name": "id",
- "type": 6,
- "flags": 1
- },
- {
- "id": "12:2409068226744965585",
- "name": "name",
- "indexId": "1:4811206443952699137",
- "type": 9,
- "flags": 34848
- },
- {
- "id": "13:8987443291286312275",
- "name": "wgQuick",
- "type": 9
- }
- ],
- "relations": []
- },
- {
- "id": "2:8887605597748372702",
- "lastPropertyId": "9:4468844863383145378",
- "name": "Settings",
- "properties": [
- {
- "id": "1:7485739868216068651",
- "name": "id",
- "type": 6,
- "flags": 1
- },
- {
- "id": "2:5814013113141456749",
- "name": "isAutoTunnelEnabled",
- "type": 1
- },
- {
- "id": "4:5645665441196906014",
- "name": "trustedNetworkSSIDs",
- "type": 30
- },
- {
- "id": "5:4989886999117763881",
- "name": "isTunnelOnMobileDataEnabled",
- "type": 1
- },
- {
- "id": "6:3370284381040192129",
- "name": "defaultTunnel",
- "type": 9
- },
- {
- "id": "9:4468844863383145378",
- "name": "isAlwaysOnVpnEnabled",
- "type": 1
- }
- ],
- "relations": []
- }
- ],
- "lastEntityId": "2:8887605597748372702",
- "lastIndexId": "1:4811206443952699137",
- "lastRelationId": "0:0",
- "lastSequenceId": "0:0",
- "modelVersion": 5,
- "modelVersionParserMinimum": 5,
- "retiredEntityUids": [],
- "retiredIndexUids": [],
- "retiredPropertyUids": [
- 1763475292291320186,
- 6483820955437198310,
- 8323071516033820771,
- 5904440563612311217,
- 1408037976996390989,
- 7737847485212546994,
- 8215616901775229364,
- 8021610768066328637,
- 6174306582797008721,
- 2175939938544485767,
- 7555225587864607050,
- 969146862000617878,
- 5057486545428188436,
- 2814640993034665120,
- 4981008812459251156
- ],
- "retiredRelationUids": [],
- "version": 1
-}
\ No newline at end of file
diff --git a/app/objectbox-models/default.json.bak b/app/objectbox-models/default.json.bak
deleted file mode 100644
index d408486..0000000
--- a/app/objectbox-models/default.json.bak
+++ /dev/null
@@ -1,94 +0,0 @@
-{
- "_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
- "_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
- "_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
- "entities": [
- {
- "id": "1:2692736974585027589",
- "lastPropertyId": "15:5057486545428188436",
- "name": "TunnelConfig",
- "properties": [
- {
- "id": "1:1985347930017457084",
- "name": "id",
- "type": 6,
- "flags": 1
- },
- {
- "id": "12:2409068226744965585",
- "name": "name",
- "indexId": "1:4811206443952699137",
- "type": 9,
- "flags": 34848
- },
- {
- "id": "13:8987443291286312275",
- "name": "wgQuick",
- "type": 9
- }
- ],
- "relations": []
- },
- {
- "id": "2:8887605597748372702",
- "lastPropertyId": "8:4981008812459251156",
- "name": "Settings",
- "properties": [
- {
- "id": "1:7485739868216068651",
- "name": "id",
- "type": 6,
- "flags": 1
- },
- {
- "id": "2:5814013113141456749",
- "name": "isAutoTunnelEnabled",
- "type": 1
- },
- {
- "id": "4:5645665441196906014",
- "name": "trustedNetworkSSIDs",
- "type": 30
- },
- {
- "id": "5:4989886999117763881",
- "name": "isTunnelOnMobileDataEnabled",
- "type": 1
- },
- {
- "id": "6:3370284381040192129",
- "name": "defaultTunnel",
- "type": 9
- }
- ],
- "relations": []
- }
- ],
- "lastEntityId": "2:8887605597748372702",
- "lastIndexId": "1:4811206443952699137",
- "lastRelationId": "0:0",
- "lastSequenceId": "0:0",
- "modelVersion": 5,
- "modelVersionParserMinimum": 5,
- "retiredEntityUids": [],
- "retiredIndexUids": [],
- "retiredPropertyUids": [
- 1763475292291320186,
- 6483820955437198310,
- 8323071516033820771,
- 5904440563612311217,
- 1408037976996390989,
- 7737847485212546994,
- 8215616901775229364,
- 8021610768066328637,
- 6174306582797008721,
- 2175939938544485767,
- 7555225587864607050,
- 969146862000617878,
- 5057486545428188436,
- 2814640993034665120,
- 4981008812459251156
- ],
- "retiredRelationUids": [],
- "version": 1
-}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f674159..d762f13 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -114,8 +114,5 @@
-
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/Constants.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/Constants.kt
index 7bffe0b..2cf4afe 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/Constants.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/Constants.kt
@@ -1,6 +1,11 @@
package com.zaneschepke.wireguardautotunnel
object Constants {
- const val VPN_CONNECTIVITY_CHECK_INTERVAL = 3000L;
- const val VPN_STATISTIC_CHECK_INTERVAL = 10000L;
+ const val VPN_CONNECTIVITY_CHECK_INTERVAL = 3000L
+ const val VPN_STATISTIC_CHECK_INTERVAL = 10000L
+ const val SNACKBAR_DELAY = 3000L
+ const val TOGGLE_TUNNEL_DELAY = 1000L
+ const val FADE_IN_ANIMATION_DURATION = 1000
+ const val SLIDE_IN_ANIMATION_DURATION = 500
+ const val SLIDE_IN_TRANSITION_OFFSET = 1000
}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt
index 39204da..2a0368e 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt
@@ -3,32 +3,17 @@ package com.zaneschepke.wireguardautotunnel
import android.app.Application
import android.content.Context
import android.content.pm.PackageManager
-import com.google.firebase.crashlytics.FirebaseCrashlytics
-import com.google.mlkit.common.MlKit
-import com.zaneschepke.wireguardautotunnel.repository.Repository
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
import dagger.hilt.android.HiltAndroidApp
import timber.log.Timber
-import javax.inject.Inject
@HiltAndroidApp
class WireGuardAutoTunnel : Application() {
- @Inject
- lateinit var settingsRepo : Repository
-
override fun onCreate() {
super.onCreate()
if(BuildConfig.DEBUG) {
- FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(false);
Timber.plant(Timber.DebugTree())
}
- try {
- MlKit.initialize(this)
- } catch (e : Exception) {
- Timber.e(e.message)
- }
- settingsRepo.init()
}
companion object {
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/BoxModule.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/BoxModule.kt
deleted file mode 100644
index 45a74f0..0000000
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/BoxModule.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.zaneschepke.wireguardautotunnel.module
-
-import android.content.Context
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.MyObjectBox
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
-import dagger.Module
-import dagger.Provides
-import dagger.hilt.InstallIn
-import dagger.hilt.android.qualifiers.ApplicationContext
-import dagger.hilt.components.SingletonComponent
-import io.objectbox.Box
-import io.objectbox.BoxStore
-import javax.inject.Singleton
-
-@Module
-@InstallIn(SingletonComponent::class)
-class BoxModule {
-
- @Provides
- @Singleton
- fun provideBoxStore(@ApplicationContext context : Context) : BoxStore {
- return MyObjectBox.builder()
- .androidContext(context.applicationContext)
- .build()
- }
-
- @Provides
- @Singleton
- fun provideBoxForSettings(store : BoxStore) : Box {
- return store.boxFor(Settings::class.java)
- }
-
- @Provides
- @Singleton
- fun provideBoxForTunnels(store : BoxStore) : Box {
- return store.boxFor(TunnelConfig::class.java)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/DatabaseModule.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/DatabaseModule.kt
new file mode 100644
index 0000000..32aa46c
--- /dev/null
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/DatabaseModule.kt
@@ -0,0 +1,25 @@
+package com.zaneschepke.wireguardautotunnel.module
+
+import android.content.Context
+import androidx.room.Room
+import com.zaneschepke.wireguardautotunnel.R
+import com.zaneschepke.wireguardautotunnel.repository.AppDatabase
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.android.qualifiers.ApplicationContext
+import dagger.hilt.components.SingletonComponent
+import javax.inject.Singleton
+
+@Module
+@InstallIn(SingletonComponent::class)
+class DatabaseModule {
+ @Provides
+ @Singleton
+ fun provideDatabase(@ApplicationContext context : Context) : AppDatabase {
+ return Room.databaseBuilder(
+ context,
+ AppDatabase::class.java, context.getString(R.string.db_name)
+ ).build()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt
index 4626425..ca056b8 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt
@@ -1,25 +1,27 @@
package com.zaneschepke.wireguardautotunnel.module
-import com.zaneschepke.wireguardautotunnel.repository.Repository
-import com.zaneschepke.wireguardautotunnel.repository.SettingsBox
-import com.zaneschepke.wireguardautotunnel.repository.TunnelBox
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
-import dagger.Binds
+import com.zaneschepke.wireguardautotunnel.repository.AppDatabase
+import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
+import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao
import dagger.Module
+import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
-abstract class RepositoryModule {
+class RepositoryModule {
- @Binds
@Singleton
- abstract fun provideSettingsRepository(settingsBox: SettingsBox) : Repository
+ @Provides
+ fun provideSettingsRepository(appDatabase: AppDatabase) : SettingsDoa {
+ return appDatabase.settingDao()
+ }
- @Binds
@Singleton
- abstract fun provideTunnelRepository(tunnelBox: TunnelBox) : Repository
+ @Provides
+ fun provideTunnelConfigRepository(appDatabase: AppDatabase) : TunnelConfigDao {
+ return appDatabase.tunnelConfigDoa()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt
index 03b8e9f..ae743f0 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt
@@ -3,9 +3,8 @@ package com.zaneschepke.wireguardautotunnel.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
-import com.zaneschepke.wireguardautotunnel.repository.Repository
+import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -17,7 +16,7 @@ import javax.inject.Inject
class BootReceiver : BroadcastReceiver() {
@Inject
- lateinit var settingsRepo : Repository
+ lateinit var settingsRepo : SettingsDoa
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt
index 93a10ae..ebe4120 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt
@@ -3,9 +3,9 @@ package com.zaneschepke.wireguardautotunnel.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
-import com.zaneschepke.wireguardautotunnel.repository.Repository
+import com.zaneschepke.wireguardautotunnel.Constants
+import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -18,16 +18,16 @@ import javax.inject.Inject
class NotificationActionReceiver : BroadcastReceiver() {
@Inject
- lateinit var settingsRepo : Repository
+ lateinit var settingsRepo : SettingsDoa
override fun onReceive(context: Context, intent: Intent?) {
CoroutineScope(Dispatchers.IO).launch {
try {
val settings = settingsRepo.getAll()
- if (!settings.isNullOrEmpty()) {
+ if (settings.isNotEmpty()) {
val setting = settings.first()
if (setting.defaultTunnel != null) {
ServiceManager.stopVpnService(context)
- delay(1000)
+ delay(Constants.TOGGLE_TUNNEL_DELAY)
ServiceManager.startVpnService(context, setting.defaultTunnel.toString())
}
}
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/AppDatabase.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/AppDatabase.kt
new file mode 100644
index 0000000..9e3d162
--- /dev/null
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/AppDatabase.kt
@@ -0,0 +1,14 @@
+package com.zaneschepke.wireguardautotunnel.repository
+
+import androidx.room.Database
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverters
+import com.zaneschepke.wireguardautotunnel.repository.model.Settings
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
+
+@Database(entities = [Settings::class, TunnelConfig::class], version = 1)
+@TypeConverters(DatabaseListConverters::class)
+abstract class AppDatabase : RoomDatabase() {
+ abstract fun settingDao(): SettingsDoa
+ abstract fun tunnelConfigDoa() : TunnelConfigDao
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/DatabaseListConverters.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/DatabaseListConverters.kt
new file mode 100644
index 0000000..e4e94c8
--- /dev/null
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/DatabaseListConverters.kt
@@ -0,0 +1,15 @@
+package com.zaneschepke.wireguardautotunnel.repository
+
+import androidx.room.TypeConverter
+
+class DatabaseListConverters {
+ @TypeConverter
+ fun listToString(value: MutableList): String {
+ return value.joinToString()
+ }
+ @TypeConverter
+ fun stringToList(value: String): MutableList {
+ if(value.isEmpty()) return mutableListOf()
+ return value.split(",").toMutableList()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/Repository.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/Repository.kt
deleted file mode 100644
index 4f1b59f..0000000
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/Repository.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.zaneschepke.wireguardautotunnel.repository
-
-import kotlinx.coroutines.flow.Flow
-
-interface Repository {
- suspend fun save(t : T)
- suspend fun saveAll(t : List)
- suspend fun getById(id : Long) : T?
- suspend fun getAll() : List?
- suspend fun delete(t : T) : Boolean?
- suspend fun count() : Long?
-
- val itemFlow : Flow>
-
- fun init()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsBox.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsBox.kt
deleted file mode 100644
index 0ba02d3..0000000
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsBox.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.zaneschepke.wireguardautotunnel.repository
-
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
-import io.objectbox.Box
-import io.objectbox.BoxStore
-import io.objectbox.kotlin.awaitCallInTx
-import io.objectbox.kotlin.toFlow
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.launch
-import javax.inject.Inject
-
-
-class SettingsBox @Inject constructor(private val box : Box, private val boxStore : BoxStore) : Repository {
-
- @OptIn(ExperimentalCoroutinesApi::class)
- override val itemFlow = box.query().build().subscribe().toFlow()
-
- override fun init() {
- CoroutineScope(Dispatchers.IO).launch {
- if(getAll().isNullOrEmpty()) {
- save(Settings())
- }
- }
- }
-
- override suspend fun save(t : Settings) {
- boxStore.awaitCallInTx {
- box.put(t)
- }
- }
-
- override suspend fun saveAll(t : List) {
- boxStore.awaitCallInTx {
- box.put(t)
- }
- }
-
- override suspend fun getById(id: Long): Settings? {
- return boxStore.awaitCallInTx {
- box[id]
- }
- }
-
- override suspend fun getAll(): List? {
- return boxStore.awaitCallInTx {
- box.all
- }
- }
-
- override suspend fun delete(t : Settings): Boolean? {
- return boxStore.awaitCallInTx {
- box.remove(t)
- }
- }
-
- override suspend fun count() : Long? {
- return boxStore.awaitCallInTx {
- box.count()
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsDoa.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsDoa.kt
new file mode 100644
index 0000000..49120a3
--- /dev/null
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsDoa.kt
@@ -0,0 +1,34 @@
+package com.zaneschepke.wireguardautotunnel.repository
+
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import com.zaneschepke.wireguardautotunnel.repository.model.Settings
+import kotlinx.coroutines.flow.Flow
+
+@Dao
+interface SettingsDoa {
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun save(t: Settings)
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun saveAll(t: List)
+
+ @Query("SELECT * FROM settings WHERE id=:id")
+ suspend fun getById(id: Long): Settings?
+
+ @Query("SELECT * FROM settings")
+ suspend fun getAll(): List
+
+ @Query("SELECT * FROM settings")
+ fun getAllFlow(): Flow>
+
+ @Delete
+ suspend fun delete(t: Settings)
+
+ @Query("SELECT COUNT('id') FROM settings")
+ suspend fun count(): Long
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelBox.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelBox.kt
deleted file mode 100644
index ea845da..0000000
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelBox.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.zaneschepke.wireguardautotunnel.repository
-
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
-import io.objectbox.Box
-import io.objectbox.BoxStore
-import io.objectbox.kotlin.awaitCallInTx
-import io.objectbox.kotlin.toFlow
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import timber.log.Timber
-import javax.inject.Inject
-
-class TunnelBox @Inject constructor(private val box : Box,private val boxStore : BoxStore) : Repository {
-
- @OptIn(ExperimentalCoroutinesApi::class)
- override val itemFlow = box.query().build().subscribe().toFlow()
- override fun init() {
-
- }
-
- override suspend fun save(t : TunnelConfig) {
- Timber.d("Saving tunnel config")
- boxStore.awaitCallInTx {
- box.put(t)
- }
-
- }
-
- override suspend fun saveAll(t : List) {
- boxStore.awaitCallInTx {
- box.put(t)
- }
- }
-
- override suspend fun getById(id: Long): TunnelConfig? {
- return boxStore.awaitCallInTx {
- box[id]
- }
- }
-
- override suspend fun getAll(): List? {
- return boxStore.awaitCallInTx {
- box.all
- }
- }
-
- override suspend fun delete(t : TunnelConfig): Boolean? {
- return boxStore.awaitCallInTx {
- box.remove(t)
- }
- }
-
- override suspend fun count() : Long? {
- return boxStore.awaitCallInTx {
- box.count()
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelConfigDao.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelConfigDao.kt
new file mode 100644
index 0000000..2533c7a
--- /dev/null
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelConfigDao.kt
@@ -0,0 +1,34 @@
+package com.zaneschepke.wireguardautotunnel.repository
+
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
+import kotlinx.coroutines.flow.Flow
+
+@Dao
+interface TunnelConfigDao{
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun save(t: TunnelConfig)
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun saveAll(t: List)
+
+ @Query("SELECT * FROM TunnelConfig WHERE id=:id")
+ suspend fun getById(id: Long): TunnelConfig?
+
+ @Query("SELECT * FROM TunnelConfig")
+ suspend fun getAll(): List
+
+ @Delete
+ suspend fun delete(t: TunnelConfig)
+
+ @Query("SELECT COUNT('id') FROM TunnelConfig")
+ suspend fun count(): Long
+
+ @Query("SELECT * FROM tunnelconfig")
+ fun getAllFlow(): Flow>
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/Settings.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/Settings.kt
new file mode 100644
index 0000000..dd67942
--- /dev/null
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/Settings.kt
@@ -0,0 +1,15 @@
+package com.zaneschepke.wireguardautotunnel.repository.model
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity
+data class Settings(
+ @PrimaryKey(autoGenerate = true) val id : Int = 0,
+ @ColumnInfo(name = "is_tunnel_enabled") var isAutoTunnelEnabled : Boolean = false,
+ @ColumnInfo(name = "is_tunnel_on_mobile_data_enabled") var isTunnelOnMobileDataEnabled : Boolean = false,
+ @ColumnInfo(name = "trusted_network_ssids") var trustedNetworkSSIDs : MutableList = mutableListOf(),
+ @ColumnInfo(name = "default_tunnel") var defaultTunnel : String? = null,
+ @ColumnInfo(name = "is_always_on_vpn_enabled") var isAlwaysOnVpnEnabled : Boolean = false,
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/TunnelConfig.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/TunnelConfig.kt
similarity index 88%
rename from app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/TunnelConfig.kt
rename to app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/TunnelConfig.kt
index 2d22faa..bd80f66 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/TunnelConfig.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/model/TunnelConfig.kt
@@ -1,25 +1,21 @@
-package com.zaneschepke.wireguardautotunnel.service.tunnel.model
+package com.zaneschepke.wireguardautotunnel.repository.model
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.Index
+import androidx.room.PrimaryKey
import com.wireguard.config.Config
-import io.objectbox.annotation.ConflictStrategy
-import io.objectbox.annotation.Entity
-import io.objectbox.annotation.Id
-import io.objectbox.annotation.Unique
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import java.io.InputStream
-
-@Entity
+@Entity(indices = [Index(value = ["name"], unique = true)])
@Serializable
data class TunnelConfig(
- @Id
- var id : Long = 0,
- @Unique(onConflict = ConflictStrategy.REPLACE)
- var name : String,
- var wgQuick : String
-) {
-
+ @PrimaryKey(autoGenerate = true) val id : Int = 0,
+ @ColumnInfo(name = "name") var name : String,
+ @ColumnInfo(name = "wg_quick") var wgQuick : String,
+){
override fun toString(): String {
return Json.encodeToString(serializer(), this)
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt
index 816eea5..35b00a8 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt
@@ -5,9 +5,8 @@ import android.app.Service
import android.content.Context
import android.content.Context.ACTIVITY_SERVICE
import android.content.Intent
-import com.google.firebase.crashlytics.ktx.crashlytics
-import com.google.firebase.ktx.Firebase
import com.zaneschepke.wireguardautotunnel.R
+import timber.log.Timber
object ServiceManager {
@Suppress("DEPRECATION")
@@ -43,7 +42,7 @@ object ServiceManager {
Action.STOP -> context.startService(intent)
}
} catch (e : Exception) {
- e.message?.let { Firebase.crashlytics.log(it) }
+ Timber.e(e.message)
}
}
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt
index e24faec..37e24d4 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt
@@ -10,14 +10,14 @@ import android.os.SystemClock
import com.wireguard.android.backend.Tunnel
import com.zaneschepke.wireguardautotunnel.Constants
import com.zaneschepke.wireguardautotunnel.R
-import com.zaneschepke.wireguardautotunnel.repository.Repository
+import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
+import com.zaneschepke.wireguardautotunnel.repository.model.Settings
import com.zaneschepke.wireguardautotunnel.service.network.MobileDataService
import com.zaneschepke.wireguardautotunnel.service.network.NetworkService
import com.zaneschepke.wireguardautotunnel.service.network.NetworkStatus
import com.zaneschepke.wireguardautotunnel.service.network.WifiService
import com.zaneschepke.wireguardautotunnel.service.notification.NotificationService
import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -39,7 +39,7 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
lateinit var mobileDataService : NetworkService
@Inject
- lateinit var settingsRepo: Repository
+ lateinit var settingsRepo: SettingsDoa
@Inject
lateinit var notificationService : NotificationService
@@ -131,7 +131,7 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
private fun startWatcherJob() {
watcherJob = CoroutineScope(Dispatchers.IO).launch {
val settings = settingsRepo.getAll();
- if(!settings.isNullOrEmpty()) {
+ if(settings.isNotEmpty()) {
setting = settings[0]
}
launch {
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt
index b875591..62d9c9e 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt
@@ -5,12 +5,11 @@ import android.content.Intent
import android.os.Bundle
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.receiver.NotificationActionReceiver
-import com.zaneschepke.wireguardautotunnel.repository.Repository
+import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
import com.zaneschepke.wireguardautotunnel.service.notification.NotificationService
import com.zaneschepke.wireguardautotunnel.service.tunnel.HandshakeStatus
import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -28,7 +27,7 @@ class WireGuardTunnelService : ForegroundService() {
lateinit var vpnService : VpnService
@Inject
- lateinit var settingsRepo: Repository
+ lateinit var settingsRepo: SettingsDoa
@Inject
lateinit var notificationService : NotificationService
@@ -62,7 +61,7 @@ class WireGuardTunnelService : ForegroundService() {
} else {
Timber.d("Tunnel config null, starting default tunnel")
val settings = settingsRepo.getAll();
- if(!settings.isNullOrEmpty()) {
+ if(settings.isNotEmpty()) {
val setting = settings[0]
if(setting.defaultTunnel != null && setting.isAlwaysOnVpnEnabled) {
val tunnelConfig = TunnelConfig.from(setting.defaultTunnel!!)
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt
index 2ebb866..bb5cc30 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt
@@ -3,11 +3,10 @@ package com.zaneschepke.wireguardautotunnel.service.shortcut
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.zaneschepke.wireguardautotunnel.R
-import com.zaneschepke.wireguardautotunnel.repository.Repository
+import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
import com.zaneschepke.wireguardautotunnel.service.foreground.Action
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardTunnelService
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -18,14 +17,14 @@ import javax.inject.Inject
class ShortcutsActivity : AppCompatActivity() {
@Inject
- lateinit var settingsRepo : Repository
+ lateinit var settingsRepo : SettingsDoa
private val scope = CoroutineScope(Dispatchers.Main);
private fun attemptWatcherServiceToggle(tunnelConfig : String) {
scope.launch {
val settings = settingsRepo.getAll()
- if (!settings.isNullOrEmpty()) {
+ if (settings.isNotEmpty()) {
val setting = settings.first()
if(setting.isAutoTunnelEnabled) {
ServiceManager.toggleWatcherServiceForeground(this@ShortcutsActivity, tunnelConfig)
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsManager.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsManager.kt
index 04c0e9d..8798319 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsManager.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsManager.kt
@@ -8,7 +8,7 @@ import androidx.core.graphics.drawable.IconCompat
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.service.foreground.Action
import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardTunnelService
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
object ShortcutsManager {
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt
index 65e8469..0dc9479 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt
@@ -5,11 +5,11 @@ import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import com.wireguard.android.backend.Tunnel
import com.zaneschepke.wireguardautotunnel.R
-import com.zaneschepke.wireguardautotunnel.repository.Repository
+import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
+import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -23,10 +23,10 @@ import javax.inject.Inject
class TunnelControlTile : TileService() {
@Inject
- lateinit var settingsRepo : Repository
+ lateinit var settingsRepo : SettingsDoa
@Inject
- lateinit var configRepo : Repository
+ lateinit var configRepo : TunnelConfigDao
@Inject
lateinit var vpnService : VpnService
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt
index 346a49a..1557c20 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt
@@ -3,7 +3,7 @@ package com.zaneschepke.wireguardautotunnel.service.tunnel
import com.wireguard.android.backend.Statistics
import com.wireguard.android.backend.Tunnel
import com.wireguard.crypto.Key
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import kotlinx.coroutines.flow.SharedFlow
interface VpnService : Tunnel {
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt
index 2f40c71..87116c7 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt
@@ -6,7 +6,7 @@ import com.wireguard.android.backend.Statistics
import com.wireguard.android.backend.Tunnel
import com.wireguard.crypto.Key
import com.zaneschepke.wireguardautotunnel.Constants
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.util.NumberUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/Settings.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/Settings.kt
deleted file mode 100644
index a868467..0000000
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/Settings.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.zaneschepke.wireguardautotunnel.service.tunnel.model
-
-import io.objectbox.annotation.Entity
-import io.objectbox.annotation.Id
-
-@Entity
-data class Settings(
- @Id
- var id : Long = 0,
- var isAutoTunnelEnabled : Boolean = false,
- var isTunnelOnMobileDataEnabled : Boolean = false,
- var trustedNetworkSSIDs : MutableList = mutableListOf(),
- var defaultTunnel : String? = null,
- var isAlwaysOnVpnEnabled : Boolean = false,
-)
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/MainActivity.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/MainActivity.kt
index 4e5758a..b72f801 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/MainActivity.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/MainActivity.kt
@@ -33,6 +33,7 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import com.wireguard.android.backend.GoBackend
+import com.zaneschepke.wireguardautotunnel.Constants
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.ui.common.PermissionRequestFailedScreen
import com.zaneschepke.wireguardautotunnel.ui.common.navigation.BottomNavBar
@@ -143,12 +144,12 @@ class MainActivity : AppCompatActivity() {
when (initialState.destination.route) {
Routes.Settings.name, Routes.Support.name ->
slideInHorizontally(
- initialOffsetX = { -1000 },
- animationSpec = tween(500)
+ initialOffsetX = { -Constants.SLIDE_IN_TRANSITION_OFFSET },
+ animationSpec = tween(Constants.SLIDE_IN_ANIMATION_DURATION)
)
else -> {
- fadeIn(animationSpec = tween(1000))
+ fadeIn(animationSpec = tween(Constants.FADE_IN_ANIMATION_DURATION))
}
}
}) {
@@ -158,19 +159,19 @@ class MainActivity : AppCompatActivity() {
when (initialState.destination.route) {
Routes.Main.name ->
slideInHorizontally(
- initialOffsetX = { 1000 },
- animationSpec = tween(500)
+ initialOffsetX = { Constants.SLIDE_IN_TRANSITION_OFFSET },
+ animationSpec = tween(Constants.SLIDE_IN_ANIMATION_DURATION)
)
Routes.Support.name -> {
slideInHorizontally(
- initialOffsetX = { -1000 },
- animationSpec = tween(500)
+ initialOffsetX = { -Constants.SLIDE_IN_TRANSITION_OFFSET },
+ animationSpec = tween(Constants.SLIDE_IN_ANIMATION_DURATION)
)
}
else -> {
- fadeIn(animationSpec = tween(1000))
+ fadeIn(animationSpec = tween(Constants.FADE_IN_ANIMATION_DURATION))
}
}
}) { SettingsScreen(padding = padding, snackbarHostState = snackbarHostState, navController = navController, focusRequester = focusRequester) }
@@ -178,20 +179,20 @@ class MainActivity : AppCompatActivity() {
when (initialState.destination.route) {
Routes.Settings.name, Routes.Main.name ->
slideInHorizontally(
- initialOffsetX = { 1000 },
- animationSpec = tween(500)
+ initialOffsetX = { Constants.SLIDE_IN_ANIMATION_DURATION },
+ animationSpec = tween(Constants.SLIDE_IN_ANIMATION_DURATION)
)
else -> {
- fadeIn(animationSpec = tween(1000))
+ fadeIn(animationSpec = tween(Constants.FADE_IN_ANIMATION_DURATION))
}
}
}) { SupportScreen(padding = padding, focusRequester) }
composable("${Routes.Config.name}/{id}", enterTransition = {
- fadeIn(animationSpec = tween(1000))
+ fadeIn(animationSpec = tween(Constants.FADE_IN_ANIMATION_DURATION))
}) { ConfigScreen(padding = padding, navController = navController, id = it.arguments?.getString("id"), focusRequester = focusRequester)}
composable("${Routes.Detail.name}/{id}", enterTransition = {
- fadeIn(animationSpec = tween(1000))
+ fadeIn(animationSpec = tween(Constants.FADE_IN_ANIMATION_DURATION))
}) { DetailScreen(padding = padding, id = it.arguments?.getString("id")) }
}
}
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt
index 25a0c07..6afe299 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt
@@ -9,10 +9,10 @@ import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.toMutableStateList
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.zaneschepke.wireguardautotunnel.repository.Repository
+import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
+import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao
import com.zaneschepke.wireguardautotunnel.service.shortcut.ShortcutsManager
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -22,8 +22,8 @@ import javax.inject.Inject
@HiltViewModel
class ConfigViewModel @Inject constructor(private val application : Application,
- private val tunnelRepo : Repository,
- private val settingsRepo : Repository) : ViewModel() {
+ private val tunnelRepo : TunnelConfigDao,
+ private val settingsRepo : SettingsDoa) : ViewModel() {
private val _tunnel = MutableStateFlow(null)
private val _tunnelName = MutableStateFlow("")
@@ -140,14 +140,15 @@ class ConfigViewModel @Inject constructor(private val application : Application,
tunnelRepo.save(it)
ShortcutsManager.createTunnelShortcuts(application, it)
val settings = settingsRepo.getAll()
- if(settings != null) {
- val setting = settings[0]
- if(setting.defaultTunnel != null) {
- if(it.id == TunnelConfig.from(setting.defaultTunnel!!).id) {
- settingsRepo.save(setting.copy(
- defaultTunnel = it.toString()
- ))
- }
+ if(settings.isEmpty()) {
+ return
+ }
+ val setting = settings[0]
+ if(setting.defaultTunnel != null) {
+ if(it.id == TunnelConfig.from(setting.defaultTunnel!!).id) {
+ settingsRepo.save(setting.copy(
+ defaultTunnel = it.toString()
+ ))
}
}
}
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailViewModel.kt
index 59c5698..c6f39ac 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailViewModel.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailViewModel.kt
@@ -2,9 +2,9 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.detail
import androidx.lifecycle.ViewModel
import com.wireguard.config.Config
-import com.zaneschepke.wireguardautotunnel.repository.Repository
+import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -12,7 +12,7 @@ import timber.log.Timber
import javax.inject.Inject
@HiltViewModel
-class DetailViewModel @Inject constructor(private val tunnelRepo : Repository, private val vpnService : VpnService
+class DetailViewModel @Inject constructor(private val tunnelRepo : TunnelConfigDao, private val vpnService : VpnService
) : ViewModel() {
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt
index 42f085b..cbca1db 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt
@@ -18,7 +18,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.FileOpen
@@ -73,8 +73,8 @@ import androidx.navigation.NavController
import com.wireguard.android.backend.Tunnel
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.service.tunnel.HandshakeStatus
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.ui.Routes
import com.zaneschepke.wireguardautotunnel.ui.common.RowListItem
import com.zaneschepke.wireguardautotunnel.ui.theme.brickRed
@@ -249,7 +249,7 @@ fun MainScreen(
.fillMaxSize()
.nestedScroll(nestedScrollConnection),
) {
- itemsIndexed(tunnels.toList()) { _, tunnel ->
+ items(tunnels, key = { tunnel -> tunnel.id }) {tunnel ->
val focusRequester = FocusRequester();
RowListItem(leadingIcon = Icons.Rounded.Circle,
leadingIconColor = if (tunnelName == tunnel.name) when (handshakeStatus) {
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt
index 8caed38..e82eba2 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt
@@ -9,21 +9,26 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.wireguard.config.BadConfigException
import com.wireguard.config.Config
+import com.zaneschepke.wireguardautotunnel.Constants
import com.zaneschepke.wireguardautotunnel.R
-import com.zaneschepke.wireguardautotunnel.repository.Repository
+import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
+import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao
import com.zaneschepke.wireguardautotunnel.service.barcode.CodeScanner
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceState
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardConnectivityWatcherService
import com.zaneschepke.wireguardautotunnel.service.shortcut.ShortcutsManager
import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
+import com.zaneschepke.wireguardautotunnel.repository.model.Settings
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.ui.ViewState
+import com.zaneschepke.wireguardautotunnel.util.NumberUtils
import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@@ -31,15 +36,15 @@ import javax.inject.Inject
@HiltViewModel
class MainViewModel @Inject constructor(private val application : Application,
- private val tunnelRepo : Repository,
- private val settingsRepo : Repository,
+ private val tunnelRepo : TunnelConfigDao,
+ private val settingsRepo : SettingsDoa,
private val vpnService: VpnService,
private val codeScanner: CodeScanner
) : ViewModel() {
private val _viewState = MutableStateFlow(ViewState())
val viewState get() = _viewState.asStateFlow()
- val tunnels get() = tunnelRepo.itemFlow
+ val tunnels get() = tunnelRepo.getAllFlow()
val state get() = vpnService.state
val handshakeStatus get() = vpnService.handshakeStatus
@@ -47,14 +52,9 @@ class MainViewModel @Inject constructor(private val application : Application,
private val _settings = MutableStateFlow(Settings())
val settings get() = _settings.asStateFlow()
- private val defaultConfigName = {
- "tunnel${(Math.random() * 100000).toInt()}"
- }
-
-
init {
- viewModelScope.launch {
- settingsRepo.itemFlow.collect {
+ viewModelScope.launch(Dispatchers.IO) {
+ settingsRepo.getAllFlow().filter { it.isNotEmpty() }.collect {
val settings = it.first()
validateWatcherServiceState(settings)
_settings.emit(settings)
@@ -75,7 +75,7 @@ class MainViewModel @Inject constructor(private val application : Application,
if(tunnelRepo.count() == 1L) {
ServiceManager.stopWatcherService(application.applicationContext)
val settings = settingsRepo.getAll()
- if(!settings.isNullOrEmpty()) {
+ if(settings.isNotEmpty()) {
val setting = settings[0]
setting.defaultTunnel = null
setting.isAutoTunnelEnabled = false
@@ -99,7 +99,7 @@ class MainViewModel @Inject constructor(private val application : Application,
suspend fun onTunnelQRSelected() {
codeScanner.scan().collect {
if(!it.isNullOrEmpty() && it.contains(application.resources.getString(R.string.config_validation))) {
- val tunnelConfig = TunnelConfig(name = defaultConfigName(), wgQuick = it)
+ val tunnelConfig = TunnelConfig(name = NumberUtils.generateRandomTunnelName(), wgQuick = it)
saveTunnel(tunnelConfig)
} else if(!it.isNullOrEmpty() && it.contains(application.resources.getString(R.string.barcode_downloading))) {
showSnackBarMessage(application.resources.getString(R.string.barcode_downloading_message))
@@ -110,34 +110,34 @@ class MainViewModel @Inject constructor(private val application : Application,
}
fun onTunnelFileSelected(uri : Uri) {
- try {
- val fileName = getFileName(application.applicationContext, uri)
- val extension = getFileExtensionFromFileName(fileName)
- if(extension != ".conf") {
- viewModelScope.launch {
- showSnackBarMessage(application.resources.getString(R.string.file_extension_message))
+ viewModelScope.launch(Dispatchers.IO) {
+ try {
+ val fileName = getFileName(application.applicationContext, uri)
+ val extension = getFileExtensionFromFileName(fileName)
+ if (extension != ".conf") {
+ launch {
+ showSnackBarMessage(application.resources.getString(R.string.file_extension_message))
+ }
+ return@launch
}
- return
- }
- val stream = application.applicationContext.contentResolver.openInputStream(uri)
- stream ?: return
- val bufferReader = stream.bufferedReader(charset = Charsets.UTF_8)
+ val stream = application.applicationContext.contentResolver.openInputStream(uri)
+ stream ?: return@launch
+ val bufferReader = stream.bufferedReader(charset = Charsets.UTF_8)
val config = Config.parse(bufferReader)
val tunnelName = getNameFromFileName(fileName)
saveTunnel(TunnelConfig(name = tunnelName, wgQuick = config.toWgQuickString()))
- stream.close()
- } catch(_: BadConfigException) {
- viewModelScope.launch {
- showSnackBarMessage(application.applicationContext.getString(R.string.bad_config))
+ stream.close()
+ } catch (_: BadConfigException) {
+ launch {
+ showSnackBarMessage(application.applicationContext.getString(R.string.bad_config))
+ }
}
}
}
- private fun saveTunnel(tunnelConfig : TunnelConfig) {
- viewModelScope.launch {
- tunnelRepo.save(tunnelConfig)
- ShortcutsManager.createTunnelShortcuts(application.applicationContext, tunnelConfig)
- }
+ private suspend fun saveTunnel(tunnelConfig : TunnelConfig) {
+ tunnelRepo.save(tunnelConfig)
+ ShortcutsManager.createTunnelShortcuts(application.applicationContext, tunnelConfig)
}
@SuppressLint("Range")
@@ -149,14 +149,14 @@ class MainViewModel @Inject constructor(private val application : Application,
Timber.d("Exception getting config name")
null
}
- cursor ?: return defaultConfigName()
+ cursor ?: return NumberUtils.generateRandomTunnelName()
cursor.use {
if(cursor.moveToFirst()) {
return cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
}
}
}
- return defaultConfigName()
+ return NumberUtils.generateRandomTunnelName()
}
suspend fun showSnackBarMessage(message : String) {
@@ -170,7 +170,7 @@ class MainViewModel @Inject constructor(private val application : Application,
}
}
))
- delay(3000)
+ delay(Constants.SNACKBAR_DELAY)
dismissSnackBar()
}
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt
index 753244e..3275815 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt
@@ -69,7 +69,7 @@ import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.ui.Routes
import com.zaneschepke.wireguardautotunnel.ui.common.ClickableIconButton
import kotlinx.coroutines.launch
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt
index 256fb7d..0a4ecde 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt
@@ -6,35 +6,41 @@ import android.location.LocationManager
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.zaneschepke.wireguardautotunnel.R
-import com.zaneschepke.wireguardautotunnel.repository.Repository
+import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
+import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao
+import com.zaneschepke.wireguardautotunnel.repository.model.Settings
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
-import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.ui.ViewState
import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class SettingsViewModel @Inject constructor(private val application : Application,
- private val tunnelRepo : Repository, private val settingsRepo : Repository
+ private val tunnelRepo : TunnelConfigDao, private val settingsRepo : SettingsDoa
) : ViewModel() {
private val _trustedSSIDs = MutableStateFlow(emptyList())
val trustedSSIDs = _trustedSSIDs.asStateFlow()
private val _settings = MutableStateFlow(Settings())
val settings get() = _settings.asStateFlow()
- val tunnels get() = tunnelRepo.itemFlow
+ val tunnels get() = tunnelRepo.getAllFlow()
private val _viewState = MutableStateFlow(ViewState())
val viewState get() = _viewState.asStateFlow()
init {
checkLocationServicesEnabled()
- viewModelScope.launch {
- settingsRepo.itemFlow.collect {
+ viewModelScope.launch(Dispatchers.IO) {
+ settingsRepo.getAllFlow().filter { it.isNotEmpty() }.collect {
val settings = it.first()
_settings.emit(settings)
_trustedSSIDs.emit(settings.trustedNetworkSSIDs.toList())
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/NumberUtils.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/NumberUtils.kt
index 7cdeddc..dd2a5b8 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/NumberUtils.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/NumberUtils.kt
@@ -13,6 +13,10 @@ object NumberUtils {
return bytes.toBigDecimal().divide(BYTES_IN_KB.toBigDecimal())
}
+ fun generateRandomTunnelName() : String {
+ return "tunnel${(Math.random() * 100000).toInt()}"
+ }
+
fun formatDecimalTwoPlaces(bigDecimal: BigDecimal) : String {
val df = DecimalFormat("#.##")
return df.format(bigDecimal)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7a2536e..8297e67 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -91,4 +91,5 @@
Search Icon
Attempting connection..
VPN Starting
+ wg-tunnel-db
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 95714b7..3ecbf9b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,20 +1,18 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
buildscript {
- val objectBoxVersion by extra("3.7.0")
- val hiltVersion by extra("2.48")
- val accompanistVersion by extra("0.31.2-alpha")
-
dependencies {
- classpath("io.objectbox:objectbox-gradle-plugin:$objectBoxVersion")
- classpath("com.google.gms:google-services:4.3.15")
- classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.9")
+ if (BuildHelper.isReleaseBuild(gradle) && BuildHelper.isGeneralFlavor(gradle)) {
+ classpath(libs.google.services)
+ classpath(libs.firebase.crashlytics.gradle)
+ }
}
}
+
+
plugins {
- id("com.android.application") version "8.2.0-beta03" apply false
- id("org.jetbrains.kotlin.android") version "1.8.22" apply false
- id("com.google.dagger.hilt.android") version "2.48" apply false
- kotlin("plugin.serialization") version "1.8.22" apply false
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+ alias(libs.plugins.hilt.android) apply false
+ kotlin("plugin.serialization").version(libs.versions.kotlin).apply(false)
+ alias(libs.plugins.ksp) apply false
}
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
new file mode 100644
index 0000000..37871be
--- /dev/null
+++ b/buildSrc/build.gradle.kts
@@ -0,0 +1,8 @@
+plugins {
+ `kotlin-dsl` // enable the Kotlin-DSL
+}
+
+repositories {
+ google()
+ mavenCentral()
+}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/BuildHelper.kt b/buildSrc/src/main/kotlin/BuildHelper.kt
new file mode 100644
index 0000000..13b6bd4
--- /dev/null
+++ b/buildSrc/src/main/kotlin/BuildHelper.kt
@@ -0,0 +1,29 @@
+import org.gradle.api.invocation.Gradle
+
+object BuildHelper {
+ private fun getCurrentFlavor(gradle : Gradle): String {
+ val taskRequestsStr = gradle.startParameter.taskRequests.toString()
+ val pattern: java.util.regex.Pattern = if (taskRequestsStr.contains("assemble")) {
+ java.util.regex.Pattern.compile("assemble(\\w+)(Release|Debug)")
+ } else {
+ java.util.regex.Pattern.compile("bundle(\\w+)(Release|Debug)")
+ }
+
+ val matcher = pattern.matcher(taskRequestsStr)
+ val flavor = if (matcher.find()) {
+ matcher.group(1).lowercase()
+ } else {
+ print("NO FLAVOR FOUND")
+ ""
+ }
+ return flavor
+ }
+
+ fun isGeneralFlavor(gradle : Gradle) : Boolean {
+ return getCurrentFlavor(gradle) == "general"
+ }
+ fun isReleaseBuild(gradle: Gradle) : Boolean {
+ return (gradle.startParameter.taskNames.size > 0 && gradle.startParameter.taskNames[0].contains(
+ "Release"))
+ }
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 1023be8..2cbd6d1 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -21,5 +21,3 @@ kotlin.code.style=official
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
-#enable buildconfig values
-android.defaults.buildfeatures.buildconfig=true
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 0000000..487e750
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,89 @@
+[versions]
+accompanist = "0.31.2-alpha"
+activityCompose = "1.7.2"
+androidx-junit = "1.1.5"
+appcompat = "1.6.1"
+coreKtx = "1.12.0"
+espressoCore = "3.5.1"
+firebase-crashlytics-gradle = "2.9.9"
+google-services = "4.3.15"
+hiltAndroid = "2.48"
+hiltNavigationCompose = "1.0.0"
+junit = "4.13.2"
+kotlinx-serialization-json = "1.5.1"
+lifecycle-runtime-compose = "2.6.2"
+material-icons-extended = "1.5.1"
+material3 = "1.1.1"
+navigationCompose = "2.7.2"
+playServicesCodeScanner = "16.1.0"
+roomVersion = "2.6.0-beta01"
+timber = "5.0.1"
+tunnel = "1.0.20230706"
+androidGradlePlugin = "8.2.0-beta03"
+kotlin="1.9.10"
+ksp="1.9.10-1.0.13"
+composeBom="2023.09.00"
+firebaseBom="32.2.3"
+compose="1.5.1"
+crashlytics="18.4.1"
+analytics="21.3.0"
+composeCompiler="1.5.3"
+
+
+[libraries]
+# accompanist
+accompanist-drawablepainter = { module = "com.google.accompanist:accompanist-drawablepainter", version.ref = "accompanist" }
+accompanist-flowlayout = { module = "com.google.accompanist:accompanist-flowlayout", version.ref = "accompanist" }
+accompanist-navigation-animation = { module = "com.google.accompanist:accompanist-navigation-animation", version.ref = "accompanist" }
+accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" }
+accompanist-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" }
+#room
+androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "roomVersion" }
+androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "roomVersion" }
+androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomVersion" }
+
+#compose
+androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref="composeBom" }
+androidx-compose-ui-test = { module="androidx.compose.ui:ui-test-junit4", version.ref="compose" }
+androidx-compose-ui-tooling = { module="androidx.compose.ui:ui-tooling", version.ref="compose" }
+androidx-compose-manifest = { module="androidx.compose.ui:ui-test-manifest", version.ref="compose" }
+androidx-compose-ui-graphics = { module="androidx.compose.ui:ui-graphics", version.ref="compose" }
+androidx-compose-ui-tooling-preview = { module="androidx.compose.ui:ui-tooling-preview", version.ref="compose" }
+androidx-compose-ui = { module="androidx.compose.ui:ui", version.ref="compose" }
+
+#hilt
+hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" }
+hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hiltAndroid" }
+
+androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" }
+androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
+androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
+androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espressoCore" }
+androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
+androidx-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-junit" }
+androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle-runtime-compose" }
+androidx-material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
+androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
+
+junit = { module = "junit:junit", version.ref = "junit" }
+kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
+lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle-runtime-compose" }
+material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "material-icons-extended" }
+play-services-code-scanner = { module = "com.google.android.gms:play-services-code-scanner", version.ref = "playServicesCodeScanner" }
+
+timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
+
+tunnel = { module = "com.wireguard.android:tunnel", version.ref = "tunnel" }
+
+#firebase
+google-firebase-crashlytics-ktx = { module = "com.google.firebase:firebase-crashlytics-ktx", version.ref = "crashlytics" }
+google-firebase-analytics-ktx = { module = "com.google.firebase:firebase-analytics-ktx", version.ref = "analytics" }
+firebase-crashlytics-gradle = { module = "com.google.firebase:firebase-crashlytics-gradle", version.ref = "firebase-crashlytics-gradle" }
+firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom"}
+google-services = { module = "com.google.gms:google-services", version.ref = "google-services" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hiltAndroid" }
+ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }