diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f1ece04bba..e30c8c7137 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1352,7 +1352,11 @@
-
+
+
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/SafeForegroundService.kt b/app/src/main/java/org/thoughtcrime/securesms/service/SafeForegroundService.kt
index 004beadc25..0f4c624ffc 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/SafeForegroundService.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/SafeForegroundService.kt
@@ -9,8 +9,10 @@ import android.app.Notification
import android.app.Service
import android.content.Context
import android.content.Intent
+import android.os.Build
import android.os.Bundle
import android.os.IBinder
+import androidx.annotation.RequiresApi
import androidx.core.app.ServiceCompat
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.jobs.ForegroundServiceUtil
@@ -122,6 +124,10 @@ abstract class SafeForegroundService : Service() {
}
}
+ fun isStopping(intent: Intent): Boolean {
+ return intent.action == ACTION_STOP
+ }
+
private fun currentState(clazz: Class): State {
return states.getOrPut(clazz) { State.STOPPED }
}
@@ -137,7 +143,11 @@ abstract class SafeForegroundService : Service() {
Log.d(tag, "[onStartCommand] action: ${intent.action}")
- startForeground(notificationId, getForegroundNotification(intent))
+ if (Build.VERSION.SDK_INT >= 30 && serviceType != 0) {
+ startForeground(notificationId, getForegroundNotification(intent), serviceType)
+ } else {
+ startForeground(notificationId, getForegroundNotification(intent))
+ }
when (val action = intent.action) {
ACTION_START -> {
@@ -187,6 +197,10 @@ abstract class SafeForegroundService : Service() {
/** Notification ID to use when posting the foreground notification */
abstract val notificationId: Int
+ /** Special service type to use when calling start service if needed */
+ @RequiresApi(30)
+ open val serviceType: Int = 0
+
/** Notification to post as our foreground notification. */
abstract fun getForegroundNotification(intent: Intent): Notification
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/ActiveCallManager.kt b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/ActiveCallManager.kt
index 7e7eecfbdf..7f5301b44f 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/ActiveCallManager.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/ActiveCallManager.kt
@@ -10,11 +10,13 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
+import android.content.pm.ServiceInfo
import android.net.ConnectivityManager
import android.os.Build
import android.telephony.PhoneStateListener
import android.telephony.TelephonyManager
import androidx.annotation.MainThread
+import androidx.annotation.RequiresApi
import androidx.core.app.NotificationManagerCompat
import androidx.core.os.bundleOf
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
@@ -194,6 +196,10 @@ class ActiveCallManager(
override val notificationId: Int
get() = CallNotificationBuilder.WEBRTC_NOTIFICATION
+ @get:RequiresApi(30)
+ override val serviceType: Int
+ get() = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
+
private var hangUpRtcOnDeviceCallAnswered: PhoneStateListener? = null
private var notification: Notification? = null
private var notificationDisposable: Disposable = Disposable.disposed()
@@ -222,6 +228,11 @@ class ActiveCallManager(
}
override fun getForegroundNotification(intent: Intent): Notification {
+ if (SafeForegroundService.isStopping(intent)) {
+ Log.v(TAG, "Service is stopping, using generic stopping notification")
+ return CallNotificationBuilder.getStoppingNotification(this)
+ }
+
if (notification != null) {
return notification!!
} else if (!intent.hasExtra(EXTRA_RECIPIENT_ID)) {