Fixed foreground service types & use

This commit is contained in:
Sylvain Berfini 2023-12-12 18:22:11 +01:00
parent 2274cdd343
commit 637f424a70
4 changed files with 70 additions and 30 deletions

View file

@ -19,36 +19,16 @@
*/
package org.linphone.compatibility
import android.app.Notification
import android.app.Service
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import androidx.annotation.RequiresApi
import org.linphone.core.tools.Log
@RequiresApi(Build.VERSION_CODES.Q)
class Api29Compatibility {
companion object {
private const val TAG = "[API 29 Compatibility]"
fun startServiceForeground(
service: Service,
id: Int,
notification: Notification,
foregroundServiceType: Int
) {
try {
service.startForeground(
id,
notification,
foregroundServiceType
)
} catch (e: Exception) {
Log.e("$TAG Can't start service as foreground! $e")
}
}
fun getMediaCollectionUri(isImage: Boolean, isVideo: Boolean, isAudio: Boolean): Uri {
return when {
isImage -> {

View file

@ -19,7 +19,9 @@
*/
package org.linphone.compatibility
import android.app.Notification
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.net.Uri
@ -34,6 +36,23 @@ class Api34Compatibility {
companion object {
private const val TAG = "[API 34 Compatibility]"
fun startServiceForeground(
service: Service,
id: Int,
notification: Notification,
foregroundServiceType: Int
) {
try {
service.startForeground(
id,
notification,
foregroundServiceType
)
} catch (e: Exception) {
Log.e("$TAG Can't start service as foreground! $e")
}
}
fun hasFullScreenIntentPermission(context: Context): Boolean {
val notificationManager = context.getSystemService(NotificationManager::class.java) as NotificationManager
// See https://developer.android.com/reference/android/app/NotificationManager#canUseFullScreenIntent%28%29

View file

@ -45,8 +45,8 @@ class Compatibility {
notification: Notification,
foregroundServiceType: Int
) {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
Api29Compatibility.startServiceForeground(
if (Version.sdkAboveOrEqual(Version.API34_ANDROID_14_UPSIDE_DOWN_CAKE)) {
Api34Compatibility.startServiceForeground(
service,
id,
notification,

View file

@ -88,6 +88,8 @@ class NotificationsManager @MainThread constructor(private val context: Context)
private const val MISSED_CALL_ID = 10
}
private var currentForegroundServiceNotificationId = -1
private val notificationManager: NotificationManagerCompat by lazy {
NotificationManagerCompat.from(context)
}
@ -359,7 +361,8 @@ class NotificationsManager @MainThread constructor(private val context: Context)
stopCallForeground()
} else {
Log.i("$TAG At least a call is still running")
startCallForeground()
val call = core.currentCall ?: core.calls.first()
startCallForeground(call)
}
}
}
@ -405,6 +408,10 @@ class NotificationsManager @MainThread constructor(private val context: Context)
isIncoming
)
notify(notifiable.notificationId, notification)
if (notifiable.notificationId == currentForegroundServiceNotificationId) {
startCallForeground(call)
}
}
@WorkerThread
@ -449,8 +456,8 @@ class NotificationsManager @MainThread constructor(private val context: Context)
}
@WorkerThread
private fun startCallForeground() {
Log.i("$TAG Trying to start foreground Service using call notification")
private fun startCallForeground(call: Call) {
Log.i("$TAG Trying to start/update foreground Service using call notification")
val channelId = context.getString(R.string.notification_channel_call_id)
val channel = notificationManager.getNotificationChannel(channelId)
@ -473,17 +480,48 @@ class NotificationsManager @MainThread constructor(private val context: Context)
}
Log.i("$TAG Found notification [${notification.id}] for current Call")
var mask = Compatibility.FOREGROUND_SERVICE_TYPE_PHONE_CALL
val callState = call.state
if (!LinphoneUtils.isCallIncoming(callState) && !LinphoneUtils.isCallOutgoing(callState) && !LinphoneUtils.isCallEnding(
callState
)
) {
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.RECORD_AUDIO
) == PackageManager.PERMISSION_GRANTED
) {
mask = mask or Compatibility.FOREGROUND_SERVICE_TYPE_MICROPHONE
Log.i(
"$TAG RECORD_AUDIO permission has been granted, adding FOREGROUND_SERVICE_TYPE_MICROPHONE"
)
}
if (call.currentParams.isVideoEnabled) {
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED
) {
mask = mask or Compatibility.FOREGROUND_SERVICE_TYPE_CAMERA
Log.i(
"$TAG CAMERA permission has been granted, adding FOREGROUND_SERVICE_TYPE_CAMERA"
)
}
}
}
val service = coreService
if (service != null) {
Log.i("$TAG Service found, starting it as foreground using notification")
Log.i(
"$TAG Service found, starting it as foreground using notification ID [${notifiable.notificationId}] with type(s) [$mask]"
)
Compatibility.startServiceForeground(
service,
notifiable.notificationId,
notification.notification,
Compatibility.FOREGROUND_SERVICE_TYPE_PHONE_CALL
or Compatibility.FOREGROUND_SERVICE_TYPE_MICROPHONE
or Compatibility.FOREGROUND_SERVICE_TYPE_CAMERA
mask
)
currentForegroundServiceNotificationId = notifiable.notificationId
} else {
Log.w("$TAG Core Foreground Service hasn't started yet...")
}
@ -493,9 +531,12 @@ class NotificationsManager @MainThread constructor(private val context: Context)
private fun stopCallForeground() {
val service = coreService
if (service != null) {
Log.i("$TAG Stopping foreground service")
Log.i(
"$TAG Stopping foreground service (was using notification ID [$currentForegroundServiceNotificationId])"
)
service.stopForeground(STOP_FOREGROUND_REMOVE)
service.stopSelf()
currentForegroundServiceNotificationId = -1
} else {
Log.w("$TAG Can't stop foreground service & notif, no service was found")
}