diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2019-09-13 12:22:00 +0000 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2019-09-13 13:35:09 +0000 |
| commit | 1b0a13d86f70f660c04e5ee8cbd3124f65a97697 (patch) | |
| tree | fdc5210107e4d520060685e755a96d02ef0aa3a4 /android/src | |
| parent | 20ff6e405e74facc34bcd9029c3a44041e98409b (diff) | |
| download | mullvadvpn-1b0a13d86f70f660c04e5ee8cbd3124f65a97697.tar.xz mullvadvpn-1b0a13d86f70f660c04e5ee8cbd3124f65a97697.zip | |
Add tunnel action button to notification
Diffstat (limited to 'android/src')
3 files changed, 156 insertions, 2 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ForegroundNotificationManager.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ForegroundNotificationManager.kt index f607b0cf2f..f42a48ce8d 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ForegroundNotificationManager.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ForegroundNotificationManager.kt @@ -5,8 +5,10 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.app.Service +import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import android.content.IntentFilter import android.os.Build import android.support.v4.app.NotificationCompat @@ -16,6 +18,9 @@ import net.mullvad.mullvadvpn.model.TunnelState val CHANNEL_ID = "vpn_tunnel_status" val FOREGROUND_NOTIFICATION_ID: Int = 1 +val KEY_CONNECT_ACTION = "connect_action" +val KEY_DISCONNECT_ACTION = "disconnect_action" +val PERMISSION_TUNNEL_ACTION = "net.mullvad.mullvadvpn.permission.TUNNEL_ACTION" class ForegroundNotificationManager(val service: Service, val connectionProxy: ConnectionProxy) { private val notificationManager = @@ -64,12 +69,80 @@ class ForegroundNotificationManager(val service: Service, val connectionProxy: C } } + private val tunnelActionText: Int + get() { + val state = tunnelState + + return when (state) { + is TunnelState.Disconnected -> R.string.connect + is TunnelState.Connecting -> R.string.cancel + is TunnelState.Connected -> R.string.disconnect + is TunnelState.Disconnecting -> { + when (state.actionAfterDisconnect) { + is ActionAfterDisconnect.Reconnect -> R.string.cancel + else -> R.string.connect + } + } + is TunnelState.Blocked -> R.string.disconnect + } + } + + private val tunnelActionKey: String + get() { + val state = tunnelState + + return when (state) { + is TunnelState.Disconnected -> KEY_CONNECT_ACTION + is TunnelState.Connecting -> KEY_DISCONNECT_ACTION + is TunnelState.Connected -> KEY_DISCONNECT_ACTION + is TunnelState.Disconnecting -> { + when (state.actionAfterDisconnect) { + is ActionAfterDisconnect.Reconnect -> KEY_DISCONNECT_ACTION + else -> KEY_CONNECT_ACTION + } + } + is TunnelState.Blocked -> KEY_DISCONNECT_ACTION + } + } + + private val tunnelActionIcon: Int + get() { + if (tunnelActionKey == KEY_CONNECT_ACTION) { + return R.drawable.icon_notification_connect + } else { + return R.drawable.icon_notification_disconnect + } + } + + private val connectReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + onConnect?.invoke() + } + } + + private val disconnectReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + onDisconnect?.invoke() + } + } + + var onConnect: (() -> Unit)? = null + var onDisconnect: (() -> Unit)? = null + init { if (Build.VERSION.SDK_INT >= 26) { initChannel() } - service.startForeground(FOREGROUND_NOTIFICATION_ID, buildNotification()) + service.apply { + val connectFilter = IntentFilter(KEY_CONNECT_ACTION) + val disconnectFilter = IntentFilter(KEY_DISCONNECT_ACTION) + + registerReceiver(connectReceiver, connectFilter, PERMISSION_TUNNEL_ACTION, null) + registerReceiver(disconnectReceiver, disconnectFilter, PERMISSION_TUNNEL_ACTION, null) + + startForeground(FOREGROUND_NOTIFICATION_ID, buildNotification()) + } } fun onDestroy() { @@ -77,7 +150,12 @@ class ForegroundNotificationManager(val service: Service, val connectionProxy: C connectionProxy.onUiStateChange.unsubscribe(listener) } - service.stopForeground(FOREGROUND_NOTIFICATION_ID) + service.apply { + unregisterReceiver(connectReceiver) + unregisterReceiver(disconnectReceiver) + + stopForeground(FOREGROUND_NOTIFICATION_ID) + } } private fun initChannel() { @@ -110,6 +188,18 @@ class ForegroundNotificationManager(val service: Service, val connectionProxy: C .setColor(service.getColor(R.color.colorPrimary)) .setContentTitle(service.getString(notificationText)) .setContentIntent(pendingIntent) + .addAction(buildTunnelAction()) .build() } + + private fun buildTunnelAction(): NotificationCompat.Action { + val intent = Intent(tunnelActionKey).setPackage("net.mullvad.mullvadvpn") + val pendingIntent = + PendingIntent.getBroadcast(service, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT) + + val icon = tunnelActionIcon + val label = service.getString(tunnelActionText) + + return NotificationCompat.Action(icon, label, pendingIntent) + } } diff --git a/android/src/main/res/drawable/icon_notification_connect.xml b/android/src/main/res/drawable/icon_notification_connect.xml new file mode 100644 index 0000000000..22e23ed1ad --- /dev/null +++ b/android/src/main/res/drawable/icon_notification_connect.xml @@ -0,0 +1,33 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="#000000" + android:fillType="evenOdd" + android:pathData=" + M -4,-1 + v -6 + a 1,1 0 0,1 1,-1 + h 6 + a 1,1 0 0,1 1,1 + v 6 + h 1 + a 1,1 0 0,1 1,1 + v 7 + a 1,1 0 0,1 -1,1 + h -10 + a 1,1 0 0,1 -1,-1 + v -7 + a 1,1 0 0,1 1,-1 + z + M -2,-1 + v -5 + h 4 + v 5 + z + " + /> +</vector> diff --git a/android/src/main/res/drawable/icon_notification_disconnect.xml b/android/src/main/res/drawable/icon_notification_disconnect.xml new file mode 100644 index 0000000000..d7d1a0cfbd --- /dev/null +++ b/android/src/main/res/drawable/icon_notification_disconnect.xml @@ -0,0 +1,31 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="#000000" + android:pathData=" + M 0,-1 + v -6 + a 1,1 0 0,1 1,-1 + h 6 + a 1,1 0 0,1 1,1 + v 6 + a 1,1 0 0,1 -2,0 + v -5 + h -4 + v 5 + h 1 + a 1,1 0 0,1 1,1 + v 7 + a 1,1 0 0,1 -1,1 + h -10 + a 1,1 0 0,1 -1,-1 + v -7 + a 1,1 0 0,1 1,-1 + z + " + /> +</vector> |
