feat: support Android 8

Add support for Android 8.

Fix shortcuts bug where it was toggling auto-tunneling without setting enabled.

Fix shortcuts name not updating with config edits.

Bump versions.

Closes #25
This commit is contained in:
Zane Schepke 2023-09-12 12:48:54 -04:00
parent e81066f508
commit 69b07eec6f
6 changed files with 78 additions and 48 deletions

View File

@ -17,12 +17,12 @@ android {
val versionMajor = 2 val versionMajor = 2
val versionMinor = 4 val versionMinor = 4
val versionPatch = 4 val versionPatch = 5
val versionBuild = 0 val versionBuild = 0
defaultConfig { defaultConfig {
applicationId = "com.zaneschepke.wireguardautotunnel" applicationId = "com.zaneschepke.wireguardautotunnel"
minSdk = 28 minSdk = 26
targetSdk = 34 targetSdk = 34
versionCode = versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild versionCode = versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
versionName = "${versionMajor}.${versionMinor}.${versionPatch}" versionName = "${versionMajor}.${versionMinor}.${versionPatch}"
@ -64,8 +64,8 @@ android {
} }
dependencies { dependencies {
implementation("androidx.core:core-ktx:1.10.1") implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.7.2") implementation("androidx.activity:activity-compose:1.7.2")
implementation(platform("androidx.compose:compose-bom:2023.03.00")) implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui")
@ -89,7 +89,7 @@ dependencies {
implementation("com.jakewharton.timber:timber:5.0.1") implementation("com.jakewharton.timber:timber:5.0.1")
// compose navigation // compose navigation
implementation("androidx.navigation:navigation-compose:2.7.1") implementation("androidx.navigation:navigation-compose:2.7.2")
implementation("androidx.hilt:hilt-navigation-compose:1.0.0") implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
// hilt // hilt
@ -107,10 +107,10 @@ dependencies {
implementation("io.objectbox:objectbox-kotlin:${rExtra.get("objectBoxVersion")}") implementation("io.objectbox:objectbox-kotlin:${rExtra.get("objectBoxVersion")}")
//lifecycle //lifecycle
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.6.1") implementation("androidx.lifecycle:lifecycle-runtime-compose:2.6.2")
//icons //icons
implementation("androidx.compose.material:material-icons-extended:1.5.0") implementation("androidx.compose.material:material-icons-extended:1.5.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")

View File

@ -3,19 +3,44 @@ package com.zaneschepke.wireguardautotunnel.service.shortcut
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.zaneschepke.wireguardautotunnel.R import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.repository.Repository
import com.zaneschepke.wireguardautotunnel.service.foreground.Action import com.zaneschepke.wireguardautotunnel.service.foreground.Action
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardTunnelService import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardTunnelService
import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class ShortcutsActivity : AppCompatActivity() { class ShortcutsActivity : AppCompatActivity() {
@Inject
lateinit var settingsRepo : Repository<Settings>
private val scope = CoroutineScope(Dispatchers.Main);
private fun attemptWatcherServiceToggle(tunnelConfig : String) {
scope.launch {
val settings = settingsRepo.getAll()
if (!settings.isNullOrEmpty()) {
val setting = settings.first()
if(setting.isAutoTunnelEnabled) {
ServiceManager.toggleWatcherServiceForeground(this@ShortcutsActivity, tunnelConfig)
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if(intent.getStringExtra(ShortcutsManager.CLASS_NAME_EXTRA_KEY) if(intent.getStringExtra(ShortcutsManager.CLASS_NAME_EXTRA_KEY)
.equals(WireGuardTunnelService::class.java.name)) { .equals(WireGuardTunnelService::class.java.name)) {
intent.getStringExtra(getString(R.string.tunnel_extras_key))?.let { intent.getStringExtra(getString(R.string.tunnel_extras_key))?.let {
ServiceManager.toggleWatcherService(this, it) attemptWatcherServiceToggle(it)
} }
when(intent.action){ when(intent.action){
Action.STOP.name -> ServiceManager.stopVpnService(this) Action.STOP.name -> ServiceManager.stopVpnService(this)

View File

@ -10,6 +10,7 @@ import androidx.compose.runtime.toMutableStateList
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.zaneschepke.wireguardautotunnel.repository.Repository import com.zaneschepke.wireguardautotunnel.repository.Repository
import com.zaneschepke.wireguardautotunnel.service.shortcut.ShortcutsManager
import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings
import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig import com.zaneschepke.wireguardautotunnel.service.tunnel.model.TunnelConfig
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
@ -114,12 +115,14 @@ class ConfigViewModel @Inject constructor(private val application : Application,
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackagesHoldingPermissions(permissions, PackageManager.PackageInfoFlags.of(0L)) packageManager.getPackagesHoldingPermissions(permissions, PackageManager.PackageInfoFlags.of(0L))
} else { } else {
@Suppress("DEPRECATION")
packageManager.getPackagesHoldingPermissions(permissions, 0) packageManager.getPackagesHoldingPermissions(permissions, 0)
} }
} }
suspend fun onSaveAllChanges() { suspend fun onSaveAllChanges() {
if(_tunnel.value != null) {
ShortcutsManager.removeTunnelShortcuts(application, _tunnel.value!!)
}
var wgQuick = _tunnel.value?.wgQuick var wgQuick = _tunnel.value?.wgQuick
if(wgQuick != null) { if(wgQuick != null) {
wgQuick = if(_include.value) { wgQuick = if(_include.value) {
@ -135,6 +138,7 @@ class ConfigViewModel @Inject constructor(private val application : Application,
wgQuick = wgQuick wgQuick = wgQuick
)?.let { )?.let {
tunnelRepo.save(it) tunnelRepo.save(it)
ShortcutsManager.createTunnelShortcuts(application, it)
val settings = settingsRepo.getAll() val settings = settingsRepo.getAll()
if(settings != null) { if(settings != null) {
val setting = settings[0] val setting = settings[0]

View File

@ -249,7 +249,7 @@ fun MainScreen(
.fillMaxSize() .fillMaxSize()
.nestedScroll(nestedScrollConnection), .nestedScroll(nestedScrollConnection),
) { ) {
itemsIndexed(tunnels.toList()) { index, tunnel -> itemsIndexed(tunnels.toList()) { _, tunnel ->
val focusRequester = FocusRequester(); val focusRequester = FocusRequester();
RowListItem(leadingIcon = Icons.Rounded.Circle, RowListItem(leadingIcon = Icons.Rounded.Circle,
leadingIconColor = if (tunnelName == tunnel.name) when (handshakeStatus) { leadingIconColor = if (tunnelName == tunnel.name) when (handshakeStatus) {

View File

@ -96,8 +96,6 @@ fun SettingsScreen(
val settings by viewModel.settings.collectAsStateWithLifecycle() val settings by viewModel.settings.collectAsStateWithLifecycle()
val trustedSSIDs by viewModel.trustedSSIDs.collectAsStateWithLifecycle() val trustedSSIDs by viewModel.trustedSSIDs.collectAsStateWithLifecycle()
val tunnels by viewModel.tunnels.collectAsStateWithLifecycle(mutableListOf()) val tunnels by viewModel.tunnels.collectAsStateWithLifecycle(mutableListOf())
val backgroundLocationState =
rememberPermissionState(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
val fineLocationState = rememberPermissionState(Manifest.permission.ACCESS_FINE_LOCATION) val fineLocationState = rememberPermissionState(Manifest.permission.ACCESS_FINE_LOCATION)
var currentText by remember { mutableStateOf("") } var currentText by remember { mutableStateOf("") }
val scrollState = rememberScrollState() val scrollState = rememberScrollState()
@ -135,8 +133,10 @@ fun SettingsScreen(
context.startActivity(intentSettings) context.startActivity(intentSettings)
} }
} }
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if(!backgroundLocationState.status.isGranted && Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { val backgroundLocationState =
rememberPermissionState(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
if(!backgroundLocationState.status.isGranted) {
Column(horizontalAlignment = Alignment.CenterHorizontally, Column(horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top, verticalArrangement = Arrangement.Top,
modifier = Modifier modifier = Modifier
@ -171,6 +171,7 @@ fun SettingsScreen(
} }
return return
} }
}
if(!fineLocationState.status.isGranted) { if(!fineLocationState.status.isGranted) {
Column( Column(

View File

@ -1,20 +1,20 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
val objectBoxVersion by extra("3.5.1") val objectBoxVersion by extra("3.7.0")
val hiltVersion by extra("2.47") val hiltVersion by extra("2.48")
val accompanistVersion by extra("0.31.2-alpha") val accompanistVersion by extra("0.31.2-alpha")
dependencies { dependencies {
classpath("io.objectbox:objectbox-gradle-plugin:$objectBoxVersion") classpath("io.objectbox:objectbox-gradle-plugin:$objectBoxVersion")
classpath("com.google.gms:google-services:4.3.15") classpath("com.google.gms:google-services:4.3.15")
classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.7") classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.9")
} }
} }
plugins { plugins {
id("com.android.application") version "8.2.0-beta03" apply false id("com.android.application") version "8.2.0-beta03" apply false
id("org.jetbrains.kotlin.android") version "1.8.22" apply false id("org.jetbrains.kotlin.android") version "1.8.22" apply false
id("com.google.dagger.hilt.android") version "2.44" apply false id("com.google.dagger.hilt.android") version "2.48" apply false
kotlin("plugin.serialization") version "1.8.22" apply false kotlin("plugin.serialization") version "1.8.22" apply false
} }