add tunnel notification

This commit is contained in:
Zane Schepke 2024-12-09 22:20:14 -05:00
parent f047a1e1b8
commit 99f6b438ab
3 changed files with 31 additions and 15 deletions

View File

@ -2,10 +2,12 @@ package com.zaneschepke.wireguardautotunnel.service.notification
import android.app.Notification import android.app.Notification
import android.app.NotificationManager import android.app.NotificationManager
import android.content.Context
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import com.zaneschepke.wireguardautotunnel.service.notification.WireGuardNotification.NotificationChannels import com.zaneschepke.wireguardautotunnel.service.notification.WireGuardNotification.NotificationChannels
interface NotificationService { interface NotificationService {
val context: Context
fun createNotification( fun createNotification(
channel: NotificationChannels, channel: NotificationChannels,
title: String = "", title: String = "",
@ -19,8 +21,13 @@ interface NotificationService {
fun createNotificationAction(action: NotificationAction): NotificationCompat.Action fun createNotificationAction(action: NotificationAction): NotificationCompat.Action
fun remove(notificationId: Int)
fun show(notificationId: Int, notification: Notification)
companion object { companion object {
const val KERNEL_SERVICE_NOTIFICATION_ID = 123 const val KERNEL_SERVICE_NOTIFICATION_ID = 123
const val AUTO_TUNNEL_NOTIFICATION_ID = 122 const val AUTO_TUNNEL_NOTIFICATION_ID = 122
const val VPN_NOTIFICATION_ID = 100
} }
} }

View File

@ -20,7 +20,7 @@ import javax.inject.Inject
class WireGuardNotification class WireGuardNotification
@Inject @Inject
constructor( constructor(
@ApplicationContext private val context: Context, @ApplicationContext override val context: Context,
) : NotificationService { ) : NotificationService {
enum class NotificationChannels { enum class NotificationChannels {
@ -28,8 +28,7 @@ constructor(
AUTO_TUNNEL, AUTO_TUNNEL,
} }
private val notificationManager = private val notificationManager = NotificationManagerCompat.from(context)
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
override fun createNotification( override fun createNotification(
channel: NotificationChannels, channel: NotificationChannels,
@ -72,9 +71,12 @@ constructor(
).build() ).build()
} }
fun Notification.show(notificationId: Int = defaultId()) { override fun remove(notificationId: Int) {
val notification = this notificationManager.cancel(notificationId)
with(NotificationManagerCompat.from(context)) { }
override fun show(notificationId: Int, notification: Notification) {
with(notificationManager) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
return return
} }
@ -82,14 +84,6 @@ constructor(
} }
} }
fun Notification.defaultId(): Int {
return when (this.channelId) {
context.getString(R.string.vpn_channel_id) -> 100
context.getString(R.string.auto_tunnel_channel_id) -> 101
else -> 102
}
}
fun NotificationChannels.asBuilder(): NotificationCompat.Builder { fun NotificationChannels.asBuilder(): NotificationCompat.Builder {
return when (this) { return when (this) {
NotificationChannels.VPN -> { NotificationChannels.VPN -> {

View File

@ -10,6 +10,7 @@ import com.zaneschepke.wireguardautotunnel.module.IoDispatcher
import com.zaneschepke.wireguardautotunnel.module.Kernel import com.zaneschepke.wireguardautotunnel.module.Kernel
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
import com.zaneschepke.wireguardautotunnel.service.notification.NotificationService import com.zaneschepke.wireguardautotunnel.service.notification.NotificationService
import com.zaneschepke.wireguardautotunnel.service.notification.WireGuardNotification
import com.zaneschepke.wireguardautotunnel.service.tunnel.statistics.AmneziaStatistics import com.zaneschepke.wireguardautotunnel.service.tunnel.statistics.AmneziaStatistics
import com.zaneschepke.wireguardautotunnel.service.tunnel.statistics.TunnelStatistics import com.zaneschepke.wireguardautotunnel.service.tunnel.statistics.TunnelStatistics
import com.zaneschepke.wireguardautotunnel.service.tunnel.statistics.WireGuardStatistics import com.zaneschepke.wireguardautotunnel.service.tunnel.statistics.WireGuardStatistics
@ -28,6 +29,9 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.amnezia.awg.backend.Tunnel import org.amnezia.awg.backend.Tunnel
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.service.notification.NotificationAction
import com.zaneschepke.wireguardautotunnel.service.notification.NotificationService.Companion.VPN_NOTIFICATION_ID
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Provider import javax.inject.Provider
@ -118,6 +122,16 @@ constructor(
setState(tunnelConfig, TunnelState.UP).onSuccess { setState(tunnelConfig, TunnelState.UP).onSuccess {
startActiveTunnelJobs() startActiveTunnelJobs()
if (it.isUp()) appDataRepository.tunnels.save(tunnelConfig.copy(isActive = true)) if (it.isUp()) appDataRepository.tunnels.save(tunnelConfig.copy(isActive = true))
with(notificationService) {
val notification = createNotification(
WireGuardNotification.NotificationChannels.VPN,
title = "${context.getString(R.string.tunnel_running)} - ${tunnelConfig.name}",
actions = listOf(
notificationService.createNotificationAction(NotificationAction.TUNNEL_OFF),
),
)
show(VPN_NOTIFICATION_ID, notification)
}
updateTunnelState(it, tunnelConfig) updateTunnelState(it, tunnelConfig)
} }
}.onFailure { }.onFailure {
@ -136,6 +150,7 @@ constructor(
setState(tunnelConfig, TunnelState.DOWN).onSuccess { setState(tunnelConfig, TunnelState.DOWN).onSuccess {
updateTunnelState(it, null) updateTunnelState(it, null)
onStop(tunnelConfig) onStop(tunnelConfig)
notificationService.remove(VPN_NOTIFICATION_ID)
stopBackgroundService() stopBackgroundService()
}.onFailure { }.onFailure {
Timber.e(it) Timber.e(it)
@ -214,7 +229,7 @@ constructor(
serviceManager.updateTunnelTile() serviceManager.updateTunnelTile()
} }
private suspend fun stopBackgroundService() { private fun stopBackgroundService() {
serviceManager.stopBackgroundService() serviceManager.stopBackgroundService()
serviceManager.updateTunnelTile() serviceManager.updateTunnelTile()
} }