diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2020-06-08 16:51:14 +0000 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2020-06-17 14:15:15 +0000 |
| commit | 35128b3c7b225a4ddfa2e54d79d9f1f99958b669 (patch) | |
| tree | 751fd0b4d0de69b0c32cf4ac46340ca8149bf6e0 /android/src | |
| parent | 3a45a4830d60f9bccf0b8c22d0cae22f207fe34e (diff) | |
| download | mullvadvpn-35128b3c7b225a4ddfa2e54d79d9f1f99958b669.tar.xz mullvadvpn-35128b3c7b225a4ddfa2e54d79d9f1f99958b669.zip | |
Create `TunnelStateNotification` class
Diffstat (limited to 'android/src')
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt new file mode 100644 index 0000000000..e91908f088 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt @@ -0,0 +1,115 @@ +package net.mullvad.mullvadvpn.service.notifications + +import android.app.Notification +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Build +import android.support.v4.app.NotificationCompat +import kotlin.properties.Delegates.observable +import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.model.TunnelState +import net.mullvad.mullvadvpn.ui.MainActivity +import net.mullvad.talpid.tunnel.ActionAfterDisconnect + +class TunnelStateNotification(val context: Context) { + companion object { + val NOTIFICATION_ID: Int = 1 + } + + private val channel = NotificationChannel( + context, + "vpn_tunnel_status", + R.string.foreground_notification_channel_name, + R.string.foreground_notification_channel_description, + NotificationManager.IMPORTANCE_MIN + ) + + private val notificationText: Int + get() = when (val state = tunnelState) { + is TunnelState.Disconnected -> R.string.unsecured + is TunnelState.Connecting -> { + if (reconnecting) { + R.string.reconnecting + } else { + R.string.connecting + } + } + is TunnelState.Connected -> R.string.secured + is TunnelState.Disconnecting -> { + when (state.actionAfterDisconnect) { + ActionAfterDisconnect.Reconnect -> R.string.reconnecting + else -> R.string.disconnecting + } + } + is TunnelState.Error -> { + if (state.errorState.isBlocking) { + R.string.blocking_all_connections + } else { + R.string.critical_error + } + } + } + + private var reconnecting = false + private var showingReconnecting = false + + var showAction by observable(false) { _, _, _ -> update() } + + var tunnelState by observable<TunnelState>(TunnelState.Disconnected()) { _, _, newState -> + reconnecting = + (newState is TunnelState.Disconnecting && + newState.actionAfterDisconnect == ActionAfterDisconnect.Reconnect) || + (newState is TunnelState.Connecting && reconnecting) + + update() + } + + var visible by observable(true) { _, _, newValue -> + if (newValue == true) { + update() + } else { + channel.notificationManager.cancel(NOTIFICATION_ID) + } + } + + private fun update() { + if (visible && (!reconnecting || !showingReconnecting)) { + channel.notificationManager.notify(NOTIFICATION_ID, build()) + } + } + + fun build(): Notification { + val intent = Intent(context, MainActivity::class.java) + .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) + .setAction(Intent.ACTION_MAIN) + + val pendingIntent = + PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT) + + val actions = if (showAction) { + listOf(buildAction()) + } else { + emptyList() + } + + return channel.buildNotification(pendingIntent, notificationText, actions) + } + + private fun buildAction(): NotificationCompat.Action { + val action = TunnelStateNotificationAction.from(tunnelState) + val label = context.getString(action.text) + + val intent = Intent(action.key).setPackage("net.mullvad.mullvadvpn") + val flags = PendingIntent.FLAG_UPDATE_CURRENT + + val pendingIntent = if (Build.VERSION.SDK_INT >= 26) { + PendingIntent.getForegroundService(context, 1, intent, flags) + } else { + PendingIntent.getService(context, 1, intent, flags) + } + + return NotificationCompat.Action(action.icon, label, pendingIntent) + } +} |
