diff --git a/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt index 66f98c277..777ab4607 100644 --- a/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Api34Compatibility.kt @@ -31,6 +31,7 @@ import android.net.Uri import android.provider.Settings import androidx.core.content.ContextCompat import org.linphone.core.tools.Log +import org.linphone.utils.PermissionHelper @TargetApi(34) class Api34Compatibility { @@ -50,12 +51,42 @@ class Api34Compatibility { 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 { service.startForeground( notifId, notif, - ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE or ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA + mask ) } catch (fssnae: ForegroundServiceStartNotAllowedException) { Log.e("[Api34 Compatibility] Can't start service as foreground! $fssnae") diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Compatibility.kt index 6598378ec..091f6d752 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.kt @@ -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)) { - Api34Compatibility.startCallForegroundService(service, notifId, notif) + Api34Compatibility.startCallForegroundService(service, notifId, notif, isCallActive) } else { startForegroundService(service, notifId, notif) } diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index aaf950229..58b5ec334 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -139,7 +139,10 @@ class NotificationsManager(private val context: Context) { 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) { - if (currentForegroundServiceNotificationId == 0 && service != null) { + private fun startForeground( + notificationId: Int, + callNotification: Notification, + isCallActive: Boolean + ) { + val coreService = service + if (coreService != null && (currentForegroundServiceNotificationId == 0 || currentForegroundServiceNotificationId == notificationId)) { Log.i( "[Notifications Manager] Starting service as foreground using call notification [$notificationId]" ) try { currentForegroundServiceNotificationId = notificationId - val coreService = service - if (coreService != null) { - Compatibility.startCallForegroundService( - coreService, - currentForegroundServiceNotificationId, - callNotification - ) - } else { - Log.w("[Notifications Manager] No Service found, can't start it as foreground") - currentForegroundServiceNotificationId = 0 - } + Compatibility.startCallForegroundService( + coreService, + currentForegroundServiceNotificationId, + callNotification, + isCallActive + ) } catch (e: Exception) { Log.e("[Notifications Manager] Foreground service wasn't allowed! $e") currentForegroundServiceNotificationId = 0 } } else { 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( "[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) } - fun displayCallNotification(call: Call, useAsForeground: Boolean = false) { + private fun displayCallNotification(call: Call, isCallActive: Boolean) { val notifiable = getNotifiableForCall(call) 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}]") notify(notifiable.notificationId, notification) - if (useAsForeground || (service != null && currentForegroundServiceNotificationId == 0)) { + if (service != null && (currentForegroundServiceNotificationId == 0 || currentForegroundServiceNotificationId == notifiable.notificationId)) { Log.i( "[Notifications Manager] Notifying call notification for foreground service [${notifiable.notificationId}]" ) - startForeground(notifiable.notificationId, notification) + startForeground(notifiable.notificationId, notification, isCallActive) } }