Skip to content

Commit 907bc41

Browse files
authored
Add fallback for ForegroundServiceStartNotAllowedException in Android 31+ (#6808)
Task/Issue URL: https://app.asana.com/1/137249556945/project/1202552961248957/task/1206535923706701?focus=true ### Description Work around platform bug ([b/229000935](https://issuetracker.google.com/issues/229000935)) where startForegroundService() for VpnService can throw ForegroundServiceStartNotAllowedException when called from background. We now catch this and fall back to startService(), which is allowed for VPNs. Service still promotes itself to foreground as usual. ### Steps to test this PR Smoke test AppTP and VPN on off scenarios for Android on 31+ and below 31
1 parent 4c17cd8 commit 907bc41

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/service/TrackerBlockingVpnService.kt

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package com.duckduckgo.mobile.android.vpn.service
1818

1919
import android.annotation.SuppressLint
2020
import android.app.ActivityManager
21+
import android.app.ForegroundServiceStartNotAllowedException
2122
import android.app.Service
2223
import android.content.ComponentName
2324
import android.content.Context
@@ -815,7 +816,7 @@ class TrackerBlockingVpnService : VpnService(), CoroutineScope by MainScope(), V
815816
if (!isServiceRunning(appContext)) return
816817

817818
snoozeIntent(appContext, triggerAtMillis).run {
818-
ContextCompat.startForegroundService(appContext, this)
819+
appContext.startForegroundServiceWithFallback(this)
819820
}
820821
}
821822

@@ -842,7 +843,7 @@ class TrackerBlockingVpnService : VpnService(), CoroutineScope by MainScope(), V
842843
if (isServiceRunning(applicationContext)) return
843844

844845
startIntent(applicationContext).run {
845-
ContextCompat.startForegroundService(applicationContext, this)
846+
applicationContext.startForegroundServiceWithFallback(this)
846847
}
847848
}
848849

@@ -852,15 +853,15 @@ class TrackerBlockingVpnService : VpnService(), CoroutineScope by MainScope(), V
852853
if (!isServiceRunning(applicationContext)) return
853854

854855
stopIntent(applicationContext).run {
855-
ContextCompat.startForegroundService(applicationContext, this)
856+
applicationContext.startForegroundServiceWithFallback(this)
856857
}
857858
}
858859

859860
private fun restartService(context: Context) {
860861
val applicationContext = context.applicationContext
861862

862863
restartIntent(applicationContext).run {
863-
ContextCompat.startForegroundService(applicationContext, this)
864+
applicationContext.startForegroundServiceWithFallback(this)
864865
}
865866
}
866867

@@ -883,6 +884,23 @@ class TrackerBlockingVpnService : VpnService(), CoroutineScope by MainScope(), V
883884
}
884885
}
885886

887+
@SuppressLint("DenyListedApi") // static private method
888+
private fun Context.startForegroundServiceWithFallback(intent: Intent) {
889+
try {
890+
ContextCompat.startForegroundService(this, intent)
891+
} catch (ex: ForegroundServiceStartNotAllowedException) {
892+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
893+
try {
894+
this.startService(intent)
895+
} catch (_: Throwable) {
896+
// no-op
897+
}
898+
} else {
899+
throw ex
900+
}
901+
}
902+
}
903+
886904
private const val ACTION_START_VPN = "ACTION_START_VPN"
887905
private const val ACTION_STOP_VPN = "ACTION_STOP_VPN"
888906
private const val ACTION_RESTART_VPN = "ACTION_RESTART_VPN"

0 commit comments

Comments
 (0)