summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson90@gmail.com>2023-11-23 15:18:43 +0100
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2023-11-27 12:11:33 +0100
commite1bf8a4e5891f067a2bc11fdabe2303d442fe354 (patch)
tree4999601064b9b1a82f752c7fbcc41ffa56bf6971 /android
parent2e41c80afb390a5f4e696f31a273a11417ffaefe (diff)
downloadmullvadvpn-e1bf8a4e5891f067a2bc11fdabe2303d442fe354.tar.xz
mullvadvpn-e1bf8a4e5891f067a2bc11fdabe2303d442fe354.zip
Fix crash with auto-connect and no permission
Diffstat (limited to 'android')
-rw-r--r--android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt24
-rw-r--r--android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/MullvadTileService.kt42
2 files changed, 61 insertions, 5 deletions
diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt
index b360613eaa..dad6ea5b56 100644
--- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt
+++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt
@@ -1,6 +1,9 @@
package net.mullvad.mullvadvpn.service
import android.app.Service
+import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED
+import android.net.VpnService
+import android.os.Build
import kotlin.properties.Delegates.observable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
@@ -90,11 +93,22 @@ class ForegroundNotificationManager(
}
fun showOnForeground() {
- service.startForeground(
- TunnelStateNotification.NOTIFICATION_ID,
- tunnelStateNotification.build()
- )
-
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ if (VpnService.prepare(service) == null) {
+ service.startForeground(
+ TunnelStateNotification.NOTIFICATION_ID,
+ tunnelStateNotification.build(),
+ FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED
+ )
+ } else {
+ return
+ }
+ } else {
+ service.startForeground(
+ TunnelStateNotification.NOTIFICATION_ID,
+ tunnelStateNotification.build(),
+ )
+ }
onForeground = true
}
diff --git a/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/MullvadTileService.kt b/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/MullvadTileService.kt
index 2a51c4e0e7..d8b1c85a6b 100644
--- a/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/MullvadTileService.kt
+++ b/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/MullvadTileService.kt
@@ -1,7 +1,11 @@
package net.mullvad.mullvadvpn.tile
+import android.annotation.SuppressLint
+import android.app.PendingIntent
import android.content.Intent
import android.graphics.drawable.Icon
+import android.net.VpnService
+import android.os.Build
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import android.util.Log
@@ -17,7 +21,9 @@ import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeoutOrNull
import net.mullvad.mullvadvpn.lib.common.constant.KEY_CONNECT_ACTION
import net.mullvad.mullvadvpn.lib.common.constant.KEY_DISCONNECT_ACTION
+import net.mullvad.mullvadvpn.lib.common.constant.MAIN_ACTIVITY_CLASS
import net.mullvad.mullvadvpn.lib.common.constant.VPN_SERVICE_CLASS
+import net.mullvad.mullvadvpn.lib.common.util.SdkUtils
import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.setSubtitleIfSupported
import net.mullvad.mullvadvpn.model.ServiceResult
import net.mullvad.mullvadvpn.model.TunnelState
@@ -74,7 +80,27 @@ class MullvadTileService : TileService() {
scope?.cancel()
}
+ @SuppressLint("StartActivityAndCollapseDeprecated")
private fun toggleTunnel() {
+ val isSetup = VpnService.prepare(applicationContext) == null
+ // TODO This logic should be more advanced, we should ensure user has an account setup etc.
+ if (!isSetup) {
+ Log.d("MullvadTileService", "VPN service not setup, starting main activity")
+
+ val intent =
+ Intent().apply {
+ setClassName(applicationContext.packageName, MAIN_ACTIVITY_CLASS)
+ flags =
+ Intent.FLAG_ACTIVITY_CLEAR_TOP or
+ Intent.FLAG_ACTIVITY_SINGLE_TOP or
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ action = Intent.ACTION_MAIN
+ }
+ startActivityAndCollapseCompat(intent)
+ return
+ } else {
+ Log.d("MullvadTileService", "VPN service is setup")
+ }
val intent =
Intent().apply {
setClassName(applicationContext.packageName, VPN_SERVICE_CLASS)
@@ -90,6 +116,22 @@ class MullvadTileService : TileService() {
startForegroundService(intent)
}
+ @SuppressLint("StartActivityAndCollapseDeprecated")
+ private fun MullvadTileService.startActivityAndCollapseCompat(intent: Intent) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ val pendingIntent =
+ PendingIntent.getActivity(
+ applicationContext,
+ 0,
+ intent,
+ SdkUtils.getSupportedPendingIntentFlags()
+ )
+ startActivityAndCollapse(pendingIntent)
+ } else {
+ startActivityAndCollapse(intent)
+ }
+ }
+
@OptIn(FlowPreview::class)
private fun CoroutineScope.launchListenToTunnelState() = launch {
ServiceConnection(this@MullvadTileService, this)