Compare commits

..

5 Commits

Author SHA1 Message Date
Zane Schepke feec7f0ffc chore: bump version 2025-06-17 15:43:46 -04:00
Zane Schepke b63c6a9b73 fix: simplify update check dialog ui 2025-06-17 15:34:24 -04:00
Zane Schepke 46975607c4 fix: version check name change 2025-06-17 14:04:00 -04:00
Zane Schepke 0c7bcb5453 fix: nightly version check 2025-06-14 16:59:40 -04:00
Zane Schepke 599bf9c9e0 fix: wifi name surrounding quotes, prevent multiple auto-tunnel jobs
#768
#797
2025-06-14 15:39:22 -04:00
12 changed files with 86 additions and 26 deletions
+1 -1
View File
@@ -123,7 +123,7 @@ android {
licensee {
Constants.allowedLicenses.forEach { allow(it) }
allowUrl(Constants.XZING_LICENSE_URL)
Constants.allowedLicenseUrls.forEach { allowUrl(it) }
}
applicationVariants.all {
@@ -73,6 +73,8 @@ class AutoTunnelService : LifecycleService() {
private val binder = LocalBinder(this)
private var isServiceRunning = false
override fun onCreate() {
super.onCreate()
launchWatcherNotification()
@@ -91,6 +93,8 @@ class AutoTunnelService : LifecycleService() {
}
fun start() {
if (isServiceRunning) return
isServiceRunning = true
kotlin
.runCatching {
launchWatcherNotification()
@@ -103,6 +107,7 @@ class AutoTunnelService : LifecycleService() {
}
fun stop() {
isServiceRunning = false
wakeLock?.let { if (it.isHeld) it.release() }
stopSelf()
}
@@ -5,11 +5,11 @@ import com.zaneschepke.wireguardautotunnel.domain.model.AppUpdate
import kotlin.collections.firstOrNull
object GitHubReleaseMapper {
fun toAppUpdate(gitHubRelease: GitHubRelease): AppUpdate {
fun toAppUpdate(gitHubRelease: GitHubRelease, newVersion: String): AppUpdate {
with(gitHubRelease) {
val apkAsset = assets.firstOrNull { it.name.endsWith(".apk") }
return AppUpdate(
version = tagName.removePrefix("v"),
version = newVersion,
title = name ?: "Update $tagName",
releaseNotes = body ?: "No release notes provided",
apkUrl = apkAsset?.browserDownloadUrl,
@@ -7,6 +7,7 @@ import com.zaneschepke.wireguardautotunnel.data.network.GitHubApi
import com.zaneschepke.wireguardautotunnel.di.IoDispatcher
import com.zaneschepke.wireguardautotunnel.domain.model.AppUpdate
import com.zaneschepke.wireguardautotunnel.domain.repository.UpdateRepository
import com.zaneschepke.wireguardautotunnel.util.Constants
import com.zaneschepke.wireguardautotunnel.util.NumberUtils
import io.ktor.client.HttpClient
import io.ktor.client.request.get
@@ -31,24 +32,30 @@ class GitHubUpdateRepository(
override suspend fun checkForUpdate(currentVersion: String): Result<AppUpdate?> =
withContext(ioDispatcher) {
Timber.i("Checking for update")
val isNightly = BuildConfig.VERSION_NAME.contains("nightly")
val release =
if (BuildConfig.VERSION_NAME.contains("nightly")) {
gitHubApi.getNightlyRelease(githubOwner, githubRepo)
if (isNightly) {
gitHubApi.getNightlyRelease(githubOwner, githubRepo).onFailure(Timber::e)
} else {
gitHubApi.getLatestRelease(githubOwner, githubRepo)
gitHubApi.getLatestRelease(githubOwner, githubRepo).onFailure(Timber::e)
}
release.map { release ->
val apkAsset =
release.assets.find { asset ->
asset.name.startsWith("wgtunnel-full-v") && asset.name.endsWith(".apk")
asset.name.startsWith("wgtunnel-${Constants.STANDALONE_FLAVOR}-v") &&
asset.name.endsWith(".apk")
}
val newVersion =
apkAsset?.name?.removePrefix("wgtunnel-full-v")?.removeSuffix(".apk")
?: return@map null
apkAsset
?.name
?.removePrefix("wgtunnel-${Constants.STANDALONE_FLAVOR}-v")
?.removeSuffix(".apk") ?: return@map null
Timber.i("Latest version: $newVersion, current version: $currentVersion")
if (isNightly && newVersion != currentVersion)
return@map GitHubReleaseMapper.toAppUpdate(release, newVersion)
if (NumberUtils.compareVersions(newVersion, currentVersion) > 0) {
GitHubReleaseMapper.toAppUpdate(release)
GitHubReleaseMapper.toAppUpdate(release, newVersion)
} else {
null
}
@@ -12,6 +12,12 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withLink
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -72,8 +78,41 @@ fun SupportScreen(viewModel: SupportViewModel = hiltViewModel(), appViewModel: A
verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.Top),
modifier = Modifier.fillMaxWidth(),
) {
Text(uiState.appUpdate?.version ?: "")
Text(uiState.appUpdate?.releaseNotes ?: "")
val annotatedString = buildAnnotatedString {
append("${uiState.appUpdate?.version ?: ""}\n")
// Add clickable text for second line
withLink(
link =
LinkAnnotation.Clickable(
tag = stringResource(id = R.string.release_notes),
linkInteractionListener = {
val version =
if (BuildConfig.VERSION_NAME.contains("nightly")) {
"nightly"
} else {
uiState.appUpdate
?.version
?.removePrefix("v")
?.trim() ?: ""
}
val url = "${Constants.BASE_RELEASE_URL}$version".trim()
context.openWebUrl(url)
},
styles =
TextLinkStyles(
style =
SpanStyle(
color = MaterialTheme.colorScheme.primary,
textDecoration = TextDecoration.Underline,
)
),
)
) {
append(stringResource(R.string.release_notes))
}
}
Text(text = annotatedString)
if (uiState.isLoading) {
LinearProgressIndicator(
progress = { uiState.downloadProgress },
@@ -38,4 +38,6 @@ object Constants {
const val GOOGLE_PLAY_FLAVOR = "google"
const val STANDALONE_FLAVOR = "standalone"
const val RELEASE = "release"
const val BASE_RELEASE_URL = "https://github.com/wgtunnel/wgtunnel/releases/tag/"
}
+1
View File
@@ -279,4 +279,5 @@
<string name="use_android_recommended">Use Android\'s recommended method for getting Wi-Fi information, based on
Android version
</string>
<string name="release_notes">Release notes</string>
</resources>
+3 -3
View File
@@ -1,7 +1,7 @@
object Constants {
const val VERSION_NAME = "3.9.2"
const val VERSION_NAME = "3.9.3"
const val JVM_TARGET = "17"
const val VERSION_CODE = 39200
const val VERSION_CODE = 39300
const val TARGET_SDK = 35
const val MIN_SDK = 26
const val APP_ID = "com.zaneschepke.wireguardautotunnel"
@@ -13,5 +13,5 @@ object Constants {
const val PRERELEASE = "prerelease"
val allowedLicenses = listOf("MIT", "Apache-2.0", "BSD-3-Clause")
const val XZING_LICENSE_URL: String = "https://github.com/journeyapps/zxing-android-embedded/blob/master/COPYING"
val allowedLicenseUrls = listOf("https://github.com/journeyapps/zxing-android-embedded/blob/master/COPYING")
}
@@ -0,0 +1,4 @@
What's new:
- Fixes deprecate location API bug by adding Wi-Fi info method selection
- Simplified update check dialog UI
- Improve auto-tunnel reliability with delayed recheck
+1 -1
View File
@@ -13,7 +13,7 @@ hiltAndroid = "2.56.2"
hiltCompiler = "1.2.0"
junit = "4.13.2"
kotlinx-serialization-json = "1.8.1"
ktorClientCore = "3.2.0"
ktorClientCore = "3.1.3"
lifecycle-runtime-compose = "2.9.1"
material3 = "1.3.2"
navigationCompose = "2.9.0"
@@ -181,8 +181,16 @@ class AndroidNetworkMonitor(context: Context, val wifiDetectionMethod: WifiDetec
activeWifiNetworks.add(network.toString())
currentSsid =
when (wifiDetectionMethod) {
WifiDetectionMethod.DEFAULT ->
networkCapabilities?.getWifiSsid() ?: getWifiSsid()
WifiDetectionMethod.DEFAULT -> {
if (networkCapabilities == null) {
Timber.d("Capabilities not available, getting SSID via legacy API")
getWifiSsid()
} else
networkCapabilities.getWifiSsid().also {
Timber.d("Got SSID from capabilities")
}
}
WifiDetectionMethod.LEGACY -> getWifiSsid()
WifiDetectionMethod.ROOT -> rootShell.getCurrentWifiName()
// TODO implement Shizuku
@@ -212,18 +220,12 @@ class AndroidNetworkMonitor(context: Context, val wifiDetectionMethod: WifiDetec
}
else ->
object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
private var netCapabilities: NetworkCapabilities? = null
override fun onAvailable(network: Network) {
Timber.i("Wi-Fi change detected using new API")
launch { handleOnWifiAvailable(network, netCapabilities) }
}
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities,
) {
launch { wifiMutex.withLock { netCapabilities = networkCapabilities } }
launch { handleOnWifiAvailable(network, networkCapabilities) }
}
override fun onLost(network: Network) {
@@ -29,7 +29,7 @@ fun NetworkCapabilities.getWifiSsid(): String? {
val info: WifiInfo
if (transportInfo is WifiInfo) {
info = transportInfo as WifiInfo
return info.ssid
return info.ssid.removeSurrounding("\"").trim()
}
}
return null