From aba0af378ae8160fc374f026bd17438f28a99304 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 24 Feb 2022 11:03:21 +0100 Subject: [PATCH] Prevent crash on Android 12 if we aren't allowed to start a Service as foreground --- .../compatibility/Api21Compatibility.kt | 7 ++++-- .../compatibility/Api31Compatibility.kt | 23 +++++++++++++++---- .../linphone/compatibility/Compatibility.kt | 13 ++++++++++- .../java/org/linphone/core/BootReceiver.kt | 3 +-- .../notifications/NotificationsManager.kt | 2 +- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt index ecea7b14c..48cf79da5 100644 --- a/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt @@ -21,8 +21,7 @@ package org.linphone.compatibility import android.annotation.SuppressLint import android.annotation.TargetApi -import android.app.Activity -import android.app.PendingIntent +import android.app.* import android.bluetooth.BluetoothAdapter import android.content.ContentValues import android.content.Context @@ -248,6 +247,10 @@ class Api21Compatibility { context.startService(intent) } + fun startForegroundService(service: Service, notifId: Int, notif: Notification?) { + service.startForeground(notifId, notif) + } + fun hideAndroidSystemUI(hide: Boolean, window: Window) { val decorView = window.decorView val uiOptions = if (hide) { diff --git a/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt index 44426abe8..c09217b4d 100644 --- a/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Api31Compatibility.kt @@ -20,12 +20,9 @@ package org.linphone.compatibility import android.annotation.TargetApi -import android.app.Activity -import android.app.Notification -import android.app.PendingIntent -import android.app.Person -import android.app.PictureInPictureParams +import android.app.* import android.content.Context +import android.content.Intent import android.content.pm.PackageManager import androidx.core.content.ContextCompat import org.linphone.LinphoneApplication.Companion.coreContext @@ -150,6 +147,22 @@ class Api31Compatibility { return builder.build() } + fun startForegroundService(context: Context, intent: Intent) { + try { + Compatibility.startForegroundService(context, intent) + } catch (fssnae: ForegroundServiceStartNotAllowedException) { + Log.e("[Api31 Compatibility] Can't start service as foreground! $fssnae") + } + } + + fun startForegroundService(service: Service, notifId: Int, notif: Notification?) { + try { + service.startForeground(notifId, notif) + } catch (fssnae: ForegroundServiceStartNotAllowedException) { + Log.e("[Api31 Compatibility] Can't start service as foreground! $fssnae") + } + } + fun enableAutoEnterPiP(activity: Activity, enable: Boolean) { val supportsPip = activity.packageManager .hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Compatibility.kt index 316b02ea7..1b821404e 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.kt @@ -22,6 +22,7 @@ package org.linphone.compatibility import android.app.Activity import android.app.Notification import android.app.PendingIntent +import android.app.Service import android.content.Context import android.content.Intent import android.content.pm.PackageManager @@ -203,13 +204,23 @@ class Compatibility { } fun startForegroundService(context: Context, intent: Intent) { - if (Version.sdkAboveOrEqual(Version.API26_O_80)) { + if (Version.sdkAboveOrEqual(Version.API31_ANDROID_12)) { + Api31Compatibility.startForegroundService(context, intent) + } else if (Version.sdkAboveOrEqual(Version.API26_O_80)) { Api26Compatibility.startForegroundService(context, intent) } else { Api21Compatibility.startForegroundService(context, intent) } } + fun startForegroundService(service: Service, notifId: Int, notif: Notification?) { + if (Version.sdkAboveOrEqual(Version.API31_ANDROID_12)) { + Api31Compatibility.startForegroundService(service, notifId, notif) + } else { + Api21Compatibility.startForegroundService(service, notifId, notif) + } + } + /* Call */ fun canDrawOverlay(context: Context): Boolean { diff --git a/app/src/main/java/org/linphone/core/BootReceiver.kt b/app/src/main/java/org/linphone/core/BootReceiver.kt index 39b49c544..951eacde0 100644 --- a/app/src/main/java/org/linphone/core/BootReceiver.kt +++ b/app/src/main/java/org/linphone/core/BootReceiver.kt @@ -23,7 +23,6 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import androidx.core.app.NotificationManagerCompat -import androidx.core.content.ContextCompat import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.R import org.linphone.compatibility.Compatibility @@ -56,6 +55,6 @@ class BootReceiver : BroadcastReceiver() { val serviceIntent = Intent(Intent.ACTION_MAIN).setClass(context, CoreService::class.java) serviceIntent.putExtra("StartForeground", true) - ContextCompat.startForegroundService(context, serviceIntent) + Compatibility.startForegroundService(context, serviceIntent) } } diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index 903b4d81f..252454223 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -338,7 +338,7 @@ class NotificationsManager(private val context: Context) { } currentForegroundServiceNotificationId = SERVICE_NOTIF_ID Log.i("[Notifications Manager] Starting service as foreground [$currentForegroundServiceNotificationId]") - coreService.startForeground(currentForegroundServiceNotificationId, serviceNotification) + Compatibility.startForegroundService(coreService, currentForegroundServiceNotificationId, serviceNotification) service = coreService }