Do not start foreground service with microphone & camera types if call is not active yet

This commit is contained in:
Sylvain Berfini 2023-12-12 13:53:24 +01:00
parent 8ad466e091
commit d9984f39ba
3 changed files with 62 additions and 23 deletions

View file

@ -31,6 +31,7 @@ import android.net.Uri
import android.provider.Settings import android.provider.Settings
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.utils.PermissionHelper
@TargetApi(34) @TargetApi(34)
class Api34Compatibility { class Api34Compatibility {
@ -50,12 +51,42 @@ class Api34Compatibility {
ContextCompat.startActivity(context, intent, null) ContextCompat.startActivity(context, intent, null)
} }
fun startCallForegroundService(service: Service, notifId: Int, notif: Notification) { fun startCallForegroundService(
service: Service,
notifId: Int,
notif: Notification,
isCallActive: Boolean
) {
val mask = if (isCallActive) {
Log.i(
"[Api34 Compatibility] Trying to start service as foreground using at least FOREGROUND_SERVICE_TYPE_PHONE_CALL"
)
var computeMask = ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL
if (PermissionHelper.get().hasCameraPermission()) {
Log.i(
"[Api34 Compatibility] CAMERA permission has been granted, adding FOREGROUND_SERVICE_TYPE_CAMERA"
)
computeMask = computeMask or ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
}
if (PermissionHelper.get().hasRecordAudioPermission()) {
Log.i(
"[Api34 Compatibility] RECORD_AUDIO permission has been granted, adding FOREGROUND_SERVICE_TYPE_MICROPHONE"
)
computeMask = computeMask or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
}
computeMask
} else {
Log.i(
"[Api34 Compatibility] Trying to start service as foreground using only FOREGROUND_SERVICE_TYPE_PHONE_CALL because call isn't active yet"
)
ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL
}
try { try {
service.startForeground( service.startForeground(
notifId, notifId,
notif, notif,
ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE or ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA mask
) )
} catch (fssnae: ForegroundServiceStartNotAllowedException) { } catch (fssnae: ForegroundServiceStartNotAllowedException) {
Log.e("[Api34 Compatibility] Can't start service as foreground! $fssnae") Log.e("[Api34 Compatibility] Can't start service as foreground! $fssnae")

View file

@ -290,9 +290,14 @@ class Compatibility {
} }
} }
fun startCallForegroundService(service: Service, notifId: Int, notif: Notification) { fun startCallForegroundService(
service: Service,
notifId: Int,
notif: Notification,
isCallActive: Boolean
) {
if (Version.sdkAboveOrEqual(Version.API34_ANDROID_14_UPSIDE_DOWN_CAKE)) { if (Version.sdkAboveOrEqual(Version.API34_ANDROID_14_UPSIDE_DOWN_CAKE)) {
Api34Compatibility.startCallForegroundService(service, notifId, notif) Api34Compatibility.startCallForegroundService(service, notifId, notif, isCallActive)
} else { } else {
startForegroundService(service, notifId, notif) startForegroundService(service, notifId, notif)
} }

View file

@ -139,7 +139,10 @@ class NotificationsManager(private val context: Context) {
displayMissedCallNotification(call.remoteAddress) displayMissedCallNotification(call.remoteAddress)
} }
} }
else -> displayCallNotification(call) Call.State.OutgoingInit, Call.State.OutgoingProgress, Call.State.OutgoingRinging -> {
displayCallNotification(call, false)
}
else -> displayCallNotification(call, true)
} }
} }
@ -556,32 +559,32 @@ class NotificationsManager(private val context: Context) {
) )
} }
private fun startForeground(notificationId: Int, callNotification: Notification) { private fun startForeground(
if (currentForegroundServiceNotificationId == 0 && service != null) { notificationId: Int,
callNotification: Notification,
isCallActive: Boolean
) {
val coreService = service
if (coreService != null && (currentForegroundServiceNotificationId == 0 || currentForegroundServiceNotificationId == notificationId)) {
Log.i( Log.i(
"[Notifications Manager] Starting service as foreground using call notification [$notificationId]" "[Notifications Manager] Starting service as foreground using call notification [$notificationId]"
) )
try { try {
currentForegroundServiceNotificationId = notificationId currentForegroundServiceNotificationId = notificationId
val coreService = service Compatibility.startCallForegroundService(
if (coreService != null) { coreService,
Compatibility.startCallForegroundService( currentForegroundServiceNotificationId,
coreService, callNotification,
currentForegroundServiceNotificationId, isCallActive
callNotification )
)
} else {
Log.w("[Notifications Manager] No Service found, can't start it as foreground")
currentForegroundServiceNotificationId = 0
}
} catch (e: Exception) { } catch (e: Exception) {
Log.e("[Notifications Manager] Foreground service wasn't allowed! $e") Log.e("[Notifications Manager] Foreground service wasn't allowed! $e")
currentForegroundServiceNotificationId = 0 currentForegroundServiceNotificationId = 0
} }
} else { } else {
Log.w( Log.w(
"[Notifications Manager] Can't start foreground service using notification id [$notificationId] (current foreground service notification id is [$currentForegroundServiceNotificationId]) and service [$service]" "[Notifications Manager] Can't start foreground service using notification id [$notificationId] (current foreground service notification id is [$currentForegroundServiceNotificationId]) and service [$coreService]"
) )
} }
} }
@ -759,7 +762,7 @@ class NotificationsManager(private val context: Context) {
Log.i( Log.i(
"[Notifications Manager] Notifying incoming call notification for foreground service [${notifiable.notificationId}]" "[Notifications Manager] Notifying incoming call notification for foreground service [${notifiable.notificationId}]"
) )
startForeground(notifiable.notificationId, notification) startForeground(notifiable.notificationId, notification, false)
} }
} }
@ -812,7 +815,7 @@ class NotificationsManager(private val context: Context) {
cancel(MISSED_CALLS_NOTIF_ID, MISSED_CALL_TAG) cancel(MISSED_CALLS_NOTIF_ID, MISSED_CALL_TAG)
} }
fun displayCallNotification(call: Call, useAsForeground: Boolean = false) { private fun displayCallNotification(call: Call, isCallActive: Boolean) {
val notifiable = getNotifiableForCall(call) val notifiable = getNotifiableForCall(call)
val serviceChannel = context.getString(R.string.notification_channel_service_id) val serviceChannel = context.getString(R.string.notification_channel_service_id)
@ -861,11 +864,11 @@ class NotificationsManager(private val context: Context) {
Log.i("[Notifications Manager] Notifying call notification [${notifiable.notificationId}]") Log.i("[Notifications Manager] Notifying call notification [${notifiable.notificationId}]")
notify(notifiable.notificationId, notification) notify(notifiable.notificationId, notification)
if (useAsForeground || (service != null && currentForegroundServiceNotificationId == 0)) { if (service != null && (currentForegroundServiceNotificationId == 0 || currentForegroundServiceNotificationId == notifiable.notificationId)) {
Log.i( Log.i(
"[Notifications Manager] Notifying call notification for foreground service [${notifiable.notificationId}]" "[Notifications Manager] Notifying call notification for foreground service [${notifiable.notificationId}]"
) )
startForeground(notifiable.notificationId, notification) startForeground(notifiable.notificationId, notification, isCallActive)
} }
} }