fix: fix disable foreground notification dismiss for watcher service

This fixes foreground notification that was allowed to be dismissed which causes the service to eventually be killed.

Also fixes notification conflict bug where notification messages were not created separate notifications for different services.
This commit is contained in:
Zane Schepke 2023-06-30 01:51:17 -04:00
parent 005afc7089
commit f894a3e0c9
8 changed files with 53 additions and 17 deletions

View File

@ -17,7 +17,7 @@ android {
val versionMajor = 1 val versionMajor = 1
val versionMinor = 1 val versionMinor = 1
val versionPatch = 2 val versionPatch = 3
val versionBuild = 0 val versionBuild = 0
defaultConfig { defaultConfig {

View File

@ -29,6 +29,8 @@ import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class WireGuardConnectivityWatcherService : ForegroundService() { class WireGuardConnectivityWatcherService : ForegroundService() {
private val foregroundId = 122;
@Inject @Inject
lateinit var wifiService : NetworkService<WifiService> lateinit var wifiService : NetworkService<WifiService>
@ -66,7 +68,7 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
// we need this lock so our service gets not affected by Doze Mode // we need this lock so our service gets not affected by Doze Mode
initWakeLock() initWakeLock()
cancelWatcherJob() cancelWatcherJob()
startWatcherNotification() launchWatcherNotification()
if(this::tunnelId.isInitialized) { if(this::tunnelId.isInitialized) {
startWatcherJob() startWatcherJob()
} else { } else {
@ -86,13 +88,12 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
stopSelf() stopSelf()
} }
private fun startWatcherNotification() { private fun launchWatcherNotification() {
val notification = notificationService.createNotification( val notification = notificationService.createNotification(
channelId = getString(R.string.watcher_channel_id), channelId = getString(R.string.watcher_channel_id),
channelName = getString(R.string.watcher_channel_name), channelName = getString(R.string.watcher_channel_name),
title = getString(R.string.watcher_notification_title),
description = getString(R.string.watcher_notification_text)) description = getString(R.string.watcher_notification_text))
super.startForeground(1, notification) super.startForeground(foregroundId, notification)
} }
//try to start task again if killed //try to start task again if killed

View File

@ -19,6 +19,8 @@ import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class WireGuardTunnelService : ForegroundService() { class WireGuardTunnelService : ForegroundService() {
private val foregroundId = 123;
@Inject @Inject
lateinit var vpnService : VpnService lateinit var vpnService : VpnService
@ -64,9 +66,11 @@ class WireGuardTunnelService : ForegroundService() {
channelId = getString(R.string.vpn_channel_id), channelId = getString(R.string.vpn_channel_id),
channelName = getString(R.string.vpn_channel_name), channelName = getString(R.string.vpn_channel_name),
title = getString(R.string.tunnel_start_title), title = getString(R.string.tunnel_start_title),
onGoing = false,
showTimestamp = true,
description = "${getString(R.string.tunnel_start_text)} $tunnelName" description = "${getString(R.string.tunnel_start_text)} $tunnelName"
) )
super.startForeground(1, notification) super.startForeground(foregroundId, notification)
} }
private fun cancelJob() { private fun cancelJob() {
if(this::job.isInitialized) { if(this::job.isInitialized) {

View File

@ -7,10 +7,12 @@ interface NotificationService {
fun createNotification( fun createNotification(
channelId: String, channelId: String,
channelName: String, channelName: String,
title: String, title: String = "",
description: String, description: String,
showTimestamp : Boolean = false,
importance: Int = NotificationManager.IMPORTANCE_HIGH, importance: Int = NotificationManager.IMPORTANCE_HIGH,
vibration: Boolean = true, vibration: Boolean = true,
onGoing: Boolean = true,
lights: Boolean = true lights: Boolean = true
): Notification ): Notification
} }

View File

@ -21,8 +21,10 @@ class WireGuardNotification @Inject constructor(@ApplicationContext private val
channelName: String, channelName: String,
title: String, title: String,
description: String, description: String,
showTimestamp: Boolean,
importance: Int, importance: Int,
vibration: Boolean, vibration: Boolean,
onGoing: Boolean,
lights: Boolean lights: Boolean
) : Notification { ) : Notification {
val channel = NotificationChannel( val channel = NotificationChannel(
@ -53,7 +55,8 @@ class WireGuardNotification @Inject constructor(@ApplicationContext private val
.setContentTitle(title) .setContentTitle(title)
.setContentText(description) .setContentText(description)
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
.setShowWhen(true) .setOngoing(onGoing)
.setShowWhen(showTimestamp)
.setSmallIcon(R.mipmap.ic_launcher_foreground) .setSmallIcon(R.mipmap.ic_launcher_foreground)
.build() .build()
} }

View File

@ -20,6 +20,10 @@ import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.AddCircleOutline
import androidx.compose.material.icons.outlined.Done
import androidx.compose.material.icons.rounded.LocationOff import androidx.compose.material.icons.rounded.LocationOff
import androidx.compose.material.icons.rounded.Map import androidx.compose.material.icons.rounded.Map
import androidx.compose.material3.Button import androidx.compose.material3.Button
@ -28,6 +32,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarHostState
@ -44,6 +49,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
@ -100,13 +106,25 @@ fun SettingsScreen(
} }
} }
} }
fun saveTrustedSSID() {
if (currentText.isNotEmpty()) {
scope.launch {
viewModel.onSaveTrustedSSID(currentText)
currentText = ""
}
}
}
if(!backgroundLocationState.status.isGranted) { if(!backgroundLocationState.status.isGranted) {
Column(horizontalAlignment = Alignment.CenterHorizontally, Column(horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top, verticalArrangement = Arrangement.Top,
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(padding)) { .padding(padding)) {
Icon(Icons.Rounded.LocationOff, contentDescription = "Map", modifier = Modifier.padding(30.dp).size(128.dp)) Icon(Icons.Rounded.LocationOff, contentDescription = "Map", modifier = Modifier
.padding(30.dp)
.size(128.dp))
Text(stringResource(R.string.prominent_background_location_title), textAlign = TextAlign.Center, modifier = Modifier.padding(30.dp), fontSize = 20.sp) Text(stringResource(R.string.prominent_background_location_title), textAlign = TextAlign.Center, modifier = Modifier.padding(30.dp), fontSize = 20.sp)
Text(stringResource(R.string.prominent_background_location_message), textAlign = TextAlign.Center, modifier = Modifier.padding(30.dp), fontSize = 15.sp) Text(stringResource(R.string.prominent_background_location_message), textAlign = TextAlign.Center, modifier = Modifier.padding(30.dp), fontSize = 15.sp)
//Spacer(modifier = Modifier.weight(1f)) //Spacer(modifier = Modifier.weight(1f))
@ -257,14 +275,20 @@ fun SettingsScreen(
), ),
keyboardActions = KeyboardActions( keyboardActions = KeyboardActions(
onDone = { onDone = {
scope.launch { saveTrustedSSID()
if (currentText.isNotEmpty()) {
viewModel.onSaveTrustedSSID(currentText)
currentText = ""
}
}
} }
), ),
trailingIcon = {
IconButton(onClick = { saveTrustedSSID() }) {
Icon(
imageVector = Icons.Outlined.Add,
contentDescription = if (currentText == "") stringResource(id = R.string.trusted_ssid_empty_description) else stringResource(
id = R.string.trusted_ssid_value_description
),
tint = if(currentText == "") Color.Transparent else Color.Green
)
}
},
) )
Row( Row(
modifier = Modifier modifier = Modifier

View File

@ -14,7 +14,7 @@
<string name="tunnel_exists">Tunnel name already exists</string> <string name="tunnel_exists">Tunnel name already exists</string>
<string name="discord_url">https://discord.gg/Ad5fuEts</string> <string name="discord_url">https://discord.gg/Ad5fuEts</string>
<string name="watcher_notification_title">Watcher Service</string> <string name="watcher_notification_title">Watcher Service</string>
<string name="watcher_notification_text">Now watching for Wi-Fi state changes</string> <string name="watcher_notification_text">Monitoring network state changes</string>
<string name="tunnel_start_title">VPN Connected</string> <string name="tunnel_start_title">VPN Connected</string>
<string name="tunnel_start_text">Connected to tunnel -</string> <string name="tunnel_start_text">Connected to tunnel -</string>
<string name="vpn_permission_required">VPN permission is required for the app to work properly.</string> <string name="vpn_permission_required">VPN permission is required for the app to work properly.</string>
@ -35,4 +35,6 @@
<string name="prominent_background_location_message">This feature requires background location permission to enable Wi-Fi SSID monitoring even while the application is closed. For more details, please see the Privacy Policy linked on the Support screen.</string> <string name="prominent_background_location_message">This feature requires background location permission to enable Wi-Fi SSID monitoring even while the application is closed. For more details, please see the Privacy Policy linked on the Support screen.</string>
<string name="prominent_background_location_title">Background Location Disclosure</string> <string name="prominent_background_location_title">Background Location Disclosure</string>
<string name="support_text">Thank you for using WG Tunnel! If you are experiencing issues with the app, please reach out on Discord or create an issue on Github. I will try to address the issue as quickly as possible. Thank you!</string> <string name="support_text">Thank you for using WG Tunnel! If you are experiencing issues with the app, please reach out on Discord or create an issue on Github. I will try to address the issue as quickly as possible. Thank you!</string>
<string name="trusted_ssid_empty_description">Enter SSID</string>
<string name="trusted_ssid_value_description">Submit SSID</string>
</resources> </resources>

View File

@ -13,7 +13,7 @@ buildscript {
} }
plugins { plugins {
id("com.android.application") version "8.2.0-alpha07" apply false id("com.android.application") version "8.2.0-alpha08" apply false
id("org.jetbrains.kotlin.android") version "1.8.21" apply false id("org.jetbrains.kotlin.android") version "1.8.21" apply false
id("com.google.dagger.hilt.android") version "2.44" apply false id("com.google.dagger.hilt.android") version "2.44" apply false
kotlin("plugin.serialization") version "1.8.21" apply false kotlin("plugin.serialization") version "1.8.21" apply false